diff --git a/.golangci.yaml b/.golangci.yaml index 712df7d33d..cde08dcf41 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -100,9 +100,7 @@ linters: - .keys - .vscode - build - - console - deploy - - docs - guides - internal/api/ui/login/static - openapi @@ -111,6 +109,12 @@ linters: - third_party$ - builtin$ - examples$ + - apps + - packages + - console + - docs + - load-test + issues: max-issues-per-linter: 0 max-same-issues: 0 @@ -135,9 +139,7 @@ formatters: - .keys - .vscode - build - - console - deploy - - docs - guides - internal/api/ui/login/static - openapi @@ -146,3 +148,8 @@ formatters: - third_party$ - builtin$ - examples$ + - apps + - packages + - console + - docs + - load-test diff --git a/cmd/start/start.go b/cmd/start/start.go index adbac7f822..045bc99d54 100644 --- a/cmd/start/start.go +++ b/cmd/start/start.go @@ -34,6 +34,7 @@ import ( "github.com/zitadel/zitadel/internal/api" "github.com/zitadel/zitadel/internal/api/assets" internal_authz "github.com/zitadel/zitadel/internal/api/authz" + action_v2 "github.com/zitadel/zitadel/internal/api/grpc/action/v2" action_v2_beta "github.com/zitadel/zitadel/internal/api/grpc/action/v2beta" "github.com/zitadel/zitadel/internal/api/grpc/admin" app "github.com/zitadel/zitadel/internal/api/grpc/app/v2beta" @@ -509,6 +510,9 @@ func startAPIs( if err := apis.RegisterService(ctx, action_v2_beta.CreateServer(config.SystemDefaults, commands, queries, domain.AllActionFunctions, apis.ListGrpcMethods, apis.ListGrpcServices)); err != nil { return nil, err } + if err := apis.RegisterService(ctx, action_v2.CreateServer(config.SystemDefaults, commands, queries, domain.AllActionFunctions, apis.ListGrpcMethods, apis.ListGrpcServices)); err != nil { + return nil, err + } if err := apis.RegisterService(ctx, project_v2beta.CreateServer(config.SystemDefaults, commands, queries, permissionCheck)); err != nil { return nil, err } diff --git a/docs/docs/apis/actions/objects.md b/docs/docs/apis/actions/objects.md index 41307ee580..bbde0f22d3 100644 --- a/docs/docs/apis/actions/objects.md +++ b/docs/docs/apis/actions/objects.md @@ -145,7 +145,7 @@ This object contains context information about the request to the [authorization - `requestedOrgDomain` *bool* - `applicationResourceOwner` *string* - `privateLabelingSetting` *Number* - + - `selectedIdpConfigId` *string* - `linkingUsers` Array of [*ExternalUser*](#external-user) - `passwordVerified` *bool* diff --git a/docs/docs/apis/openidoauth/claims.md b/docs/docs/apis/openidoauth/claims.md index b7424aaf1d..c82e3a3883 100644 --- a/docs/docs/apis/openidoauth/claims.md +++ b/docs/docs/apis/openidoauth/claims.md @@ -111,6 +111,6 @@ ZITADEL reserves some claims to assert certain data. Please check out the [reser | urn:zitadel:iam:org:project:roles | `{"urn:zitadel:iam:org:project:roles": [ {"user": {"id1": "acme.zitade.ch", "id2": "caos.ch"} } ] }` | When roles are asserted, ZITADEL does this by providing the `id` and `primaryDomain` below the role. This gives you the option to check in which organization a user has the role on the current project (where your client belongs to). | | urn:zitadel:iam:org:project:\{projectid}:roles | `{"urn:zitadel:iam:org:project:id3:roles": [ {"user": {"id1": "acme.zitade.ch", "id2": "caos.ch"} } ] }` | When roles are asserted, ZITADEL does this by providing the `id` and `primaryDomain` below the role. This gives you the option to check in which organization a user has the role on a specific project. | | urn:zitadel:iam:user:metadata | `{"urn:zitadel:iam:user:metadata": [ {"key": "VmFsdWU=" } ] }` | The metadata claim will include all metadata of a user. The values are base64 encoded. | -| urn:zitadel:iam:user:resourceowner:id | `{"urn:zitadel:iam:user:resourceowner:id": "orgid"}` | This claim represents the id of the resource owner organisation of the user. | -| urn:zitadel:iam:user:resourceowner:name | `{"urn:zitadel:iam:user:resourceowner:name": "ACME"}` | This claim represents the name of the resource owner organisation of the user. | -| urn:zitadel:iam:user:resourceowner:primary_domain | `{"urn:zitadel:iam:user:resourceowner:primary_domain": "acme.ch"}` | This claim represents the primary domain of the resource owner organisation of the user. | +| urn:zitadel:iam:user:resourceowner:id | `{"urn:zitadel:iam:user:resourceowner:id": "orgid"}` | This claim represents the user's organization ID. | +| urn:zitadel:iam:user:resourceowner:name | `{"urn:zitadel:iam:user:resourceowner:name": "ACME"}` | This claim represents the user's organization's name. | +| urn:zitadel:iam:user:resourceowner:primary_domain | `{"urn:zitadel:iam:user:resourceowner:primary_domain": "acme.ch"}` | This claim represents the user's organization's primary domain. | diff --git a/docs/docs/apis/openidoauth/scopes.md b/docs/docs/apis/openidoauth/scopes.md index d1fe9c7c5b..c7efa914c6 100644 --- a/docs/docs/apis/openidoauth/scopes.md +++ b/docs/docs/apis/openidoauth/scopes.md @@ -31,8 +31,8 @@ In addition to the standard compliant scopes we utilize the following scopes. | `urn:zitadel:iam:org:id:{id}` | `urn:zitadel:iam:org:id:178204173316174381` | When requesting this scope **ZITADEL** will enforce that the user is a member of the selected organization. If the organization does not exist a failure is displayed. It will assert the `urn:zitadel:iam:user:resourceowner` claims. | | `urn:zitadel:iam:org:domain:primary:{domainname}` | `urn:zitadel:iam:org:domain:primary:acme.ch` | When requesting this scope **ZITADEL** will enforce that the user is a member of the selected organization and the username is suffixed by the provided domain. If the organization does not exist a failure is displayed | | `urn:zitadel:iam:org:roles:id:{orgID}` | `urn:zitadel:iam:org:roles:id:178204173316174381` | This scope can be used one or more times to limit the granted organization IDs in the returned roles. Unknown organization IDs are ignored. When this scope is not used, all granted organizations are returned inside the roles. | -| `urn:zitadel:iam:org:project:id:{projectid}:aud` | `urn:zitadel:iam:org:project:id:69234237810729019:aud` | By adding this scope, the requested projectid will be added to the audience of the access token | -| `urn:zitadel:iam:org:project:id:zitadel:aud` | `urn:zitadel:iam:org:project:id:zitadel:aud` | By adding this scope, the ZITADEL project ID will be added to the audience of the access token | +| `urn:zitadel:iam:org:project:id:{projectid}:aud` | `urn:zitadel:iam:org:project:id:69234237810729019:aud` | By adding this scope, the requested project id will be added to the audience of the access token | +| `urn:zitadel:iam:org:project:id:zitadel:aud` | `urn:zitadel:iam:org:project:id:zitadel:aud` | By adding this scope, the ZITADEL project id will be added to the audience of the access token | | `urn:zitadel:iam:user:metadata` | `urn:zitadel:iam:user:metadata` | By adding this scope, the metadata of the user will be included in the token. The values are base64 encoded. | -| `urn:zitadel:iam:user:resourceowner` | `urn:zitadel:iam:user:resourceowner` | By adding this scope: id, name and primary_domain of the resource owner (the users organization) will be included in the token. | +| `urn:zitadel:iam:user:resourceowner` | `urn:zitadel:iam:user:resourceowner` | By adding this scope: id, name and primary_domain of the user's organization will be included in the token. | | `urn:zitadel:iam:org:idp:id:{idp_id}` | `urn:zitadel:iam:org:idp:id:76625965177954913` | By adding this scope the user will directly be redirected to the identity provider to authenticate. Make sure you also send the primary domain scope if a custom login policy is configured. Otherwise the system will not be able to identify the identity provider. | diff --git a/docs/docs/guides/integrate/actions/testing-event.md b/docs/docs/guides/integrate/actions/testing-event.md index 8b4502703b..7c8bdd8c2b 100644 --- a/docs/docs/guides/integrate/actions/testing-event.md +++ b/docs/docs/guides/integrate/actions/testing-event.md @@ -103,9 +103,7 @@ curl -L -X PUT 'https://$CUSTOM-DOMAIN/v2beta/actions/executions' \ } }, "targets": [ - { - "target": "" - } + "" ] }' ``` diff --git a/docs/docs/guides/integrate/actions/testing-function-manipulation.md b/docs/docs/guides/integrate/actions/testing-function-manipulation.md index 8f5e2fc968..e82f0b8c18 100644 --- a/docs/docs/guides/integrate/actions/testing-function-manipulation.md +++ b/docs/docs/guides/integrate/actions/testing-function-manipulation.md @@ -129,9 +129,7 @@ curl -L -X PUT 'https://$CUSTOM-DOMAIN/v2beta/actions/executions' \ } }, "targets": [ - { - "target": "" - } + "" ] }' ``` diff --git a/docs/docs/guides/integrate/actions/testing-function.md b/docs/docs/guides/integrate/actions/testing-function.md index f14f20b69d..a2faa5e709 100644 --- a/docs/docs/guides/integrate/actions/testing-function.md +++ b/docs/docs/guides/integrate/actions/testing-function.md @@ -107,9 +107,7 @@ curl -L -X PUT 'https://$CUSTOM-DOMAIN/v2beta/actions/executions' \ } }, "targets": [ - { - "target": "" - } + "" ] }' ``` diff --git a/docs/docs/guides/integrate/actions/testing-request-manipulation.md b/docs/docs/guides/integrate/actions/testing-request-manipulation.md index 1cb4f1776a..b10c32d372 100644 --- a/docs/docs/guides/integrate/actions/testing-request-manipulation.md +++ b/docs/docs/guides/integrate/actions/testing-request-manipulation.md @@ -154,9 +154,7 @@ curl -L -X PUT 'https://$CUSTOM-DOMAIN/v2beta/actions/executions' \ } }, "targets": [ - { - "target": "" - } + "" ] }' ``` diff --git a/docs/docs/guides/integrate/actions/testing-request-signature.md b/docs/docs/guides/integrate/actions/testing-request-signature.md index c1932a7d5b..b3a9f0fa5d 100644 --- a/docs/docs/guides/integrate/actions/testing-request-signature.md +++ b/docs/docs/guides/integrate/actions/testing-request-signature.md @@ -114,9 +114,7 @@ curl -L -X PUT 'https://$CUSTOM-DOMAIN/v2beta/actions/executions' \ } }, "targets": [ - { - "target": "" - } + "" ] }' ``` diff --git a/docs/docs/guides/integrate/actions/testing-request.md b/docs/docs/guides/integrate/actions/testing-request.md index b2413e606e..c99e16cd2f 100644 --- a/docs/docs/guides/integrate/actions/testing-request.md +++ b/docs/docs/guides/integrate/actions/testing-request.md @@ -107,9 +107,7 @@ curl -L -X PUT 'https://$CUSTOM-DOMAIN/v2beta/actions/executions' \ } }, "targets": [ - { - "target": "" - } + "" ] }' ``` diff --git a/docs/docs/guides/integrate/actions/testing-response-manipulation.md b/docs/docs/guides/integrate/actions/testing-response-manipulation.md index 9d95479b05..2bec3e0acd 100644 --- a/docs/docs/guides/integrate/actions/testing-response-manipulation.md +++ b/docs/docs/guides/integrate/actions/testing-response-manipulation.md @@ -173,9 +173,7 @@ curl -L -X PUT 'https://$CUSTOM-DOMAIN/v2beta/actions/executions' \ } }, "targets": [ - { - "target": "" - } + "" ] }' ``` diff --git a/docs/docs/guides/integrate/actions/testing-response.md b/docs/docs/guides/integrate/actions/testing-response.md index a2ab736505..aea6ac732f 100644 --- a/docs/docs/guides/integrate/actions/testing-response.md +++ b/docs/docs/guides/integrate/actions/testing-response.md @@ -107,9 +107,7 @@ curl -L -X PUT 'https://$CUSTOM-DOMAIN/v2beta/actions/executions' \ } }, "targets": [ - { - "target": "" - } + "" ] }' ``` diff --git a/docs/docs/guides/integrate/actions/usage.md b/docs/docs/guides/integrate/actions/usage.md index e21fb4935d..643c9a3995 100644 --- a/docs/docs/guides/integrate/actions/usage.md +++ b/docs/docs/guides/integrate/actions/usage.md @@ -406,17 +406,11 @@ If you then have a call on `/zitadel.user.v2.UserService/UpdateHumanUser` the fo And if you use a different service, for example `zitadel.session.v2.SessionService`, then the `all` Execution would still be used. -### Targets and Includes +### Targets -:::info -Includes are limited to 3 levels, which mean that include1->include2->include3 is the maximum for now. -If you have feedback to the include logic, or a reason why 3 levels are not enough, please open [an issue on github](https://github.com/zitadel/zitadel/issues) or [start a discussion on github](https://github.com/zitadel/zitadel/discussions)/[start a topic on discord](https://zitadel.com/chat) -::: +An execution can contain only a list of Targets, and Targets are comma separated string values. -An execution can not only contain a list of Targets, but also Includes. -The Includes can be defined in the Execution directly, which means you include all defined Targets by a before set Execution. - -If you define 2 Executions as follows: +Here's an example of a Target defined on a service (e.g. `zitadel.user.v2.UserService`) ```json { @@ -426,13 +420,12 @@ If you define 2 Executions as follows: } }, "targets": [ - { - "target": "" - } + "" ] } ``` +Here's an example of a Target defined on a method (e.g. `/zitadel.user.v2.UserService/AddHumanUser`) ```json { "condition": { @@ -441,21 +434,13 @@ If you define 2 Executions as follows: } }, "targets": [ - { - "target": "" - }, - { - "include": { - "request": { - "service": "zitadel.user.v2.UserService" - } - } - } + "", + "" ] } ``` -The called Targets on "/zitadel.user.v2.UserService/AddHumanUser" would be, in order: +The called Targets on `/zitadel.user.v2.UserService/AddHumanUser` would be, in order: 1. `` 2. `` diff --git a/docs/docs/guides/manage/console/projects.mdx b/docs/docs/guides/manage/console/projects.mdx index 53abea2dac..9fa41d850e 100644 --- a/docs/docs/guides/manage/console/projects.mdx +++ b/docs/docs/guides/manage/console/projects.mdx @@ -77,8 +77,8 @@ You can choose from | Setting | Description | | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Unspecified | If nothing is specified the default will trigger. (System settings) | -| Enforce project resource owner policy | This setting will enforce the private labeling of the organization (resource owner) of the project through the whole login process. | -| Allow Login User resource owner policy | With this setting first the private labeling of the organization (resource owner) of the project will trigger. As soon as the user and its organization (resource owner) is identified by ZITADEL, the settings will change to the organization of the user. | +| Enforce project's policy | This setting will enforce the private labeling of the organization of the project through the whole login process. | +| Allow login user policy | With this setting first the private labeling of the organization of the project will trigger. As soon as the user and its organization is identified by ZITADEL, the settings will change to the organization of the user. | In a B2B use case, you would typically use the organization setting. If you want to omit organization detection, you can preselect an organization with the [primary domain scope](/apis/openidoauth/scopes#reserved-scopes) (ex. `urn:zitadel:iam:org:domain:primary:{domainname}`). diff --git a/docs/docs/guides/migrate/sources/zitadel.md b/docs/docs/guides/migrate/sources/zitadel.md index 99b6e1d64e..3f97629951 100644 --- a/docs/docs/guides/migrate/sources/zitadel.md +++ b/docs/docs/guides/migrate/sources/zitadel.md @@ -80,7 +80,7 @@ curl --request POST \ | Field | Type | Description | | ---------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| org_ids | list of strings | provide a list of organizationIDs to select which organizations should be exported (eg, `[ "70669144072186707", "70671105999825752" ]`); leave empty to export all | +| org_ids | list of strings | provide a list of Organization IDs to select which organizations should be exported (eg, `[ "70669144072186707", "70671105999825752" ]`); leave empty to export all | | excluded_org_ids | list of strings | to exclude several organization, if for example no organizations are selected | | with_passwords | bool | to include the hashed_passwords of the users in the export | | with_otp | bool | to include the OTP-code of the users in the export | @@ -143,7 +143,7 @@ curl --request POST \ | Field | Type | Description | | ---------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| org_ids | list of strings | provide a list of organizationIDs to select which organizations should be exported (eg, `[ "70669144072186707", "70671105999825752" ]`); leave empty to export all | +| org_ids | list of strings | provide a list of Organization IDs to select which organizations should be exported (eg, `[ "70669144072186707", "70671105999825752" ]`); leave empty to export all | | excluded_org_ids | list of strings | to exclude several organization, if for example no organizations are selected | | with_passwords | bool | to include the hashed_passwords of the users in the export | | with_otp | bool | to include the OTP-code of the users in the export | diff --git a/docs/docs/guides/solution-scenarios/b2b.mdx b/docs/docs/guides/solution-scenarios/b2b.mdx index 144853b3f8..7ec1129b52 100644 --- a/docs/docs/guides/solution-scenarios/b2b.mdx +++ b/docs/docs/guides/solution-scenarios/b2b.mdx @@ -43,7 +43,7 @@ In order to define the need of the **Portal Application** some planning consider You can decide whether a organization is preselected for the login or if the user is redirected to the default login screen. Using OpenID Connect, you can send the user to a specific organization by defining the organization in a [reserved scope](/docs/apis/openidoauth/scopes#reserved-scopes) (primary domain). Settings to the branding or the login options of the organization can be made from the organization section in [Console](/docs/concepts/features/console). -The behavior of the login branding can be set in your projects detail page. You can choose the branding of the selected organization, the user resource owner, or the projects resource owner. +The behavior of the login branding can be set in your projects detail page. You can choose the branding of the selected organization, the user's organization, or the project's organization. ### Organizations diff --git a/docs/docs/product/roadmap.mdx b/docs/docs/product/roadmap.mdx index b61323fa90..a7409cead2 100644 --- a/docs/docs/product/roadmap.mdx +++ b/docs/docs/product/roadmap.mdx @@ -293,7 +293,7 @@ Excitingly, v3 introduces the foundational elements for Actions V2, opening up a ### v4.x -**Current State**: Implementation +**Current State**: General Availability / Stable
@@ -311,9 +311,13 @@ Excitingly, v3 introduces the foundational elements for Actions V2, opening up a This change, along with standardized naming and improved documentation, will simplify integration, accelerate development, and create a more intuitive experience for our customers and community. Resources integrated in this release: - - Instances + - Applications (in beta) + - Authorizations (in beta) + - Instances (in beta) - Organizations - - Projects + - Permissions (in beta) + - Projects (in beta) + - Settings (beta) now includes 3 new endpoints: `ListOrganizationSettings()`, `SetOrganizationSettings()` and `DeleteOrganizationSettings()` - Users For more details read the [Github Issue](https://github.com/zitadel/zitadel/issues/6305) @@ -369,40 +373,123 @@ Excitingly, v3 introduces the foundational elements for Actions V2, opening up a We're officially moving our new Login UI v2 from beta to General Availability. Starting now, it will be the default login experience for all new customers. - With this release, 8.0we are also focused on implementing previously missing features, such as device authorization and LDAP IDP support, to make the new UI fully feature-complete. + With this release, 8.0 we are also focused on implementing previously missing features, such as device authorization and LDAP IDP support, to make the new UI fully feature-complete. - - [Hosted Login V2](http://localhost:3000/docs/guides/integrate/login/hosted-login#hosted-login-version-2-beta) + - [Hosted Login V2](../guides/integrate/login/hosted-login#hosted-login-version-2-beta)
- Web Keys + Actions v2 - Web Keys in ZITADEL are used to sign and verify JSON Web Tokens (JWT). - ID tokens are created, signed and returned by ZITADEL when a OpenID connect (OIDC) or OAuth2 authorization flow completes and a user is authenticated. - Based on customer and community feedback, we've updated our key management system. You now have full manual control over key generation and rotation, instead of the previous automatic process. + This API enables you to manage custom executions and targets—formerly known as actions—across your entire ZITADEL instance. + With Actions V2, you gain significantly more flexibility to tailor ZITADEL’s behavior compared to previous versions. + Actions are now available instance-wide, eliminating the need to configure them for each organization individually. + ZITADEL no longer restricts the implementation language, tooling, or runtime for action executions. + Instead, you define external endpoints that are called by ZITADEL and maintained by you. - Read the full description about Web Keys in our [Documentation](https://zitadel.com/docs/guides/integrate/login/oidc/webkeys). + - [Actions V2](../apis/resources/action_service_v2) +
+ + +
+ Deprecated endpoints + + + +
+ Organization Objects V1 > Users V1 + + - `AddMachineKey()` + - `AddMachineUser()` + - `AddPersonalAccessToken()` + - `BulkRemoveUserMetadata()` + - `BulkSetUserMetadata()` + - `GenerateMachineSecret()` + - `GetMachineKeyByIDs()` + - `GetOrgByDomainGlobal()` + - `GetPersonalAccessTokenByIDs()` + - `GetUserMetadata()` + - `ListAppKeys()` + - `ListMachineKeys()` + - `ListPersonalAccessTokens()` + - `ListUserMetadata()` + - `RemoveMachineKey()` + - `RemoveMachineSecret()` + - `RemovePersonalAccessToken()` + - `RemoveUserMetadata()` + - `SetUserMetadata()` + - `UpdateHumanPhone()` + - `UpdateMachine()` + - `UpdateUserName()`
- SCIM 2.0 Server - User Resource + Projects V1 - The Zitadel SCIM v2 service provider interface enables seamless integration of identity and access management (IAM) systems with Zitadel, following the System for Cross-domain Identity Management (SCIM) v2.0 specification. - This interface allows standardized management of IAM resources, making it easier to automate user provisioning and deprovisioning. - - - [SCIM 2.0 API](https://zitadel.com/docs/apis/scim2) - - [Manage Users Guide](https://zitadel.com/docs/guides/manage/user/scim2) + - `AddProject()` + - `AddProjectGrant()` + - `AddProjectRole()` + - `BulkAddProjectRoles()` + - `DeactivateProject()` + - `DeactivateProjectGrant()` + - `GetGrantedProjectByID()` + - `GetProjectByID()` + - `GetProjectGrantByID()` + - `ListAllProjectGrants()` + - `ListGrantedProjectRoles()` + - `ListGrantedProjects()` + - `ListProjectGrants()` + - `ListProjectRoles()` + - `ListProjects()` + - `ReactivateProject()` + - `ReactivateProjectGrant()` + - `RemoveProject()` + - `RemoveProjectGrant()` + - `RemoveProjectRole()` + - `UpdateProject()` + - `UpdateProjectGrant()` + - `UpdateProjectRole()`
- Caches + Members V1 - ZITADEL supports the use of a caches to speed up the lookup of frequently needed objects. - As opposed to HTTP caches which might reside between ZITADEL and end-user applications, the cache build into ZITADEL uses active invalidation when an object gets updated. - Another difference is that HTTP caches only cache the result of a complete request and the built-in cache stores objects needed for the internal business logic. - For example, each request made to ZITADEL needs to retrieve and set instance information in middleware. + - `AddIAMMember()` + - `AddOrgMember()` + - `AddProjectGrantMember()` + - `AddProjectMember()` + - `ListIAMMembers()` + - `ListOrgMembers()` + - `ListProjectGrantMembers()` + - `ListProjectMembers()` + - `ListUserMemberships()` + - `RemoveIAMMember()` + - `RemoveOrgMember()` + - `RemoveProjectGrantMember()` + - `RemoveProjectMember()` + - `UpdateIAMMember()` + - `UpdateOrgMember()` + - `UpdateProjectGrantMember()` + - `UpdateProjectMember()` +
- Read more about Zitadel Caches [here](https://zitadel.com/docs/self-hosting/manage/cache) +
+ Instance Lifecycle V1 > System Service V1 + + - `AddInstanceTrustedDomain()` + - `GetMyInstance()` + - `ListInstanceDomains()` + - `ListInstanceTrustedDomains()` + - `RemoveInstanceTrustedDomain()` + +
+ +
+ Instance Objects V1 > Organizations V1 + + - `GetDefaultOrg()` + - `GetOrgByID()` + - `IsOrgUnique()`
diff --git a/docs/docs/self-hosting/deploy/.gitignore b/docs/docs/self-hosting/deploy/.gitignore new file mode 100644 index 0000000000..83754bbee4 --- /dev/null +++ b/docs/docs/self-hosting/deploy/.gitignore @@ -0,0 +1 @@ +login-client-pat diff --git a/docs/docs/self-hosting/deploy/compose.mdx b/docs/docs/self-hosting/deploy/compose.mdx index 370c0e7f5d..f47a33da16 100644 --- a/docs/docs/self-hosting/deploy/compose.mdx +++ b/docs/docs/self-hosting/deploy/compose.mdx @@ -1,67 +1,65 @@ --- -title: Set up ZITADEL with Docker Compose +title: Set up Zitadel with Docker Compose sidebar_label: Docker Compose --- import CodeBlock from '@theme/CodeBlock'; import DockerComposeSource from '!!raw-loader!./docker-compose.yaml' -import DockerComposeSaSource from '!!raw-loader!./docker-compose-sa.yaml' -import Disclaimer from './_disclaimer.mdx' -import DefaultUser from './_defaultuser.mdx' -import Next from './_next.mdx' -import NoteInstanceNotFound from './troubleshooting/_note_instance_not_found.mdx'; +import ExampleZitadelConfigSource from '!!raw-loader!./example-zitadel-config.yaml' +import ExampleZitadelSecretsSource from '!!raw-loader!./example-zitadel-secrets.yaml' +import ExampleZitadelInitStepsSource from '!!raw-loader!./example-zitadel-init-steps.yaml' +The stack consists of four long-running containers and a couple of short-lived containers: +- A [Traefik](https://doc.traefik.io/traefik/) reverse proxy container with upstream HTTP/2 enabled, issuing a self-signed TLS certificate. +- A Login container that is accessible via Traefik at `/ui/v2/login` +- A Zitadel container that is accessible via Traefik at all other paths than `/ui/v2/login`. +- An insecure [PostgreSQL](https://www.postgresql.org/docs/current/index.html). -The setup is tested against Docker version 20.10.17 and Docker Compose version v2.2.3 +The Traefik container and the login container call the Zitadel container via the internal Docker network at `h2c://zitadel:8080` -## Docker compose +The setup is tested against Docker version 28.3.2 and Docker Compose version v2.38.2 -By executing the commands below, you will download the following file: +By executing the commands below, you will download the following files:
docker-compose.yaml {DockerComposeSource}
+
+ example-zitadel-config.yaml + {ExampleZitadelConfigSource} +
+
+ example-zitadel-secrets.yaml + {ExampleZitadelSecretsSource} +
+
+ example-zitadel-init-steps.yaml + {ExampleZitadelInitStepsSource} +
```bash # Download the docker compose example configuration. wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/docs/self-hosting/deploy/docker-compose.yaml -# Run the database and application containers. -docker compose up --detach +# Download and adjust the example configuration file containing standard configuration. +wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/docs/self-hosting/deploy/example-zitadel-config.yaml + +# Download and adjust the example configuration file containing secret configuration. +wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/docs/self-hosting/deploy/example-zitadel-secrets.yaml + +# Download and adjust the example configuration file containing database initialization configuration. +wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/docs/self-hosting/deploy/example-zitadel-init-steps.yaml + +# Make sure you have the latest version of the images +docker compose pull + +# Run the containers +docker compose up ``` - +Open your favorite internet browser at https://localhost/ui/console?login_hint=zitadel-admin@zitadel.localhost. +Your browser warns you about the insecure self-signed TLS certificate. As localhost resolves to your local machine, you can safely proceed. +Use the password *Password1!* to log in. - - -## VideoGuide - - -## Docker compose with service account - -By executing the commands below, you will download the following file: - -
- docker-compose-sa.yaml - {DockerComposeSaSource} -
- -```bash -# Download the docker compose example configuration. -wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/docs/self-hosting/deploy/docker-compose-sa.yaml -O docker-compose.yaml - -# create the machine key directory -mkdir machinekey - -# Run the database and application containers. -docker compose up --detach - -# then you can move your machine key -mv ./machinekey/zitadel-admin-sa.json $HOME/zitadel-admin-sa.json -``` - -This key can be used to provision resources with for example [Terraform](/docs/guides/manage/terraform-provider). - - - +Read more about [the login process](/guides/integrate/login/oidc/login-users). \ No newline at end of file diff --git a/docs/docs/self-hosting/deploy/docker-compose-sa.yaml b/docs/docs/self-hosting/deploy/docker-compose-sa.yaml deleted file mode 100644 index 9edd95faa0..0000000000 --- a/docs/docs/self-hosting/deploy/docker-compose-sa.yaml +++ /dev/null @@ -1,49 +0,0 @@ -services: - zitadel: - # The user should have the permission to write to ./machinekey - user: "${UID:-1000}" - restart: 'always' - networks: - - 'zitadel' - image: 'ghcr.io/zitadel/zitadel:latest' - command: 'start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled' - environment: - ZITADEL_DATABASE_POSTGRES_HOST: db - ZITADEL_DATABASE_POSTGRES_PORT: 5432 - ZITADEL_DATABASE_POSTGRES_DATABASE: zitadel - ZITADEL_DATABASE_POSTGRES_USER_USERNAME: zitadel - ZITADEL_DATABASE_POSTGRES_USER_PASSWORD: zitadel - ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE: disable - ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME: postgres - ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD: postgres - ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE: disable - ZITADEL_EXTERNALSECURE: false - ZITADEL_FIRSTINSTANCE_MACHINEKEYPATH: /machinekey/zitadel-admin-sa.json - ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_USERNAME: zitadel-admin-sa - ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_NAME: Admin - ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINEKEY_TYPE: 1 - depends_on: - db: - condition: 'service_healthy' - ports: - - '8080:8080' - volumes: - - ./machinekey:/machinekey - - db: - restart: 'always' - image: postgres:17-alpine - environment: - PGUSER: postgres - POSTGRES_PASSWORD: postgres - networks: - - 'zitadel' - healthcheck: - test: ["CMD-SHELL", "pg_isready", "-d", "zitadel", "-U", "postgres"] - interval: '10s' - timeout: '30s' - retries: 5 - start_period: '20s' - -networks: - zitadel: diff --git a/docs/docs/self-hosting/deploy/docker-compose.yaml b/docs/docs/self-hosting/deploy/docker-compose.yaml index f5164eb3b7..23d651efc9 100644 --- a/docs/docs/self-hosting/deploy/docker-compose.yaml +++ b/docs/docs/self-hosting/deploy/docker-compose.yaml @@ -1,41 +1,117 @@ services: - zitadel: - restart: 'always' - networks: - - 'zitadel' - image: 'ghcr.io/zitadel/zitadel:latest' - command: 'start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled' + + db: + image: postgres:17-alpine + restart: unless-stopped environment: - ZITADEL_DATABASE_POSTGRES_HOST: db - ZITADEL_DATABASE_POSTGRES_PORT: 5432 - ZITADEL_DATABASE_POSTGRES_DATABASE: zitadel - ZITADEL_DATABASE_POSTGRES_USER_USERNAME: zitadel - ZITADEL_DATABASE_POSTGRES_USER_PASSWORD: zitadel - ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE: disable - ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME: postgres - ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD: postgres - ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE: disable - ZITADEL_EXTERNALSECURE: false + - POSTGRES_USER=root + - POSTGRES_PASSWORD=postgres + networks: + - 'storage' + healthcheck: + test: [ "CMD-SHELL", "pg_isready", "-d", "db_prod" ] + interval: 10s + timeout: 60s + retries: 5 + start_period: 10s + volumes: + - 'data:/var/lib/postgresql/data:rw' + + zitadel-init: + restart: 'no' + networks: + - 'storage' + image: 'ghcr.io/zitadel/zitadel:v4.0.0-rc.2' + command: [ init, --config, /example-zitadel-config.yaml, --config, /example-zitadel-secrets.yaml ] depends_on: db: condition: 'service_healthy' - ports: - - '8080:8080' + volumes: + - './example-zitadel-config.yaml:/example-zitadel-config.yaml:ro' + - './example-zitadel-secrets.yaml:/example-zitadel-secrets.yaml:ro' - db: - restart: 'always' - image: postgres:17-alpine - environment: - PGUSER: postgres - POSTGRES_PASSWORD: postgres + zitadel-setup: + restart: 'no' networks: - - 'zitadel' + - 'storage' + image: 'ghcr.io/zitadel/zitadel:v4.0.0-rc.2' + command: [ setup, --config, /current-dir/example-zitadel-config.yaml, --config, /current-dir/example-zitadel-secrets.yaml, --steps, /current-dir/example-zitadel-init-steps.yaml, --masterkey, MasterkeyNeedsToHave32Characters ] + depends_on: + zitadel-init: + condition: 'service_completed_successfully' + restart: false + volumes: + - '.:/current-dir:rw' + + zitadel: + restart: 'unless-stopped' + networks: + - 'backend' + - 'storage' + labels: + - "traefik.http.routers.zitadel.rule=!PathPrefix(`/ui/v2/login`)" + - "traefik.http.routers.zitadel.tls=true" # Traefik uses a self-signed certificate + - "traefik.http.services.zitadel.loadbalancer.passhostheader=true" + - "traefik.http.services.zitadel.loadbalancer.server.scheme=h2c" + - "traefik.http.services.zitadel.loadbalancer.server.port=8080" + image: 'ghcr.io/zitadel/zitadel:v4.0.0-rc.2' + command: [ start, --config, /example-zitadel-config.yaml, --config, /example-zitadel-secrets.yaml, --masterkey, MasterkeyNeedsToHave32Characters ] + depends_on: + zitadel-setup: + condition: 'service_completed_successfully' + restart: true + volumes: + - './example-zitadel-config.yaml:/example-zitadel-config.yaml:ro' + - './example-zitadel-secrets.yaml:/example-zitadel-secrets.yaml:ro' healthcheck: - test: ["CMD-SHELL", "pg_isready", "-d", "zitadel", "-U", "postgres"] - interval: '10s' - timeout: '30s' + test: [ "CMD", "/app/zitadel", "ready", "--config", "/example-zitadel-config.yaml", "--config", "/example-zitadel-secrets.yaml" ] + interval: 10s + timeout: 60s retries: 5 - start_period: '20s' + start_period: 10s + + login: + restart: 'unless-stopped' + labels: + - "traefik.http.routers.login.rule=PathPrefix(`/ui/v2/login`)" + - "traefik.http.routers.login.tls=true" # Traefik uses a self-signed certificate + - "traefik.http.services.login.loadbalancer.passhostheader=true" + - "traefik.http.services.login.loadbalancer.server.port=3000" + image: 'ghcr.io/zitadel/zitadel-login:v4.0.0-rc.2' + # If you can't use the network_mode service:zitadel, you can pass the environment variable CUSTOM_REQUEST_HEADERS=Host:localhost instead. + network_mode: service:zitadel + environment: + - ZITADEL_API_URL=http://localhost:8080 + - NEXT_PUBLIC_BASE_PATH=/ui/v2/login + - ZITADEL_SERVICE_USER_TOKEN_FILE=/current-dir/login-client-pat + user: "${UID:-1000}" + volumes: + - '.:/current-dir:ro' + depends_on: + zitadel-setup: + condition: 'service_completed_successfully' + restart: false + + traefik: + image: traefik:latest + command: --providers.docker --api.insecure=true --entrypoints.websecure.address=:443 --log.level=DEBUG --accesslog + networks: + - 'backend' + ports: + - "443:443" + - "8080:8080" + volumes: + - /var/run/docker.sock:/var/run/docker.sock + depends_on: + zitadel: + condition: 'service_healthy' + login: + condition: 'service_started' networks: - zitadel: + storage: + backend: + + +volumes: + data: diff --git a/docs/docs/self-hosting/deploy/loadbalancing-example/example-zitadel-config.yaml b/docs/docs/self-hosting/deploy/example-zitadel-config.yaml similarity index 60% rename from docs/docs/self-hosting/deploy/loadbalancing-example/example-zitadel-config.yaml rename to docs/docs/self-hosting/deploy/example-zitadel-config.yaml index af5bb5145c..baacd6cefe 100644 --- a/docs/docs/self-hosting/deploy/loadbalancing-example/example-zitadel-config.yaml +++ b/docs/docs/self-hosting/deploy/example-zitadel-config.yaml @@ -1,7 +1,6 @@ # All possible options and their defaults: https://github.com/zitadel/zitadel/blob/main/cmd/defaults.yaml ExternalSecure: true -ExternalDomain: 127.0.0.1.sslip.io ExternalPort: 443 # Traefik terminates TLS. Inside the Docker network, we use plain text. @@ -16,14 +15,8 @@ Database: User.SSL.Mode: 'disable' Admin.SSL.Mode: 'disable' -# By default, ZITADEL should redirect to /ui/v2/login -OIDC: - DefaultLoginURLV2: "/ui/v2/login/login?authRequest=" # ZITADEL_OIDC_DEFAULTLOGINURLV2 - DefaultLogoutURLV2: "/ui/v2/login/logout?post_logout_redirect=" # ZITADEL_OIDC_DEFAULTLOGOUTURLV2 -SAML.DefaultLoginURLV2: "/ui/v2/login/login?authRequest=" # ZITADEL_SAML_DEFAULTLOGINURLV2 - # Access logs allow us to debug Network issues LogStore.Access.Stdout.Enabled: true # Skipping the MFA init step allows us to immediately authenticate at the console -DefaultInstance.LoginPolicy.MfaInitSkipLifetime: "0s" \ No newline at end of file +DefaultInstance.LoginPolicy.MfaInitSkipLifetime: "0s" diff --git a/docs/docs/self-hosting/deploy/loadbalancing-example/example-zitadel-init-steps.yaml b/docs/docs/self-hosting/deploy/example-zitadel-init-steps.yaml similarity index 58% rename from docs/docs/self-hosting/deploy/loadbalancing-example/example-zitadel-init-steps.yaml rename to docs/docs/self-hosting/deploy/example-zitadel-init-steps.yaml index 9bdf41269d..373c6ae744 100644 --- a/docs/docs/self-hosting/deploy/loadbalancing-example/example-zitadel-init-steps.yaml +++ b/docs/docs/self-hosting/deploy/example-zitadel-init-steps.yaml @@ -1,12 +1,11 @@ # All possible options and their defaults: https://github.com/zitadel/zitadel/blob/main/cmd/setup/steps.yaml FirstInstance: - PatPath: '/pat' + LoginClientPatPath: '/current-dir/login-client-pat' Org: # We want to authenticate immediately at the console without changing the password - Human: - PasswordChangeRequired: false - Machine: + Human.PasswordChangeRequired: false + LoginClient: Machine: - Username: 'login-container' - Name: 'Login Container' + Username: 'login-client' + Name: 'Automatically Initialized IAM Login Client' Pat.ExpirationDate: '2029-01-01T00:00:00Z' \ No newline at end of file diff --git a/docs/docs/self-hosting/deploy/loadbalancing-example/example-zitadel-secrets.yaml b/docs/docs/self-hosting/deploy/example-zitadel-secrets.yaml similarity index 100% rename from docs/docs/self-hosting/deploy/loadbalancing-example/example-zitadel-secrets.yaml rename to docs/docs/self-hosting/deploy/example-zitadel-secrets.yaml diff --git a/docs/docs/self-hosting/deploy/loadbalancing-example/.gitignore b/docs/docs/self-hosting/deploy/loadbalancing-example/.gitignore deleted file mode 100644 index 8a28618b17..0000000000 --- a/docs/docs/self-hosting/deploy/loadbalancing-example/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.env-file \ No newline at end of file diff --git a/docs/docs/self-hosting/deploy/loadbalancing-example/docker-compose.yaml b/docs/docs/self-hosting/deploy/loadbalancing-example/docker-compose.yaml deleted file mode 100644 index 96a87fa8d7..0000000000 --- a/docs/docs/self-hosting/deploy/loadbalancing-example/docker-compose.yaml +++ /dev/null @@ -1,157 +0,0 @@ -services: - - db: - image: postgres:17-alpine - restart: unless-stopped - environment: - - POSTGRES_USER=root - - POSTGRES_PASSWORD=postgres - networks: - - 'storage' - healthcheck: - test: ["CMD-SHELL", "pg_isready", "-d", "db_prod"] - interval: 10s - timeout: 60s - retries: 5 - start_period: 10s - volumes: - - 'data:/var/lib/postgresql/data:rw' - - zitadel-init: - restart: 'no' - networks: - - 'storage' - image: 'ghcr.io/zitadel/zitadel:latest' - command: 'init --config /example-zitadel-config.yaml --config /example-zitadel-secrets.yaml' - depends_on: - db: - condition: 'service_healthy' - volumes: - - './example-zitadel-config.yaml:/example-zitadel-config.yaml:ro' - - './example-zitadel-secrets.yaml:/example-zitadel-secrets.yaml:ro' - - zitadel-setup: - restart: 'no' - networks: - - 'storage' - # We use the debug image so we have the environment to - # - create the .env file for the login to authenticate at Zitadel - # - set the correct permissions for the .env-file folder - image: 'ghcr.io/zitadel/zitadel:latest-debug' - user: root - entrypoint: '/bin/sh' - command: - - -c - - > - /app/zitadel setup - --config /example-zitadel-config.yaml - --config /example-zitadel-secrets.yaml - --steps /example-zitadel-init-steps.yaml - --masterkey ${ZITADEL_MASTERKEY} && - mv /pat /.env-file/pat || exit 0 && - echo ZITADEL_SERVICE_USER_TOKEN=$(cat /.env-file/pat) > /.env-file/.env && - chown -R 1001:${GID} /.env-file && - chmod -R 770 /.env-file - environment: - - GID - depends_on: - zitadel-init: - condition: 'service_completed_successfully' - restart: false - volumes: - - './.env-file:/.env-file:rw' - - './example-zitadel-config.yaml:/example-zitadel-config.yaml:ro' - - './example-zitadel-secrets.yaml:/example-zitadel-secrets.yaml:ro' - - './example-zitadel-init-steps.yaml:/example-zitadel-init-steps.yaml:ro' - - zitadel: - restart: 'unless-stopped' - networks: - - 'backend' - - 'storage' - image: 'ghcr.io/zitadel/zitadel:latest' - command: > - start --config /example-zitadel-config.yaml - --config /example-zitadel-secrets.yaml - --masterkey ${ZITADEL_MASTERKEY} - depends_on: - zitadel-setup: - condition: 'service_completed_successfully' - restart: true - volumes: - - './example-zitadel-config.yaml:/example-zitadel-config.yaml:ro' - - './example-zitadel-secrets.yaml:/example-zitadel-secrets.yaml:ro' - ports: - - "8080:8080" - healthcheck: - test: [ - "CMD", "/app/zitadel", "ready", - "--config", "/example-zitadel-config.yaml", - "--config", "/example-zitadel-secrets.yaml" - ] - interval: 10s - timeout: 60s - retries: 5 - start_period: 10s - - # The use-new-login service configures Zitadel to use the new login v2 for all applications. - # It also gives the setupped machine user the necessary IAM_LOGIN_CLIENT role. - use-new-login: - restart: 'on-failure' - user: "1001" - networks: - - 'backend' - image: 'badouralix/curl-jq:alpine' - entrypoint: '/bin/sh' - command: - - -c - - > - curl -X PUT -H "Host: 127.0.0.1.sslip.io" -H "Authorization: Bearer $(cat ./.env-file/pat)" --insecure http://zitadel:8080/v2/features/instance -d '{"loginV2": {"required": true}}' && - LOGIN_USER=$(curl --fail-with-body -H "Host: 127.0.0.1.sslip.io" -H "Authorization: Bearer $(cat ./.env-file/pat)" --insecure http://zitadel:8080/auth/v1/users/me | jq -r '.user.id') && - curl -X PUT -H "Host: 127.0.0.1.sslip.io" -H "Authorization: Bearer $(cat ./.env-file/pat)" --insecure http://zitadel:8080/admin/v1/members/$${LOGIN_USER} -d '{"roles": ["IAM_OWNER", "IAM_LOGIN_CLIENT"]}' - volumes: - - './.env-file:/.env-file:ro' - depends_on: - zitadel: - condition: 'service_healthy' - restart: false - - login: - restart: 'unless-stopped' - networks: - - 'backend' - image: 'ghcr.io/zitadel/login:main' - environment: - - ZITADEL_API_URL=http://zitadel:8080 - - CUSTOM_REQUEST_HEADERS=Host:127.0.0.1.sslip.io - - NEXT_PUBLIC_BASE_PATH="/ui/v2/login" - user: "${UID:-1000}" - volumes: - - './.env-file:/.env-file:ro' - depends_on: - zitadel: - condition: 'service_healthy' - restart: false - - traefik: - restart: 'unless-stopped' - networks: - - 'backend' - image: "traefik:latest" - ports: - - "80:80" - - "443:443" - volumes: - - "./example-traefik.yaml:/etc/traefik/traefik.yaml" - depends_on: - zitadel: - condition: 'service_healthy' - login: - condition: 'service_started' - -networks: - storage: - backend: - -volumes: - data: \ No newline at end of file diff --git a/docs/docs/self-hosting/deploy/loadbalancing-example/example-traefik.yaml b/docs/docs/self-hosting/deploy/loadbalancing-example/example-traefik.yaml deleted file mode 100644 index a3af425172..0000000000 --- a/docs/docs/self-hosting/deploy/loadbalancing-example/example-traefik.yaml +++ /dev/null @@ -1,40 +0,0 @@ -log: - level: DEBUG - -accessLog: {} - -entrypoints: - websecure: - address: ":443" - -providers: - file: - filename: /etc/traefik/traefik.yaml - -http: - routers: - login: - entryPoints: - - websecure - service: login - rule: 'Host(`127.0.0.1.sslip.io`) && PathPrefix(`/ui/v2/login`)' - tls: {} - zitadel: - entryPoints: - - websecure - service: zitadel - rule: 'Host(`127.0.0.1.sslip.io`) && !PathPrefix(`/ui/v2/login`)' - tls: {} - - services: - login: - loadBalancer: - servers: - - url: http://login:3000 - passHostHeader: true - zitadel: - loadBalancer: - servers: - - url: h2c://zitadel:8080 - passHostHeader: true - diff --git a/docs/docs/self-hosting/deploy/loadbalancing-example/loadbalancing-example.mdx b/docs/docs/self-hosting/deploy/loadbalancing-example/loadbalancing-example.mdx deleted file mode 100644 index 3fb4784ea0..0000000000 --- a/docs/docs/self-hosting/deploy/loadbalancing-example/loadbalancing-example.mdx +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: A Zitadel Load Balancing Example ---- - -import CodeBlock from '@theme/CodeBlock'; -import DockerComposeSource from '!!raw-loader!./docker-compose.yaml' -import ExampleTraefikSource from '!!raw-loader!./example-traefik.yaml' -import ExampleZITADELConfigSource from '!!raw-loader!./example-zitadel-config.yaml' -import ExampleZITADELSecretsSource from '!!raw-loader!./example-zitadel-secrets.yaml' -import ExampleZITADELInitStepsSource from '!!raw-loader!./example-zitadel-init-steps.yaml' - -The stack consists of four long-running containers and a couple of short-lived containers: -- A [Traefik](https://doc.traefik.io/traefik/) reverse proxy container with upstream HTTP/2 enabled, issuing a self-signed TLS certificate. -- A Login container that is accessible via Traefik at `/ui/v2/login` -- A Zitadel container that is accessible via Traefik at all other paths than `/ui/v2/login`. -- An insecure [PostgreSQL](https://www.postgresql.org/docs/current/index.html). - -The Traefik container and the login container call the Zitadel container via the internal Docker network at `h2c://zitadel:8080` - -The setup is tested against Docker version 28.0.4 and Docker Compose version v2.34.0 - -By executing the commands below, you will download the following files: - -
- docker-compose.yaml - {DockerComposeSource} -
-
- example-traefik.yaml - {ExampleTraefikSource} -
-
- example-zitadel-config.yaml - {ExampleZITADELConfigSource} -
-
- example-zitadel-secrets.yaml - {ExampleZITADELSecretsSource} -
-
- example-zitadel-init-steps.yaml - {ExampleZITADELInitStepsSource} -
- -```bash -# Download the docker compose example configuration. -wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/docs/self-hosting/deploy/loadbalancing-example/docker-compose.yaml - -# Download the Traefik example configuration. -wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/docs/self-hosting/deploy/loadbalancing-example/example-traefik.yaml - -# Download and adjust the example configuration file containing standard configuration. -wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/docs/self-hosting/deploy/loadbalancing-example/example-zitadel-config.yaml - -# Download and adjust the example configuration file containing secret configuration. -wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/docs/self-hosting/deploy/loadbalancing-example/example-zitadel-secrets.yaml - -# Download and adjust the example configuration file containing database initialization configuration. -wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/docs/self-hosting/deploy/loadbalancing-example/example-zitadel-init-steps.yaml - -# A single ZITADEL instance always needs the same 32 bytes long masterkey -# Generate one to a file if you haven't done so already and pass it as environment variable -LC_ALL=C tr -dc '[:graph:]' ./zitadel-masterkey -export ZITADEL_MASTERKEY="$(cat ./zitadel-masterkey)" - -# Run the database and application containers -docker compose up --detach --wait -``` - -Open your favorite internet browser at https://127.0.0.1.sslip.io/ui/console?login_hint=zitadel-admin@zitadel.127.0.0.1.sslip.io. -Your browser warns you about the insecure self-signed TLS certificate. As 127.0.0.1.sslip.io resolves to your localhost, you can safely proceed. -Use the password *Password1!* to log in. - -Read more about [the login process](/guides/integrate/login/oidc/login-users). \ No newline at end of file diff --git a/docs/docs/self-hosting/manage/service_ping.md b/docs/docs/self-hosting/manage/service_ping.md new file mode 100644 index 0000000000..65f16725ad --- /dev/null +++ b/docs/docs/self-hosting/manage/service_ping.md @@ -0,0 +1,83 @@ +--- +title: Service Ping +sidebar_label: Service Ping +--- + +Service Ping is a feature that periodically sends anonymized analytics and usage data from your ZITADEL system to a central endpoint. +This data helps improve ZITADEL by providing insights into its usage patterns. + +The feature is enabled by default, but can be disabled either completely or for specific reports. +Checkout the configuration options below. + +## Data Sent by Service Ping + +### Base Information + +If the feature is enabled, the base information will always be sent. To prevent that, you can opt out by disabling the entire Service Ping: + +```yaml +ServicePing: + Enabled: false # ZITADEL_SERVICEPING_ENABLED +``` + +The base information sent back includes the following: +- your systemID +- the currently run version of ZITADEL +- information on all instances + - id + - creation date + - domains + +### Resource Counts + +Resource counts is a report that provides us with information about the number of resources in your ZITADEL instances. + +The following resources are counted: +- Instances +- Organizations +- Projects per organization +- Users per organization +- Instance Administrators +- Identity Providers +- LDAP Identity Providers +- Actions (V1) +- Targets and set up executions +- Login Policies +- Password Complexity Policies +- Password Expiry Policies +- Lockout Policies + +The list might be extended in the future to include more resources. + +To disable this report, set the following in your configuration file: + +```yaml +ServicePing: + Telemetry: + ResourceCounts: + Enabled: false # ZITADEL_SERVICEPING_TELEMETRY_RESOURCECOUNT_ENABLED +``` + +## Configuration + +The Service Ping feature can be configured through the runtime configuration. Please check out the configuration file +for all available options. Below is a list of the most important options: + +### Interval + +This defines at which interval the Service Ping feature sends data to the central endpoint. It supports the extended cron syntax +and by default is set to `@daily`, which means it will send data every day. The time is randomized on startup to prevent +all systems from sending data at the same time. + +You can adjust it to your needs to make sure there is no performance impact on your system. +For example, if you already have some scheduled job syncing data in and out of ZITADEL around a specific time or have regularly a +lot of traffic during the day, you might want to change it to a different time, e.g. `15 4 * * *` to send it every day at 4:15 AM. + +The interval must be at least 30 minutes to prevent too frequent requests to the central endpoint. + +### MaxAttempts + +This defines how many attempts the Service Ping feature will make to send data to the central endpoint before giving up +for a specific interval and report. If one report fails, it will be retried up to this number of times. +Other reports will still be handled in parallel and have their own retry count. This means if the base information +only succeeded after three attempts, the resource count still has five attempts to be sent. diff --git a/docs/sidebars.js b/docs/sidebars.js index 578a337da9..acca7b1659 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -1084,7 +1084,6 @@ module.exports = { "self-hosting/deploy/devcontainer", "self-hosting/deploy/knative", "self-hosting/deploy/kubernetes", - "self-hosting/deploy/loadbalancing-example/loadbalancing-example", "self-hosting/deploy/troubleshooting/troubleshooting", ], }, @@ -1118,6 +1117,7 @@ module.exports = { "self-hosting/manage/tls_modes", "self-hosting/manage/database/database", "self-hosting/manage/cache", + "self-hosting/manage/service_ping", "self-hosting/manage/updating_scaling", "self-hosting/manage/usage_control", { diff --git a/docs/src/components/authrequest.jsx b/docs/src/components/authrequest.jsx index 82ecc91337..f864b1cbbb 100644 --- a/docs/src/components/authrequest.jsx +++ b/docs/src/components/authrequest.jsx @@ -111,7 +111,7 @@ export function SetAuthRequest() { "urn:zitadel:iam:org:project:id:zitadel:aud", "urn:zitadel:iam:user:metadata", `urn:zitadel:iam:org:id:${ - organizationId ? organizationId : "[organizationId]" + organizationId ? organizationId : "[Organization ID]" }`, ]; @@ -525,7 +525,7 @@ export function SetAuthRequest() { const value = event.target.value; setOrganizationId(value); allScopes[7] = `urn:zitadel:iam:org:id:${ - value ? value : "[organizationId]" + value ? value : "[Organization ID]" }`; toggleScope(8, true); setScope( diff --git a/internal/api/grpc/action/v2/execution.go b/internal/api/grpc/action/v2/execution.go new file mode 100644 index 0000000000..6941f62ace --- /dev/null +++ b/internal/api/grpc/action/v2/execution.go @@ -0,0 +1,92 @@ +package action + +import ( + "context" + + "connectrpc.com/connect" + "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/zitadel/zitadel/internal/api/authz" + "github.com/zitadel/zitadel/internal/command" + "github.com/zitadel/zitadel/internal/domain" + "github.com/zitadel/zitadel/internal/repository/execution" + "github.com/zitadel/zitadel/internal/zerrors" + "github.com/zitadel/zitadel/pkg/grpc/action/v2" +) + +func (s *Server) SetExecution(ctx context.Context, req *connect.Request[action.SetExecutionRequest]) (*connect.Response[action.SetExecutionResponse], error) { + reqTargets := req.Msg.GetTargets() + targets := make([]*execution.Target, len(reqTargets)) + for i, target := range reqTargets { + targets[i] = &execution.Target{Type: domain.ExecutionTargetTypeTarget, Target: target} + } + set := &command.SetExecution{ + Targets: targets, + } + var err error + var details *domain.ObjectDetails + instanceID := authz.GetInstance(ctx).InstanceID() + switch t := req.Msg.GetCondition().GetConditionType().(type) { + case *action.Condition_Request: + cond := executionConditionFromRequest(t.Request) + details, err = s.command.SetExecutionRequest(ctx, cond, set, instanceID) + case *action.Condition_Response: + cond := executionConditionFromResponse(t.Response) + details, err = s.command.SetExecutionResponse(ctx, cond, set, instanceID) + case *action.Condition_Event: + cond := executionConditionFromEvent(t.Event) + details, err = s.command.SetExecutionEvent(ctx, cond, set, instanceID) + case *action.Condition_Function: + details, err = s.command.SetExecutionFunction(ctx, command.ExecutionFunctionCondition(t.Function.GetName()), set, instanceID) + default: + err = zerrors.ThrowInvalidArgument(nil, "ACTION-5r5Ju", "Errors.Execution.ConditionInvalid") + } + if err != nil { + return nil, err + } + return connect.NewResponse(&action.SetExecutionResponse{ + SetDate: timestamppb.New(details.EventDate), + }), nil +} + +func (s *Server) ListExecutionFunctions(ctx context.Context, _ *connect.Request[action.ListExecutionFunctionsRequest]) (*connect.Response[action.ListExecutionFunctionsResponse], error) { + return connect.NewResponse(&action.ListExecutionFunctionsResponse{ + Functions: s.ListActionFunctions(), + }), nil +} + +func (s *Server) ListExecutionMethods(ctx context.Context, _ *connect.Request[action.ListExecutionMethodsRequest]) (*connect.Response[action.ListExecutionMethodsResponse], error) { + return connect.NewResponse(&action.ListExecutionMethodsResponse{ + Methods: s.ListGRPCMethods(), + }), nil +} + +func (s *Server) ListExecutionServices(ctx context.Context, _ *connect.Request[action.ListExecutionServicesRequest]) (*connect.Response[action.ListExecutionServicesResponse], error) { + return connect.NewResponse(&action.ListExecutionServicesResponse{ + Services: s.ListGRPCServices(), + }), nil +} + +func executionConditionFromRequest(request *action.RequestExecution) *command.ExecutionAPICondition { + return &command.ExecutionAPICondition{ + Method: request.GetMethod(), + Service: request.GetService(), + All: request.GetAll(), + } +} + +func executionConditionFromResponse(response *action.ResponseExecution) *command.ExecutionAPICondition { + return &command.ExecutionAPICondition{ + Method: response.GetMethod(), + Service: response.GetService(), + All: response.GetAll(), + } +} + +func executionConditionFromEvent(event *action.EventExecution) *command.ExecutionEventCondition { + return &command.ExecutionEventCondition{ + Event: event.GetEvent(), + Group: event.GetGroup(), + All: event.GetAll(), + } +} diff --git a/internal/api/grpc/action/v2/integration_test/execution_target_test.go b/internal/api/grpc/action/v2/integration_test/execution_target_test.go new file mode 100644 index 0000000000..f5bd7c50ec --- /dev/null +++ b/internal/api/grpc/action/v2/integration_test/execution_target_test.go @@ -0,0 +1,1310 @@ +//go:build integration + +package action_test + +import ( + "context" + "encoding/base64" + "net/http" + "net/url" + "strings" + "testing" + "time" + + "github.com/brianvoe/gofakeit/v6" + "github.com/crewjam/saml" + "github.com/crewjam/saml/samlsp" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/zitadel/oidc/v3/pkg/client/rp" + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/op" + "golang.org/x/text/language" + "google.golang.org/protobuf/types/known/durationpb" + + "github.com/zitadel/zitadel/internal/api/grpc/server/middleware" + oidc_api "github.com/zitadel/zitadel/internal/api/oidc" + saml_api "github.com/zitadel/zitadel/internal/api/saml" + "github.com/zitadel/zitadel/internal/domain" + "github.com/zitadel/zitadel/internal/integration" + "github.com/zitadel/zitadel/internal/query" + "github.com/zitadel/zitadel/pkg/grpc/action/v2" + "github.com/zitadel/zitadel/pkg/grpc/app" + "github.com/zitadel/zitadel/pkg/grpc/management" + "github.com/zitadel/zitadel/pkg/grpc/metadata" + oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2" + saml_pb "github.com/zitadel/zitadel/pkg/grpc/saml/v2" + "github.com/zitadel/zitadel/pkg/grpc/session/v2" + "github.com/zitadel/zitadel/pkg/grpc/user/v2" +) + +const ( + redirectURIImplicit = "http://localhost:9999/callback" +) + +var ( + loginV2 = &app.LoginVersion{Version: &app.LoginVersion_LoginV2{LoginV2: &app.LoginV2{BaseUri: nil}}} +) + +func TestServer_ExecutionTarget(t *testing.T) { + instance := integration.NewInstance(CTX) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + fullMethod := action.ActionService_GetTarget_FullMethodName + + tests := []struct { + name string + ctx context.Context + dep func(context.Context, *action.GetTargetRequest, *action.GetTargetResponse) (closeF func(), calledF func() bool) + clean func(context.Context) + req *action.GetTargetRequest + want *action.GetTargetResponse + wantErr bool + }{ + { + name: "GetTarget, request and response, ok", + ctx: isolatedIAMOwnerCTX, + dep: func(ctx context.Context, request *action.GetTargetRequest, response *action.GetTargetResponse) (func(), func() bool) { + + orgID := instance.DefaultOrg.Id + projectID := "" + userID := instance.Users.Get(integration.UserTypeIAMOwner).ID + + // create target for target changes + targetCreatedName := gofakeit.Name() + targetCreatedURL := "https://nonexistent" + + targetCreated := instance.CreateTarget(ctx, t, targetCreatedName, targetCreatedURL, domain.TargetTypeCall, false) + + // request received by target + wantRequest := &middleware.ContextInfoRequest{FullMethod: fullMethod, InstanceID: instance.ID(), OrgID: orgID, ProjectID: projectID, UserID: userID, Request: middleware.Message{Message: request}} + changedRequest := &action.GetTargetRequest{Id: targetCreated.GetId()} + // replace original request with different targetID + urlRequest, closeRequest, calledRequest, _ := integration.TestServerCallProto(wantRequest, 0, http.StatusOK, changedRequest) + + targetRequest := waitForTarget(ctx, t, instance, urlRequest, domain.TargetTypeCall, false) + + waitForExecutionOnCondition(ctx, t, instance, conditionRequestFullMethod(fullMethod), []string{targetRequest.GetId()}) + + // expected response from the GetTarget + expectedResponse := &action.GetTargetResponse{ + Target: &action.Target{ + Id: targetCreated.GetId(), + CreationDate: targetCreated.GetCreationDate(), + ChangeDate: targetCreated.GetCreationDate(), + Name: targetCreatedName, + TargetType: &action.Target_RestCall{ + RestCall: &action.RESTCall{ + InterruptOnError: false, + }, + }, + Timeout: durationpb.New(5 * time.Second), + Endpoint: targetCreatedURL, + SigningKey: targetCreated.GetSigningKey(), + }, + } + + changedResponse := &action.GetTargetResponse{ + Target: &action.Target{ + Id: "changed", + CreationDate: targetCreated.GetCreationDate(), + ChangeDate: targetCreated.GetCreationDate(), + Name: targetCreatedName, + TargetType: &action.Target_RestCall{ + RestCall: &action.RESTCall{ + InterruptOnError: false, + }, + }, + Timeout: durationpb.New(5 * time.Second), + Endpoint: targetCreatedURL, + SigningKey: targetCreated.GetSigningKey(), + }, + } + // content for update + response.Target = &action.Target{ + Id: "changed", + CreationDate: targetCreated.GetCreationDate(), + ChangeDate: targetCreated.GetCreationDate(), + Name: targetCreatedName, + TargetType: &action.Target_RestCall{ + RestCall: &action.RESTCall{ + InterruptOnError: false, + }, + }, + Timeout: durationpb.New(5 * time.Second), + Endpoint: targetCreatedURL, + SigningKey: targetCreated.GetSigningKey(), + } + + // response received by target + wantResponse := &middleware.ContextInfoResponse{ + FullMethod: fullMethod, + InstanceID: instance.ID(), + OrgID: orgID, + ProjectID: projectID, + UserID: userID, + Request: middleware.Message{Message: changedRequest}, + Response: middleware.Message{Message: expectedResponse}, + } + // after request with different targetID, return changed response + targetResponseURL, closeResponse, calledResponse, _ := integration.TestServerCallProto(wantResponse, 0, http.StatusOK, changedResponse) + + targetResponse := waitForTarget(ctx, t, instance, targetResponseURL, domain.TargetTypeCall, false) + waitForExecutionOnCondition(ctx, t, instance, conditionResponseFullMethod(fullMethod), []string{targetResponse.GetId()}) + return func() { + closeRequest() + closeResponse() + }, func() bool { + if calledRequest() != 1 { + return false + } + if calledResponse() != 1 { + return false + } + return true + } + }, + clean: func(ctx context.Context) { + instance.DeleteExecution(ctx, t, conditionRequestFullMethod(fullMethod)) + instance.DeleteExecution(ctx, t, conditionResponseFullMethod(fullMethod)) + }, + req: &action.GetTargetRequest{ + Id: "something", + }, + want: &action.GetTargetResponse{ + // defined in the dependency function + }, + }, + { + name: "GetTarget, request, interrupt", + ctx: isolatedIAMOwnerCTX, + dep: func(ctx context.Context, request *action.GetTargetRequest, response *action.GetTargetResponse) (func(), func() bool) { + orgID := instance.DefaultOrg.Id + projectID := "" + userID := instance.Users.Get(integration.UserTypeIAMOwner).ID + + // request received by target + wantRequest := &middleware.ContextInfoRequest{FullMethod: fullMethod, InstanceID: instance.ID(), OrgID: orgID, ProjectID: projectID, UserID: userID, Request: middleware.Message{Message: request}} + urlRequest, closeRequest, calledRequest, _ := integration.TestServerCallProto(wantRequest, 0, http.StatusInternalServerError, nil) + + targetRequest := waitForTarget(ctx, t, instance, urlRequest, domain.TargetTypeCall, true) + waitForExecutionOnCondition(ctx, t, instance, conditionRequestFullMethod(fullMethod), []string{targetRequest.GetId()}) + // GetTarget with used target + request.Id = targetRequest.GetId() + return func() { + closeRequest() + }, func() bool { + return calledRequest() == 1 + } + }, + clean: func(ctx context.Context) { + instance.DeleteExecution(ctx, t, conditionRequestFullMethod(fullMethod)) + }, + req: &action.GetTargetRequest{}, + wantErr: true, + }, + { + name: "GetTarget, response, interrupt", + ctx: isolatedIAMOwnerCTX, + dep: func(ctx context.Context, request *action.GetTargetRequest, response *action.GetTargetResponse) (func(), func() bool) { + orgID := instance.DefaultOrg.Id + projectID := "" + userID := instance.Users.Get(integration.UserTypeIAMOwner).ID + + // create target for target changes + targetCreatedName := gofakeit.Name() + targetCreatedURL := "https://nonexistent" + + targetCreated := instance.CreateTarget(ctx, t, targetCreatedName, targetCreatedURL, domain.TargetTypeCall, false) + + // GetTarget with used target + request.Id = targetCreated.GetId() + + // expected response from the GetTarget + expectedResponse := &action.GetTargetResponse{ + Target: &action.Target{ + Id: targetCreated.GetId(), + CreationDate: targetCreated.GetCreationDate(), + ChangeDate: targetCreated.GetCreationDate(), + Name: targetCreatedName, + TargetType: &action.Target_RestCall{ + RestCall: &action.RESTCall{ + InterruptOnError: false, + }, + }, + Timeout: durationpb.New(5 * time.Second), + Endpoint: targetCreatedURL, + SigningKey: targetCreated.GetSigningKey(), + }, + } + + // response received by target + wantResponse := &middleware.ContextInfoResponse{ + FullMethod: fullMethod, + InstanceID: instance.ID(), + OrgID: orgID, + ProjectID: projectID, + UserID: userID, + Request: middleware.Message{Message: request}, + Response: middleware.Message{Message: expectedResponse}, + } + // after request with different targetID, return changed response + targetResponseURL, closeResponse, calledResponse, _ := integration.TestServerCallProto(wantResponse, 0, http.StatusInternalServerError, nil) + + targetResponse := waitForTarget(ctx, t, instance, targetResponseURL, domain.TargetTypeCall, true) + waitForExecutionOnCondition(ctx, t, instance, conditionResponseFullMethod(fullMethod), []string{targetResponse.GetId()}) + return func() { + closeResponse() + }, func() bool { + return calledResponse() == 1 + } + }, + clean: func(ctx context.Context) { + instance.DeleteExecution(ctx, t, conditionResponseFullMethod(fullMethod)) + }, + req: &action.GetTargetRequest{}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + closeF, calledF := tt.dep(tt.ctx, tt.req, tt.want) + defer closeF() + + retryDuration, tick := integration.WaitForAndTickWithMaxDuration(tt.ctx, time.Minute) + require.EventuallyWithT(t, func(ttt *assert.CollectT) { + got, err := instance.Client.ActionV2.GetTarget(tt.ctx, tt.req) + if tt.wantErr { + require.Error(ttt, err) + return + } + require.NoError(ttt, err) + assert.EqualExportedValues(ttt, tt.want.GetTarget(), got.GetTarget()) + + }, retryDuration, tick, "timeout waiting for expected execution result") + + if tt.clean != nil { + tt.clean(tt.ctx) + } + require.True(t, calledF()) + }) + } +} + +func TestServer_ExecutionTarget_Event(t *testing.T) { + instance := integration.NewInstance(CTX) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + + event := "session.added" + urlRequest, closeF, calledF, resetF := integration.TestServerCall(nil, 0, http.StatusOK, nil) + defer closeF() + + targetResponse := waitForTarget(isolatedIAMOwnerCTX, t, instance, urlRequest, domain.TargetTypeWebhook, true) + waitForExecutionOnCondition(isolatedIAMOwnerCTX, t, instance, conditionEvent(event), []string{targetResponse.GetId()}) + + tests := []struct { + name string + ctx context.Context + eventCount int + expectedCalls int + clean func(context.Context) + wantErr bool + }{ + { + name: "event, 1 session.added, ok", + ctx: isolatedIAMOwnerCTX, + eventCount: 1, + expectedCalls: 1, + }, + { + name: "event, 5 session.added, ok", + ctx: isolatedIAMOwnerCTX, + eventCount: 5, + expectedCalls: 5, + }, + { + name: "event, 50 session.added, ok", + ctx: isolatedIAMOwnerCTX, + eventCount: 50, + expectedCalls: 50, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // reset the count of the target + resetF() + + for i := 0; i < tt.eventCount; i++ { + _, err := instance.Client.SessionV2.CreateSession(tt.ctx, &session.CreateSessionRequest{}) + require.NoError(t, err) + } + + // wait for called target + retryDuration, tick := integration.WaitForAndTickWithMaxDuration(tt.ctx, time.Minute) + require.EventuallyWithT(t, func(ttt *assert.CollectT) { + assert.True(ttt, calledF() == tt.expectedCalls) + }, retryDuration, tick, "timeout waiting for expected execution result") + }) + } +} + +func TestServer_ExecutionTarget_Event_LongerThanTargetTimeout(t *testing.T) { + instance := integration.NewInstance(CTX) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + + event := "session.added" + // call takes longer than timeout of target + urlRequest, closeF, calledF, resetF := integration.TestServerCall(nil, 5*time.Second, http.StatusOK, nil) + defer closeF() + + targetResponse := waitForTarget(isolatedIAMOwnerCTX, t, instance, urlRequest, domain.TargetTypeWebhook, true) + waitForExecutionOnCondition(isolatedIAMOwnerCTX, t, instance, conditionEvent(event), []string{targetResponse.GetId()}) + + tests := []struct { + name string + ctx context.Context + eventCount int + expectedCalls int + clean func(context.Context) + wantErr bool + }{ + { + name: "event, 1 session.added, error logs", + ctx: isolatedIAMOwnerCTX, + eventCount: 1, + expectedCalls: 1, + }, + { + name: "event, 5 session.added, error logs", + ctx: isolatedIAMOwnerCTX, + eventCount: 5, + expectedCalls: 5, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // reset the count of the target + resetF() + + for i := 0; i < tt.eventCount; i++ { + _, err := instance.Client.SessionV2.CreateSession(tt.ctx, &session.CreateSessionRequest{}) + require.NoError(t, err) + } + + // wait for called target + retryDuration, tick := integration.WaitForAndTickWithMaxDuration(tt.ctx, time.Minute) + require.EventuallyWithT(t, func(ttt *assert.CollectT) { + assert.True(ttt, calledF() == tt.expectedCalls) + }, retryDuration, tick, "timeout waiting for expected execution result") + }) + } +} + +func TestServer_ExecutionTarget_Event_LongerThanTransactionTimeout(t *testing.T) { + instance := integration.NewInstance(CTX) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + + event := "session.added" + urlRequest, closeF, calledF, resetF := integration.TestServerCall(nil, 1*time.Second, http.StatusOK, nil) + defer closeF() + + targetResponse := waitForTarget(isolatedIAMOwnerCTX, t, instance, urlRequest, domain.TargetTypeWebhook, true) + waitForExecutionOnCondition(isolatedIAMOwnerCTX, t, instance, conditionEvent(event), []string{targetResponse.GetId()}) + + tests := []struct { + name string + ctx context.Context + eventCount int + expectedCalls int + clean func(context.Context) + wantErr bool + }{ + { + name: "event, 1 session.added, ok", + ctx: isolatedIAMOwnerCTX, + eventCount: 1, + expectedCalls: 1, + }, + { + name: "event, 5 session.added, ok", + ctx: isolatedIAMOwnerCTX, + eventCount: 5, + expectedCalls: 5, + }, + { + name: "event, 5 session.added, ok", + ctx: isolatedIAMOwnerCTX, + eventCount: 5, + expectedCalls: 5, + }, + { + name: "event, 20 session.added, ok", + ctx: isolatedIAMOwnerCTX, + eventCount: 20, + expectedCalls: 20, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // reset the count of the target + resetF() + + for i := 0; i < tt.eventCount; i++ { + _, err := instance.Client.SessionV2.CreateSession(tt.ctx, &session.CreateSessionRequest{}) + require.NoError(t, err) + } + + // wait for called target + retryDuration, tick := integration.WaitForAndTickWithMaxDuration(tt.ctx, time.Minute) + require.EventuallyWithT(t, func(ttt *assert.CollectT) { + assert.True(ttt, calledF() == tt.expectedCalls) + }, retryDuration, tick, "timeout waiting for expected execution result") + }) + } +} + +func waitForExecutionOnCondition(ctx context.Context, t *testing.T, instance *integration.Instance, condition *action.Condition, targets []string) { + instance.SetExecution(ctx, t, condition, targets) + + retryDuration, tick := integration.WaitForAndTickWithMaxDuration(ctx, time.Minute) + require.EventuallyWithT(t, func(ttt *assert.CollectT) { + got, err := instance.Client.ActionV2.ListExecutions(ctx, &action.ListExecutionsRequest{ + Filters: []*action.ExecutionSearchFilter{ + {Filter: &action.ExecutionSearchFilter_InConditionsFilter{ + InConditionsFilter: &action.InConditionsFilter{Conditions: []*action.Condition{condition}}, + }}, + }, + }) + if !assert.NoError(ttt, err) { + return + } + if !assert.Len(ttt, got.GetExecutions(), 1) { + return + } + gotTargets := got.GetExecutions()[0].GetTargets() + // always first check length, otherwise its failed anyway + if assert.Len(ttt, gotTargets, len(targets)) { + for i := range targets { + assert.EqualExportedValues(ttt, targets[i], gotTargets[i]) + } + } + }, retryDuration, tick, "timeout waiting for expected execution result") +} + +func waitForTarget(ctx context.Context, t *testing.T, instance *integration.Instance, endpoint string, ty domain.TargetType, interrupt bool) *action.CreateTargetResponse { + resp := instance.CreateTarget(ctx, t, "", endpoint, ty, interrupt) + + retryDuration, tick := integration.WaitForAndTickWithMaxDuration(ctx, time.Minute) + require.EventuallyWithT(t, func(ttt *assert.CollectT) { + got, err := instance.Client.ActionV2.ListTargets(ctx, &action.ListTargetsRequest{ + Filters: []*action.TargetSearchFilter{ + {Filter: &action.TargetSearchFilter_InTargetIdsFilter{ + InTargetIdsFilter: &action.InTargetIDsFilter{TargetIds: []string{resp.GetId()}}, + }}, + }, + }) + if !assert.NoError(ttt, err) { + return + } + if !assert.Len(ttt, got.GetTargets(), 1) { + return + } + config := got.GetTargets()[0] + assert.Equal(ttt, config.GetEndpoint(), endpoint) + switch ty { + case domain.TargetTypeWebhook: + if !assert.NotNil(ttt, config.GetRestWebhook()) { + return + } + assert.Equal(ttt, interrupt, config.GetRestWebhook().GetInterruptOnError()) + case domain.TargetTypeAsync: + assert.NotNil(ttt, config.GetRestAsync()) + case domain.TargetTypeCall: + if !assert.NotNil(ttt, config.GetRestCall()) { + return + } + assert.Equal(ttt, interrupt, config.GetRestCall().GetInterruptOnError()) + } + }, retryDuration, tick, "timeout waiting for expected execution result") + return resp +} + +func conditionRequestFullMethod(fullMethod string) *action.Condition { + return &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ + Method: fullMethod, + }, + }, + }, + } +} + +func conditionResponseFullMethod(fullMethod string) *action.Condition { + return &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_Method{ + Method: fullMethod, + }, + }, + }, + } +} + +func conditionEvent(event string) *action.Condition { + return &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_Event{ + Event: event, + }, + }, + }, + } +} + +func conditionFunction(function string) *action.Condition { + return &action.Condition{ + ConditionType: &action.Condition_Function{ + Function: &action.FunctionExecution{ + Name: function, + }, + }, + } +} + +func TestServer_ExecutionTargetPreUserinfo(t *testing.T) { + instance := integration.NewInstance(CTX) + isolatedIAMCtx := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + ctxLoginClient := instance.WithAuthorizationToken(CTX, integration.UserTypeLogin) + + client, err := instance.CreateOIDCImplicitFlowClient(isolatedIAMCtx, t, redirectURIImplicit, loginV2) + require.NoError(t, err) + + type want struct { + addedClaims map[string]any + addedLogClaims map[string][]string + setUserMetadata []*metadata.Metadata + } + tests := []struct { + name string + ctx context.Context + dep func(ctx context.Context, t *testing.T, req *oidc_pb.CreateCallbackRequest) (string, func()) + req *oidc_pb.CreateCallbackRequest + want want + wantErr bool + }{ + { + name: "append claim", + ctx: ctxLoginClient, + dep: func(ctx context.Context, t *testing.T, req *oidc_pb.CreateCallbackRequest) (string, func()) { + response := &oidc_api.ContextInfoResponse{ + AppendClaims: []*oidc_api.AppendClaim{ + {Key: "added", Value: "value"}, + }, + } + return expectPreUserinfoExecution(ctx, t, instance, client.GetClientId(), req, response) + }, + req: &oidc_pb.CreateCallbackRequest{ + AuthRequestId: func() string { + authRequestID, err := instance.CreateOIDCAuthRequestImplicitWithoutLoginClientHeader(isolatedIAMCtx, client.GetClientId(), redirectURIImplicit) + require.NoError(t, err) + return authRequestID + }(), + }, + want: want{ + addedClaims: map[string]any{ + "added": "value", + }, + }, + wantErr: false, + }, + { + name: "append log claim", + ctx: ctxLoginClient, + dep: func(ctx context.Context, t *testing.T, req *oidc_pb.CreateCallbackRequest) (string, func()) { + response := &oidc_api.ContextInfoResponse{ + AppendLogClaims: []string{ + "addedLog", + }, + } + return expectPreUserinfoExecution(ctx, t, instance, client.GetClientId(), req, response) + }, + req: &oidc_pb.CreateCallbackRequest{ + AuthRequestId: func() string { + authRequestID, err := instance.CreateOIDCAuthRequestImplicitWithoutLoginClientHeader(isolatedIAMCtx, client.GetClientId(), redirectURIImplicit) + require.NoError(t, err) + return authRequestID + }(), + }, + want: want{ + addedLogClaims: map[string][]string{ + "urn:zitadel:iam:action:function/preuserinfo:log": {"addedLog"}, + }, + }, + wantErr: false, + }, + { + name: "set user metadata", + ctx: ctxLoginClient, + dep: func(ctx context.Context, t *testing.T, req *oidc_pb.CreateCallbackRequest) (string, func()) { + response := &oidc_api.ContextInfoResponse{ + SetUserMetadata: []*domain.Metadata{ + {Key: "key", Value: []byte("value")}, + }, + } + return expectPreUserinfoExecution(ctx, t, instance, client.GetClientId(), req, response) + }, + req: &oidc_pb.CreateCallbackRequest{ + AuthRequestId: func() string { + authRequestID, err := instance.CreateOIDCAuthRequestImplicitWithoutLoginClientHeader(isolatedIAMCtx, client.GetClientId(), redirectURIImplicit) + require.NoError(t, err) + return authRequestID + }(), + }, + want: want{ + setUserMetadata: []*metadata.Metadata{ + {Key: "key", Value: []byte("value")}, + }, + }, + wantErr: false, + }, + { + name: "full usage", + ctx: ctxLoginClient, + dep: func(ctx context.Context, t *testing.T, req *oidc_pb.CreateCallbackRequest) (string, func()) { + response := &oidc_api.ContextInfoResponse{ + SetUserMetadata: []*domain.Metadata{ + {Key: "key1", Value: []byte("value1")}, + {Key: "key2", Value: []byte("value2")}, + {Key: "key3", Value: []byte("value3")}, + }, + AppendLogClaims: []string{ + "addedLog1", + "addedLog2", + "addedLog3", + }, + AppendClaims: []*oidc_api.AppendClaim{ + {Key: "added1", Value: "value1"}, + {Key: "added2", Value: "value2"}, + {Key: "added3", Value: "value3"}, + }, + } + return expectPreUserinfoExecution(ctx, t, instance, client.GetClientId(), req, response) + }, + req: &oidc_pb.CreateCallbackRequest{ + AuthRequestId: func() string { + authRequestID, err := instance.CreateOIDCAuthRequestImplicitWithoutLoginClientHeader(isolatedIAMCtx, client.GetClientId(), redirectURIImplicit) + require.NoError(t, err) + return authRequestID + }(), + }, + want: want{ + addedClaims: map[string]any{ + "added1": "value1", + "added2": "value2", + "added3": "value3", + }, + setUserMetadata: []*metadata.Metadata{ + {Key: "key1", Value: []byte("value1")}, + {Key: "key2", Value: []byte("value2")}, + {Key: "key3", Value: []byte("value3")}, + }, + addedLogClaims: map[string][]string{ + "urn:zitadel:iam:action:function/preuserinfo:log": {"addedLog1", "addedLog2", "addedLog3"}, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + userID, closeF := tt.dep(isolatedIAMCtx, t, tt.req) + defer closeF() + + got, err := instance.Client.OIDCv2.CreateCallback(tt.ctx, tt.req) + if tt.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + callbackUrl, err := url.Parse(strings.Replace(got.GetCallbackUrl(), "#", "?", 1)) + require.NoError(t, err) + claims := getIDTokenClaimsFromCallbackURL(tt.ctx, t, instance, client.GetClientId(), callbackUrl) + + for k, v := range tt.want.addedClaims { + value, ok := claims[k] + if !assert.True(t, ok) { + return + } + assert.Equal(t, v, value) + } + for k, v := range tt.want.addedLogClaims { + value, ok := claims[k] + if !assert.True(t, ok) { + return + } + assert.ElementsMatch(t, v, value) + } + if len(tt.want.setUserMetadata) > 0 { + checkForSetMetadata(isolatedIAMCtx, t, instance, userID, tt.want.setUserMetadata) + } + }) + } +} + +func expectPreUserinfoExecution(ctx context.Context, t *testing.T, instance *integration.Instance, clientID string, req *oidc_pb.CreateCallbackRequest, response *oidc_api.ContextInfoResponse) (string, func()) { + userEmail := gofakeit.Email() + userPhone := "+41" + gofakeit.Phone() + userResp := instance.CreateHumanUserVerified(ctx, instance.DefaultOrg.Id, userEmail, userPhone) + + sessionResp := createSession(ctx, t, instance, userResp.GetUserId()) + req.CallbackKind = &oidc_pb.CreateCallbackRequest_Session{ + Session: &oidc_pb.Session{ + SessionId: sessionResp.GetSessionId(), + SessionToken: sessionResp.GetSessionToken(), + }, + } + expectedContextInfo := contextInfoForUserOIDC(instance, "function/preuserinfo", clientID, userResp, userEmail, userPhone) + + targetURL, closeF, _, _ := integration.TestServerCall(expectedContextInfo, 0, http.StatusOK, response) + + targetResp := waitForTarget(ctx, t, instance, targetURL, domain.TargetTypeCall, true) + waitForExecutionOnCondition(ctx, t, instance, conditionFunction("preuserinfo"), []string{targetResp.GetId()}) + return userResp.GetUserId(), closeF +} + +func createSession(ctx context.Context, t *testing.T, instance *integration.Instance, userID string) *session.CreateSessionResponse { + sessionResp, err := instance.Client.SessionV2.CreateSession(ctx, &session.CreateSessionRequest{ + Checks: &session.Checks{ + User: &session.CheckUser{ + Search: &session.CheckUser_UserId{ + UserId: userID, + }, + }, + }, + }) + require.NoError(t, err) + return sessionResp +} + +func checkForSetMetadata(ctx context.Context, t *testing.T, instance *integration.Instance, userID string, metadataExpected []*metadata.Metadata) { + integration.WaitForAndTickWithMaxDuration(ctx, time.Minute) + + retryDuration, tick := integration.WaitForAndTickWithMaxDuration(ctx, time.Minute) + assert.EventuallyWithT(t, func(ct *assert.CollectT) { + metadataResp, err := instance.Client.Mgmt.ListUserMetadata(ctx, &management.ListUserMetadataRequest{Id: userID}) + if !assert.NoError(ct, err) { + return + } + for _, dataExpected := range metadataExpected { + found := false + for _, dataCheck := range metadataResp.GetResult() { + if dataExpected.Key == dataCheck.Key { + found = true + if !assert.Equal(ct, dataExpected.Value, dataCheck.Value) { + return + } + } + } + if !assert.True(ct, found) { + return + } + } + }, retryDuration, tick) +} + +func getIDTokenClaimsFromCallbackURL(ctx context.Context, t *testing.T, instance *integration.Instance, clientID string, callbackURL *url.URL) map[string]any { + accessToken := callbackURL.Query().Get("access_token") + idToken := callbackURL.Query().Get("id_token") + + provider, err := instance.CreateRelyingParty(ctx, clientID, redirectURIImplicit, oidc.ScopeOpenID, oidc.ScopeProfile, oidc.ScopeEmail, oidc.ScopePhone) + require.NoError(t, err) + claims, err := rp.VerifyTokens[*oidc.IDTokenClaims](context.Background(), accessToken, idToken, provider.IDTokenVerifier()) + require.NoError(t, err) + return claims.Claims +} + +type CustomAccessTokenClaims struct { + oidc.TokenClaims + Added1 string `json:"added1,omitempty"` + Added2 string `json:"added2,omitempty"` + Added3 string `json:"added3,omitempty"` + Log []string `json:"urn:zitadel:iam:action:function/preaccesstoken:log,omitempty"` +} + +func getAccessTokenClaims(ctx context.Context, t *testing.T, instance *integration.Instance, callbackURL *url.URL) *CustomAccessTokenClaims { + accessToken := callbackURL.Query().Get("access_token") + + verifier := op.NewAccessTokenVerifier(instance.OIDCIssuer(), rp.NewRemoteKeySet(http.DefaultClient, instance.OIDCIssuer()+"/oauth/v2/keys")) + + claims, err := op.VerifyAccessToken[*CustomAccessTokenClaims](ctx, accessToken, verifier) + require.NoError(t, err) + return claims +} + +func contextInfoForUserOIDC(instance *integration.Instance, function string, clientID string, userResp *user.AddHumanUserResponse, email, phone string) *oidc_api.ContextInfo { + return &oidc_api.ContextInfo{ + Function: function, + UserInfo: &oidc.UserInfo{ + Subject: userResp.GetUserId(), + }, + User: &query.User{ + ID: userResp.GetUserId(), + CreationDate: userResp.Details.ChangeDate.AsTime(), + ChangeDate: userResp.Details.ChangeDate.AsTime(), + ResourceOwner: instance.DefaultOrg.GetId(), + Sequence: userResp.Details.Sequence, + State: 1, + Username: email, + PreferredLoginName: email, + Human: &query.Human{ + FirstName: "Mickey", + LastName: "Mouse", + NickName: "Mickey", + DisplayName: "Mickey Mouse", + AvatarKey: "", + PreferredLanguage: language.Dutch, + Gender: 2, + Email: domain.EmailAddress(email), + IsEmailVerified: true, + Phone: domain.PhoneNumber(phone), + IsPhoneVerified: true, + PasswordChangeRequired: false, + PasswordChanged: time.Time{}, + MFAInitSkipped: time.Time{}, + }, + }, + UserMetadata: nil, + Application: &oidc_api.ContextInfoApplication{ + ClientID: clientID, + }, + Org: &query.UserInfoOrg{ + ID: instance.DefaultOrg.GetId(), + Name: instance.DefaultOrg.GetName(), + PrimaryDomain: instance.DefaultOrg.GetPrimaryDomain(), + }, + UserGrants: nil, + Response: nil, + } +} + +func TestServer_ExecutionTargetPreAccessToken(t *testing.T) { + instance := integration.NewInstance(CTX) + isolatedIAMCtx := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + ctxLoginClient := instance.WithAuthorizationToken(CTX, integration.UserTypeLogin) + + client, err := instance.CreateOIDCImplicitFlowClient(isolatedIAMCtx, t, redirectURIImplicit, loginV2) + require.NoError(t, err) + + type want struct { + addedClaims *CustomAccessTokenClaims + addedLogClaims map[string][]string + setUserMetadata []*metadata.Metadata + } + tests := []struct { + name string + ctx context.Context + dep func(ctx context.Context, t *testing.T, req *oidc_pb.CreateCallbackRequest) (string, func()) + req *oidc_pb.CreateCallbackRequest + want want + wantErr bool + }{ + { + name: "append claim", + ctx: ctxLoginClient, + dep: func(ctx context.Context, t *testing.T, req *oidc_pb.CreateCallbackRequest) (string, func()) { + response := &oidc_api.ContextInfoResponse{ + AppendClaims: []*oidc_api.AppendClaim{ + {Key: "added1", Value: "value"}, + }, + } + return expectPreAccessTokenExecution(ctx, t, instance, client.GetClientId(), req, response) + }, + req: &oidc_pb.CreateCallbackRequest{ + AuthRequestId: func() string { + authRequestID, err := instance.CreateOIDCAuthRequestImplicitWithoutLoginClientHeader(isolatedIAMCtx, client.GetClientId(), redirectURIImplicit) + require.NoError(t, err) + return authRequestID + }(), + }, + want: want{ + addedClaims: &CustomAccessTokenClaims{ + Added1: "value", + }, + }, + wantErr: false, + }, + { + name: "append log claim", + ctx: ctxLoginClient, + dep: func(ctx context.Context, t *testing.T, req *oidc_pb.CreateCallbackRequest) (string, func()) { + response := &oidc_api.ContextInfoResponse{ + AppendLogClaims: []string{ + "addedLog", + }, + } + return expectPreAccessTokenExecution(ctx, t, instance, client.GetClientId(), req, response) + }, + req: &oidc_pb.CreateCallbackRequest{ + AuthRequestId: func() string { + authRequestID, err := instance.CreateOIDCAuthRequestImplicitWithoutLoginClientHeader(isolatedIAMCtx, client.GetClientId(), redirectURIImplicit) + require.NoError(t, err) + return authRequestID + }(), + }, + want: want{ + addedClaims: &CustomAccessTokenClaims{ + Log: []string{"addedLog"}, + }, + }, + wantErr: false, + }, + { + name: "set user metadata", + ctx: ctxLoginClient, + dep: func(ctx context.Context, t *testing.T, req *oidc_pb.CreateCallbackRequest) (string, func()) { + response := &oidc_api.ContextInfoResponse{ + SetUserMetadata: []*domain.Metadata{ + {Key: "key", Value: []byte("value")}, + }, + } + return expectPreAccessTokenExecution(ctx, t, instance, client.GetClientId(), req, response) + }, + req: &oidc_pb.CreateCallbackRequest{ + AuthRequestId: func() string { + authRequestID, err := instance.CreateOIDCAuthRequestImplicitWithoutLoginClientHeader(isolatedIAMCtx, client.GetClientId(), redirectURIImplicit) + require.NoError(t, err) + return authRequestID + }(), + }, + want: want{ + setUserMetadata: []*metadata.Metadata{ + {Key: "key", Value: []byte("value")}, + }, + }, + wantErr: false, + }, + { + name: "full usage", + ctx: ctxLoginClient, + dep: func(ctx context.Context, t *testing.T, req *oidc_pb.CreateCallbackRequest) (string, func()) { + response := &oidc_api.ContextInfoResponse{ + SetUserMetadata: []*domain.Metadata{ + {Key: "key1", Value: []byte("value1")}, + {Key: "key2", Value: []byte("value2")}, + {Key: "key3", Value: []byte("value3")}, + }, + AppendLogClaims: []string{ + "addedLog1", + "addedLog2", + "addedLog3", + }, + AppendClaims: []*oidc_api.AppendClaim{ + {Key: "added1", Value: "value1"}, + {Key: "added2", Value: "value2"}, + {Key: "added3", Value: "value3"}, + }, + } + return expectPreAccessTokenExecution(ctx, t, instance, client.GetClientId(), req, response) + }, + req: &oidc_pb.CreateCallbackRequest{ + AuthRequestId: func() string { + authRequestID, err := instance.CreateOIDCAuthRequestImplicitWithoutLoginClientHeader(isolatedIAMCtx, client.GetClientId(), redirectURIImplicit) + require.NoError(t, err) + return authRequestID + }(), + }, + want: want{ + addedClaims: &CustomAccessTokenClaims{ + Added1: "value1", + Added2: "value2", + Added3: "value3", + Log: []string{"addedLog1", "addedLog2", "addedLog3"}, + }, + setUserMetadata: []*metadata.Metadata{ + {Key: "key1", Value: []byte("value1")}, + {Key: "key2", Value: []byte("value2")}, + {Key: "key3", Value: []byte("value3")}, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + userID, closeF := tt.dep(isolatedIAMCtx, t, tt.req) + defer closeF() + + got, err := instance.Client.OIDCv2.CreateCallback(tt.ctx, tt.req) + if tt.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + + callbackUrl, err := url.Parse(strings.Replace(got.GetCallbackUrl(), "#", "?", 1)) + require.NoError(t, err) + claims := getAccessTokenClaims(tt.ctx, t, instance, callbackUrl) + + if tt.want.addedClaims != nil { + assert.Equal(t, tt.want.addedClaims.Added1, claims.Added1) + assert.Equal(t, tt.want.addedClaims.Added2, claims.Added2) + assert.Equal(t, tt.want.addedClaims.Added3, claims.Added3) + assert.Equal(t, tt.want.addedClaims.Log, claims.Log) + } + if len(tt.want.setUserMetadata) > 0 { + checkForSetMetadata(isolatedIAMCtx, t, instance, userID, tt.want.setUserMetadata) + } + + }) + } +} + +func expectPreAccessTokenExecution(ctx context.Context, t *testing.T, instance *integration.Instance, clientID string, req *oidc_pb.CreateCallbackRequest, response *oidc_api.ContextInfoResponse) (string, func()) { + userEmail := gofakeit.Email() + userPhone := "+41" + gofakeit.Phone() + userResp := instance.CreateHumanUserVerified(ctx, instance.DefaultOrg.Id, userEmail, userPhone) + + sessionResp := createSession(ctx, t, instance, userResp.GetUserId()) + req.CallbackKind = &oidc_pb.CreateCallbackRequest_Session{ + Session: &oidc_pb.Session{ + SessionId: sessionResp.GetSessionId(), + SessionToken: sessionResp.GetSessionToken(), + }, + } + expectedContextInfo := contextInfoForUserOIDC(instance, "function/preaccesstoken", clientID, userResp, userEmail, userPhone) + + targetURL, closeF, _, _ := integration.TestServerCall(expectedContextInfo, 0, http.StatusOK, response) + + targetResp := waitForTarget(ctx, t, instance, targetURL, domain.TargetTypeCall, true) + waitForExecutionOnCondition(ctx, t, instance, conditionFunction("preaccesstoken"), []string{targetResp.GetId()}) + return userResp.GetUserId(), closeF +} + +func TestServer_ExecutionTargetPreSAMLResponse(t *testing.T) { + instance := integration.NewInstance(CTX) + isolatedIAMCtx := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + ctxLoginClient := instance.WithAuthorizationToken(CTX, integration.UserTypeLogin) + + idpMetadata, err := instance.GetSAMLIDPMetadata() + require.NoError(t, err) + + acsPost := idpMetadata.IDPSSODescriptors[0].SingleSignOnServices[1] + _, _, spMiddlewarePost := createSAMLApplication(isolatedIAMCtx, t, instance, idpMetadata, saml.HTTPPostBinding, false, false) + + type want struct { + addedAttributes map[string][]saml.AttributeValue + setUserMetadata []*metadata.Metadata + } + tests := []struct { + name string + ctx context.Context + dep func(ctx context.Context, t *testing.T, req *saml_pb.CreateResponseRequest) (string, func()) + req *saml_pb.CreateResponseRequest + want want + wantErr bool + }{ + { + name: "append attribute", + ctx: ctxLoginClient, + dep: func(ctx context.Context, t *testing.T, req *saml_pb.CreateResponseRequest) (string, func()) { + response := &saml_api.ContextInfoResponse{ + AppendAttribute: []*saml_api.AppendAttribute{ + {Name: "added", NameFormat: "format", Value: []string{"value"}}, + }, + } + return expectPreSAMLResponseExecution(ctx, t, instance, req, response) + }, + req: &saml_pb.CreateResponseRequest{ + SamlRequestId: func() string { + _, samlRequestID, err := instance.CreateSAMLAuthRequest(spMiddlewarePost, instance.Users[integration.UserTypeOrgOwner].ID, acsPost, gofakeit.BitcoinAddress(), saml.HTTPPostBinding) + require.NoError(t, err) + return samlRequestID + }(), + }, + want: want{ + addedAttributes: map[string][]saml.AttributeValue{ + "added": {saml.AttributeValue{Value: "value"}}, + }, + }, + wantErr: false, + }, + { + name: "set user metadata", + ctx: ctxLoginClient, + dep: func(ctx context.Context, t *testing.T, req *saml_pb.CreateResponseRequest) (string, func()) { + response := &saml_api.ContextInfoResponse{ + SetUserMetadata: []*domain.Metadata{ + {Key: "key", Value: []byte("value")}, + }, + } + return expectPreSAMLResponseExecution(ctx, t, instance, req, response) + }, + req: &saml_pb.CreateResponseRequest{ + SamlRequestId: func() string { + _, samlRequestID, err := instance.CreateSAMLAuthRequest(spMiddlewarePost, instance.Users[integration.UserTypeOrgOwner].ID, acsPost, gofakeit.BitcoinAddress(), saml.HTTPPostBinding) + require.NoError(t, err) + return samlRequestID + }(), + }, + want: want{ + setUserMetadata: []*metadata.Metadata{ + {Key: "key", Value: []byte("value")}, + }, + }, + wantErr: false, + }, + { + name: "set user metadata", + ctx: ctxLoginClient, + dep: func(ctx context.Context, t *testing.T, req *saml_pb.CreateResponseRequest) (string, func()) { + response := &saml_api.ContextInfoResponse{ + AppendAttribute: []*saml_api.AppendAttribute{ + {Name: "added1", NameFormat: "format", Value: []string{"value1"}}, + {Name: "added2", NameFormat: "format", Value: []string{"value2"}}, + {Name: "added3", NameFormat: "format", Value: []string{"value3"}}, + }, + SetUserMetadata: []*domain.Metadata{ + {Key: "key1", Value: []byte("value1")}, + {Key: "key2", Value: []byte("value2")}, + {Key: "key3", Value: []byte("value3")}, + }, + } + return expectPreSAMLResponseExecution(ctx, t, instance, req, response) + }, + req: &saml_pb.CreateResponseRequest{ + SamlRequestId: func() string { + _, samlRequestID, err := instance.CreateSAMLAuthRequest(spMiddlewarePost, instance.Users[integration.UserTypeOrgOwner].ID, acsPost, gofakeit.BitcoinAddress(), saml.HTTPPostBinding) + require.NoError(t, err) + return samlRequestID + }(), + }, + want: want{ + addedAttributes: map[string][]saml.AttributeValue{ + "added1": {saml.AttributeValue{Value: "value1"}}, + "added2": {saml.AttributeValue{Value: "value2"}}, + "added3": {saml.AttributeValue{Value: "value3"}}, + }, + setUserMetadata: []*metadata.Metadata{ + {Key: "key1", Value: []byte("value1")}, + {Key: "key2", Value: []byte("value2")}, + {Key: "key3", Value: []byte("value3")}, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + userID, closeF := tt.dep(isolatedIAMCtx, t, tt.req) + defer closeF() + + got, err := instance.Client.SAMLv2.CreateResponse(tt.ctx, tt.req) + if tt.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + attributes := getSAMLResponseAttributes(t, got.GetPost().GetSamlResponse(), spMiddlewarePost) + for k, v := range tt.want.addedAttributes { + found := false + for _, attribute := range attributes { + if attribute.Name == k { + found = true + assert.Equal(t, v, attribute.Values) + } + } + if !assert.True(t, found) { + return + } + } + if len(tt.want.setUserMetadata) > 0 { + checkForSetMetadata(isolatedIAMCtx, t, instance, userID, tt.want.setUserMetadata) + } + }) + } +} + +func expectPreSAMLResponseExecution(ctx context.Context, t *testing.T, instance *integration.Instance, req *saml_pb.CreateResponseRequest, response *saml_api.ContextInfoResponse) (string, func()) { + userEmail := gofakeit.Email() + userPhone := "+41" + gofakeit.Phone() + userResp := instance.CreateHumanUserVerified(ctx, instance.DefaultOrg.Id, userEmail, userPhone) + + sessionResp := createSession(ctx, t, instance, userResp.GetUserId()) + req.ResponseKind = &saml_pb.CreateResponseRequest_Session{ + Session: &saml_pb.Session{ + SessionId: sessionResp.GetSessionId(), + SessionToken: sessionResp.GetSessionToken(), + }, + } + expectedContextInfo := contextInfoForUserSAML(instance, "function/presamlresponse", userResp, userEmail, userPhone) + + targetURL, closeF, _, _ := integration.TestServerCall(expectedContextInfo, 0, http.StatusOK, response) + + targetResp := waitForTarget(ctx, t, instance, targetURL, domain.TargetTypeCall, true) + waitForExecutionOnCondition(ctx, t, instance, conditionFunction("presamlresponse"), []string{targetResp.GetId()}) + + return userResp.GetUserId(), closeF +} + +func createSAMLSP(t *testing.T, idpMetadata *saml.EntityDescriptor, binding string) (string, *samlsp.Middleware) { + rootURL := "example." + gofakeit.DomainName() + spMiddleware, err := integration.CreateSAMLSP("https://"+rootURL, idpMetadata, binding) + require.NoError(t, err) + return rootURL, spMiddleware +} + +func createSAMLApplication(ctx context.Context, t *testing.T, instance *integration.Instance, idpMetadata *saml.EntityDescriptor, binding string, projectRoleCheck, hasProjectCheck bool) (string, string, *samlsp.Middleware) { + project := instance.CreateProject(ctx, t, instance.DefaultOrg.GetId(), gofakeit.AppName(), projectRoleCheck, hasProjectCheck) + rootURL, sp := createSAMLSP(t, idpMetadata, binding) + _, err := instance.CreateSAMLClient(ctx, project.GetId(), sp) + require.NoError(t, err) + return project.GetId(), rootURL, sp +} + +func getSAMLResponseAttributes(t *testing.T, samlResponse string, sp *samlsp.Middleware) []saml.Attribute { + data, err := base64.StdEncoding.DecodeString(samlResponse) + require.NoError(t, err) + sp.ServiceProvider.AllowIDPInitiated = true + assertion, err := sp.ServiceProvider.ParseXMLResponse(data, []string{}) + require.NoError(t, err) + return assertion.AttributeStatements[0].Attributes +} + +func contextInfoForUserSAML(instance *integration.Instance, function string, userResp *user.AddHumanUserResponse, email, phone string) *saml_api.ContextInfo { + return &saml_api.ContextInfo{ + Function: function, + User: &query.User{ + ID: userResp.GetUserId(), + CreationDate: userResp.Details.ChangeDate.AsTime(), + ChangeDate: userResp.Details.ChangeDate.AsTime(), + ResourceOwner: instance.DefaultOrg.GetId(), + Sequence: userResp.Details.Sequence, + State: 1, + Type: domain.UserTypeHuman, + Username: email, + PreferredLoginName: email, + LoginNames: []string{email}, + Human: &query.Human{ + FirstName: "Mickey", + LastName: "Mouse", + NickName: "Mickey", + DisplayName: "Mickey Mouse", + AvatarKey: "", + PreferredLanguage: language.Dutch, + Gender: 2, + Email: domain.EmailAddress(email), + IsEmailVerified: true, + Phone: domain.PhoneNumber(phone), + IsPhoneVerified: true, + PasswordChangeRequired: false, + PasswordChanged: time.Time{}, + MFAInitSkipped: time.Time{}, + }, + }, + UserGrants: nil, + Response: nil, + } +} diff --git a/internal/api/grpc/action/v2/integration_test/execution_test.go b/internal/api/grpc/action/v2/integration_test/execution_test.go new file mode 100644 index 0000000000..da31fe5a0b --- /dev/null +++ b/internal/api/grpc/action/v2/integration_test/execution_test.go @@ -0,0 +1,565 @@ +//go:build integration + +package action_test + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/zitadel/zitadel/internal/domain" + "github.com/zitadel/zitadel/internal/integration" + "github.com/zitadel/zitadel/pkg/grpc/action/v2" +) + +func TestServer_SetExecution_Request(t *testing.T) { + instance := integration.NewInstance(CTX) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://notexisting", domain.TargetTypeWebhook, false) + + tests := []struct { + name string + ctx context.Context + req *action.SetExecutionRequest + wantSetDate bool + wantErr bool + }{ + { + name: "missing permission", + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_All{All: true}, + }, + }, + }, + }, + wantErr: true, + }, + { + name: "no condition, error", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{}, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantErr: true, + }, + { + name: "method, not existing", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ + Method: "/zitadel.session.v2.NotExistingService/List", + }, + }, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantErr: true, + }, + { + name: "method, ok", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ + Method: "/zitadel.session.v2.SessionService/ListSessions", + }, + }, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantSetDate: true, + }, + { + name: "service, not existing", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Service{ + Service: "NotExistingService", + }, + }, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantErr: true, + }, + { + name: "service, ok", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Service{ + Service: "zitadel.session.v2.SessionService", + }, + }, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantSetDate: true, + }, + { + name: "all, ok", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_All{ + All: true, + }, + }, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantSetDate: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // We want to have the same response no matter how often we call the function + creationDate := time.Now().UTC() + got, err := instance.Client.ActionV2.SetExecution(tt.ctx, tt.req) + setDate := time.Now().UTC() + if tt.wantErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + + assertSetExecutionResponse(t, creationDate, setDate, tt.wantSetDate, got) + + // cleanup to not impact other requests + instance.DeleteExecution(tt.ctx, t, tt.req.GetCondition()) + }) + } +} + +func assertSetExecutionResponse(t *testing.T, creationDate, setDate time.Time, expectedSetDate bool, actualResp *action.SetExecutionResponse) { + if expectedSetDate { + if !setDate.IsZero() { + assert.WithinRange(t, actualResp.GetSetDate().AsTime(), creationDate, setDate) + } else { + assert.WithinRange(t, actualResp.GetSetDate().AsTime(), creationDate, time.Now().UTC()) + } + } else { + assert.Nil(t, actualResp.SetDate) + } +} + +func TestServer_SetExecution_Response(t *testing.T) { + instance := integration.NewInstance(CTX) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://notexisting", domain.TargetTypeWebhook, false) + + tests := []struct { + name string + ctx context.Context + req *action.SetExecutionRequest + wantSetDate bool + wantErr bool + }{ + { + name: "missing permission", + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_All{All: true}, + }, + }, + }, + }, + wantErr: true, + }, + { + name: "no condition, error", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{}, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantErr: true, + }, + { + name: "method, not existing", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_Method{ + Method: "/zitadel.session.v2.NotExistingService/List", + }, + }, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantErr: true, + }, + { + name: "method, ok", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_Method{ + Method: "/zitadel.session.v2.SessionService/ListSessions", + }, + }, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantSetDate: true, + }, + { + name: "service, not existing", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_Service{ + Service: "NotExistingService", + }, + }, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantErr: true, + }, + { + name: "service, ok", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_Service{ + Service: "zitadel.session.v2.SessionService", + }, + }, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantSetDate: true, + }, + { + name: "all, ok", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_All{ + All: true, + }, + }, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantSetDate: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + creationDate := time.Now().UTC() + got, err := instance.Client.ActionV2.SetExecution(tt.ctx, tt.req) + setDate := time.Now().UTC() + if tt.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + + assertSetExecutionResponse(t, creationDate, setDate, tt.wantSetDate, got) + + // cleanup to not impact other requests + instance.DeleteExecution(tt.ctx, t, tt.req.GetCondition()) + }) + } +} + +func TestServer_SetExecution_Event(t *testing.T) { + instance := integration.NewInstance(CTX) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://notexisting", domain.TargetTypeWebhook, false) + + tests := []struct { + name string + ctx context.Context + req *action.SetExecutionRequest + wantSetDate bool + wantErr bool + }{ + { + name: "missing permission", + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_All{ + All: true, + }, + }, + }, + }, + }, + wantErr: true, + }, + { + name: "no condition, error", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{}, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantErr: true, + }, + { + name: "event, not existing", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_Event{ + Event: "user.human.notexisting", + }, + }, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantErr: true, + }, + { + name: "event, ok", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_Event{ + Event: "user.human.added", + }, + }, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantSetDate: true, + }, + { + name: "group, not existing", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_Group{ + Group: "user.notexisting", + }, + }, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantErr: true, + }, + { + name: "group, level 1, ok", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_Group{ + Group: "user", + }, + }, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantSetDate: true, + }, + { + name: "group, level 2, ok", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_Group{ + Group: "user.human", + }, + }, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantSetDate: true, + }, + { + name: "all, ok", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_All{ + All: true, + }, + }, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantSetDate: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + creationDate := time.Now().UTC() + got, err := instance.Client.ActionV2.SetExecution(tt.ctx, tt.req) + setDate := time.Now().UTC() + if tt.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + + assertSetExecutionResponse(t, creationDate, setDate, tt.wantSetDate, got) + + // cleanup to not impact other requests + instance.DeleteExecution(tt.ctx, t, tt.req.GetCondition()) + }) + } +} + +func TestServer_SetExecution_Function(t *testing.T) { + instance := integration.NewInstance(CTX) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://notexisting", domain.TargetTypeWebhook, false) + + tests := []struct { + name string + ctx context.Context + req *action.SetExecutionRequest + wantSetDate bool + wantErr bool + }{ + { + name: "missing permission", + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_All{All: true}, + }, + }, + }, + }, + wantErr: true, + }, + { + name: "no condition, error", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{}, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantErr: true, + }, + { + name: "function, not existing", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Function{ + Function: &action.FunctionExecution{Name: "xxx"}, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantErr: true, + }, + { + name: "function, ok", + ctx: isolatedIAMOwnerCTX, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Function{ + Function: &action.FunctionExecution{Name: "presamlresponse"}, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + wantSetDate: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + creationDate := time.Now().UTC() + got, err := instance.Client.ActionV2.SetExecution(tt.ctx, tt.req) + setDate := time.Now().UTC() + if tt.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + + assertSetExecutionResponse(t, creationDate, setDate, tt.wantSetDate, got) + + // cleanup to not impact other requests + instance.DeleteExecution(tt.ctx, t, tt.req.GetCondition()) + }) + } +} diff --git a/internal/api/grpc/action/v2/integration_test/query_test.go b/internal/api/grpc/action/v2/integration_test/query_test.go new file mode 100644 index 0000000000..2a93a4ad4b --- /dev/null +++ b/internal/api/grpc/action/v2/integration_test/query_test.go @@ -0,0 +1,784 @@ +//go:build integration + +package action_test + +import ( + "context" + "testing" + "time" + + "github.com/brianvoe/gofakeit/v6" + "github.com/muhlemmer/gu" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/types/known/durationpb" + + "github.com/zitadel/zitadel/internal/domain" + "github.com/zitadel/zitadel/internal/integration" + "github.com/zitadel/zitadel/pkg/grpc/action/v2" + "github.com/zitadel/zitadel/pkg/grpc/filter/v2" +) + +func TestServer_GetTarget(t *testing.T) { + instance := integration.NewInstance(CTX) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + type args struct { + ctx context.Context + dep func(context.Context, *action.GetTargetRequest, *action.GetTargetResponse) error + req *action.GetTargetRequest + } + tests := []struct { + name string + args args + want *action.GetTargetResponse + wantErr bool + }{ + { + name: "missing permission", + args: args{ + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), + req: &action.GetTargetRequest{}, + }, + wantErr: true, + }, + { + name: "not found", + args: args{ + ctx: isolatedIAMOwnerCTX, + req: &action.GetTargetRequest{Id: "notexisting"}, + }, + wantErr: true, + }, + { + name: "get, ok", + args: args{ + ctx: isolatedIAMOwnerCTX, + dep: func(ctx context.Context, request *action.GetTargetRequest, response *action.GetTargetResponse) error { + name := gofakeit.Name() + resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeWebhook, false) + request.Id = resp.GetId() + response.Target.Id = resp.GetId() + response.Target.Name = name + response.Target.CreationDate = resp.GetCreationDate() + response.Target.ChangeDate = resp.GetCreationDate() + response.Target.SigningKey = resp.GetSigningKey() + return nil + }, + req: &action.GetTargetRequest{}, + }, + want: &action.GetTargetResponse{ + Target: &action.Target{ + Endpoint: "https://example.com", + TargetType: &action.Target_RestWebhook{ + RestWebhook: &action.RESTWebhook{}, + }, + Timeout: durationpb.New(5 * time.Second), + }, + }, + }, + { + name: "get, async, ok", + args: args{ + ctx: isolatedIAMOwnerCTX, + dep: func(ctx context.Context, request *action.GetTargetRequest, response *action.GetTargetResponse) error { + name := gofakeit.Name() + resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeAsync, false) + request.Id = resp.GetId() + response.Target.Id = resp.GetId() + response.Target.Name = name + response.Target.CreationDate = resp.GetCreationDate() + response.Target.ChangeDate = resp.GetCreationDate() + response.Target.SigningKey = resp.GetSigningKey() + return nil + }, + req: &action.GetTargetRequest{}, + }, + want: &action.GetTargetResponse{ + Target: &action.Target{ + Endpoint: "https://example.com", + TargetType: &action.Target_RestAsync{ + RestAsync: &action.RESTAsync{}, + }, + Timeout: durationpb.New(5 * time.Second), + }, + }, + }, + { + name: "get, webhook interruptOnError, ok", + args: args{ + ctx: isolatedIAMOwnerCTX, + dep: func(ctx context.Context, request *action.GetTargetRequest, response *action.GetTargetResponse) error { + name := gofakeit.Name() + resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeWebhook, true) + request.Id = resp.GetId() + response.Target.Id = resp.GetId() + response.Target.Name = name + response.Target.CreationDate = resp.GetCreationDate() + response.Target.ChangeDate = resp.GetCreationDate() + response.Target.SigningKey = resp.GetSigningKey() + return nil + }, + req: &action.GetTargetRequest{}, + }, + want: &action.GetTargetResponse{ + Target: &action.Target{ + Endpoint: "https://example.com", + TargetType: &action.Target_RestWebhook{ + RestWebhook: &action.RESTWebhook{ + InterruptOnError: true, + }, + }, + Timeout: durationpb.New(5 * time.Second), + }, + }, + }, + { + name: "get, call, ok", + args: args{ + ctx: isolatedIAMOwnerCTX, + dep: func(ctx context.Context, request *action.GetTargetRequest, response *action.GetTargetResponse) error { + name := gofakeit.Name() + resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeCall, false) + request.Id = resp.GetId() + response.Target.Id = resp.GetId() + response.Target.Name = name + response.Target.CreationDate = resp.GetCreationDate() + response.Target.ChangeDate = resp.GetCreationDate() + response.Target.SigningKey = resp.GetSigningKey() + return nil + }, + req: &action.GetTargetRequest{}, + }, + want: &action.GetTargetResponse{ + Target: &action.Target{ + Endpoint: "https://example.com", + TargetType: &action.Target_RestCall{ + RestCall: &action.RESTCall{ + InterruptOnError: false, + }, + }, + Timeout: durationpb.New(5 * time.Second), + }, + }, + }, + { + name: "get, call interruptOnError, ok", + args: args{ + ctx: isolatedIAMOwnerCTX, + dep: func(ctx context.Context, request *action.GetTargetRequest, response *action.GetTargetResponse) error { + name := gofakeit.Name() + resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeCall, true) + request.Id = resp.GetId() + response.Target.Id = resp.GetId() + response.Target.Name = name + response.Target.CreationDate = resp.GetCreationDate() + response.Target.ChangeDate = resp.GetCreationDate() + response.Target.SigningKey = resp.GetSigningKey() + return nil + }, + req: &action.GetTargetRequest{}, + }, + want: &action.GetTargetResponse{ + Target: &action.Target{ + Endpoint: "https://example.com", + TargetType: &action.Target_RestCall{ + RestCall: &action.RESTCall{ + InterruptOnError: true, + }, + }, + Timeout: durationpb.New(5 * time.Second), + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.args.dep != nil { + err := tt.args.dep(tt.args.ctx, tt.args.req, tt.want) + require.NoError(t, err) + } + retryDuration, tick := integration.WaitForAndTickWithMaxDuration(isolatedIAMOwnerCTX, 2*time.Minute) + require.EventuallyWithT(t, func(ttt *assert.CollectT) { + got, err := instance.Client.ActionV2.GetTarget(tt.args.ctx, tt.args.req) + if tt.wantErr { + assert.Error(ttt, err, "Error: "+err.Error()) + return + } + assert.NoError(ttt, err) + assert.EqualExportedValues(ttt, tt.want, got) + }, retryDuration, tick, "timeout waiting for expected target Executions") + }) + } +} + +func TestServer_ListTargets(t *testing.T) { + instance := integration.NewInstance(CTX) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + type args struct { + ctx context.Context + dep func(context.Context, *action.ListTargetsRequest, *action.ListTargetsResponse) + req *action.ListTargetsRequest + } + tests := []struct { + name string + args args + want *action.ListTargetsResponse + wantErr bool + }{ + { + name: "missing permission", + args: args{ + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), + req: &action.ListTargetsRequest{}, + }, + wantErr: true, + }, + { + name: "list, not found", + args: args{ + ctx: isolatedIAMOwnerCTX, + req: &action.ListTargetsRequest{ + Filters: []*action.TargetSearchFilter{ + {Filter: &action.TargetSearchFilter_InTargetIdsFilter{ + InTargetIdsFilter: &action.InTargetIDsFilter{ + TargetIds: []string{"notfound"}, + }, + }, + }, + }, + }, + }, + want: &action.ListTargetsResponse{ + Pagination: &filter.PaginationResponse{ + TotalResult: 0, + AppliedLimit: 100, + }, + Targets: []*action.Target{}, + }, + }, + { + name: "list single id", + args: args{ + ctx: isolatedIAMOwnerCTX, + dep: func(ctx context.Context, request *action.ListTargetsRequest, response *action.ListTargetsResponse) { + name := gofakeit.Name() + resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeWebhook, false) + request.Filters[0].Filter = &action.TargetSearchFilter_InTargetIdsFilter{ + InTargetIdsFilter: &action.InTargetIDsFilter{ + TargetIds: []string{resp.GetId()}, + }, + } + + response.Targets[0].Id = resp.GetId() + response.Targets[0].Name = name + response.Targets[0].CreationDate = resp.GetCreationDate() + response.Targets[0].ChangeDate = resp.GetCreationDate() + response.Targets[0].SigningKey = resp.GetSigningKey() + }, + req: &action.ListTargetsRequest{ + Filters: []*action.TargetSearchFilter{{}}, + }, + }, + want: &action.ListTargetsResponse{ + Pagination: &filter.PaginationResponse{ + TotalResult: 1, + AppliedLimit: 100, + }, + Targets: []*action.Target{ + { + Endpoint: "https://example.com", + TargetType: &action.Target_RestWebhook{ + RestWebhook: &action.RESTWebhook{ + InterruptOnError: false, + }, + }, + Timeout: durationpb.New(5 * time.Second), + }, + }, + }, + }, { + name: "list single name", + args: args{ + ctx: isolatedIAMOwnerCTX, + dep: func(ctx context.Context, request *action.ListTargetsRequest, response *action.ListTargetsResponse) { + name := gofakeit.Name() + resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeWebhook, false) + request.Filters[0].Filter = &action.TargetSearchFilter_TargetNameFilter{ + TargetNameFilter: &action.TargetNameFilter{ + TargetName: name, + }, + } + + response.Targets[0].Id = resp.GetId() + response.Targets[0].Name = name + response.Targets[0].CreationDate = resp.GetCreationDate() + response.Targets[0].ChangeDate = resp.GetCreationDate() + response.Targets[0].SigningKey = resp.GetSigningKey() + }, + req: &action.ListTargetsRequest{ + Filters: []*action.TargetSearchFilter{{}}, + }, + }, + want: &action.ListTargetsResponse{ + Pagination: &filter.PaginationResponse{ + TotalResult: 1, + AppliedLimit: 100, + }, + Targets: []*action.Target{ + { + Endpoint: "https://example.com", + TargetType: &action.Target_RestWebhook{ + RestWebhook: &action.RESTWebhook{ + InterruptOnError: false, + }, + }, + Timeout: durationpb.New(5 * time.Second), + }, + }, + }, + }, + { + name: "list multiple id", + args: args{ + ctx: isolatedIAMOwnerCTX, + dep: func(ctx context.Context, request *action.ListTargetsRequest, response *action.ListTargetsResponse) { + name1 := gofakeit.Name() + name2 := gofakeit.Name() + name3 := gofakeit.Name() + resp1 := instance.CreateTarget(ctx, t, name1, "https://example.com", domain.TargetTypeWebhook, false) + resp2 := instance.CreateTarget(ctx, t, name2, "https://example.com", domain.TargetTypeCall, true) + resp3 := instance.CreateTarget(ctx, t, name3, "https://example.com", domain.TargetTypeAsync, false) + request.Filters[0].Filter = &action.TargetSearchFilter_InTargetIdsFilter{ + InTargetIdsFilter: &action.InTargetIDsFilter{ + TargetIds: []string{resp1.GetId(), resp2.GetId(), resp3.GetId()}, + }, + } + + response.Targets[2].Id = resp1.GetId() + response.Targets[2].Name = name1 + response.Targets[2].CreationDate = resp1.GetCreationDate() + response.Targets[2].ChangeDate = resp1.GetCreationDate() + response.Targets[2].SigningKey = resp1.GetSigningKey() + + response.Targets[1].Id = resp2.GetId() + response.Targets[1].Name = name2 + response.Targets[1].CreationDate = resp2.GetCreationDate() + response.Targets[1].ChangeDate = resp2.GetCreationDate() + response.Targets[1].SigningKey = resp2.GetSigningKey() + + response.Targets[0].Id = resp3.GetId() + response.Targets[0].Name = name3 + response.Targets[0].CreationDate = resp3.GetCreationDate() + response.Targets[0].ChangeDate = resp3.GetCreationDate() + response.Targets[0].SigningKey = resp3.GetSigningKey() + }, + req: &action.ListTargetsRequest{ + Filters: []*action.TargetSearchFilter{{}}, + }, + }, + want: &action.ListTargetsResponse{ + Pagination: &filter.PaginationResponse{ + TotalResult: 3, + AppliedLimit: 100, + }, + Targets: []*action.Target{ + { + Endpoint: "https://example.com", + TargetType: &action.Target_RestAsync{ + RestAsync: &action.RESTAsync{}, + }, + Timeout: durationpb.New(5 * time.Second), + }, + { + Endpoint: "https://example.com", + TargetType: &action.Target_RestCall{ + RestCall: &action.RESTCall{ + InterruptOnError: true, + }, + }, + Timeout: durationpb.New(5 * time.Second), + }, + { + Endpoint: "https://example.com", + TargetType: &action.Target_RestWebhook{ + RestWebhook: &action.RESTWebhook{ + InterruptOnError: false, + }, + }, + Timeout: durationpb.New(5 * time.Second), + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.args.dep != nil { + tt.args.dep(tt.args.ctx, tt.args.req, tt.want) + } + + retryDuration, tick := integration.WaitForAndTickWithMaxDuration(isolatedIAMOwnerCTX, time.Minute) + require.EventuallyWithT(t, func(ttt *assert.CollectT) { + got, listErr := instance.Client.ActionV2.ListTargets(tt.args.ctx, tt.args.req) + if tt.wantErr { + require.Error(ttt, listErr, "Error: "+listErr.Error()) + return + } + require.NoError(ttt, listErr) + + // always first check length, otherwise its failed anyway + if assert.Len(ttt, got.Targets, len(tt.want.Targets)) { + for i := range tt.want.Targets { + assert.EqualExportedValues(ttt, tt.want.Targets[i], got.Targets[i]) + } + } + assertPaginationResponse(ttt, tt.want.Pagination, got.Pagination) + }, retryDuration, tick, "timeout waiting for expected execution Executions") + }) + } +} + +func assertPaginationResponse(t *assert.CollectT, expected *filter.PaginationResponse, actual *filter.PaginationResponse) { + assert.Equal(t, expected.AppliedLimit, actual.AppliedLimit) + assert.Equal(t, expected.TotalResult, actual.TotalResult) +} + +func TestServer_ListExecutions(t *testing.T) { + instance := integration.NewInstance(CTX) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false) + + type args struct { + ctx context.Context + dep func(context.Context, *action.ListExecutionsRequest, *action.ListExecutionsResponse) + req *action.ListExecutionsRequest + } + tests := []struct { + name string + args args + want *action.ListExecutionsResponse + wantErr bool + }{ + { + name: "missing permission", + args: args{ + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), + req: &action.ListExecutionsRequest{}, + }, + wantErr: true, + }, + { + name: "list request single condition", + args: args{ + ctx: isolatedIAMOwnerCTX, + dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) { + cond := request.Filters[0].GetInConditionsFilter().GetConditions()[0] + resp := instance.SetExecution(ctx, t, cond, []string{targetResp.GetId()}) + + // Set expected response with used values for SetExecution + response.Executions[0].CreationDate = resp.GetSetDate() + response.Executions[0].ChangeDate = resp.GetSetDate() + response.Executions[0].Condition = cond + }, + req: &action.ListExecutionsRequest{ + Filters: []*action.ExecutionSearchFilter{{ + Filter: &action.ExecutionSearchFilter_InConditionsFilter{ + InConditionsFilter: &action.InConditionsFilter{ + Conditions: []*action.Condition{{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ + Method: "/zitadel.session.v2.SessionService/GetSession", + }, + }, + }, + }}, + }, + }, + }}, + }, + }, + want: &action.ListExecutionsResponse{ + Pagination: &filter.PaginationResponse{ + TotalResult: 1, + AppliedLimit: 100, + }, + Executions: []*action.Execution{ + { + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ + Method: "/zitadel.session.v2.SessionService/GetSession", + }, + }, + }, + }, + Targets: []string{targetResp.GetId()}, + }, + }, + }, + }, + { + name: "list request single target", + args: args{ + ctx: isolatedIAMOwnerCTX, + dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) { + target := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false) + // add target as Filter to the request + request.Filters[0] = &action.ExecutionSearchFilter{ + Filter: &action.ExecutionSearchFilter_TargetFilter{ + TargetFilter: &action.TargetFilter{ + TargetId: target.GetId(), + }, + }, + } + cond := &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ + Method: "/zitadel.management.v1.ManagementService/UpdateAction", + }, + }, + }, + } + resp := instance.SetExecution(ctx, t, cond, []string{target.GetId()}) + + response.Executions[0].CreationDate = resp.GetSetDate() + response.Executions[0].ChangeDate = resp.GetSetDate() + response.Executions[0].Condition = cond + response.Executions[0].Targets = []string{target.GetId()} + }, + req: &action.ListExecutionsRequest{ + Filters: []*action.ExecutionSearchFilter{{}}, + }, + }, + want: &action.ListExecutionsResponse{ + Pagination: &filter.PaginationResponse{ + TotalResult: 1, + AppliedLimit: 100, + }, + Executions: []*action.Execution{ + { + Condition: &action.Condition{}, + Targets: []string{""}, + }, + }, + }, + }, + { + name: "list multiple conditions", + args: args{ + ctx: isolatedIAMOwnerCTX, + dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) { + + request.Filters[0] = &action.ExecutionSearchFilter{ + Filter: &action.ExecutionSearchFilter_InConditionsFilter{ + InConditionsFilter: &action.InConditionsFilter{ + Conditions: []*action.Condition{ + {ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ + Method: "/zitadel.session.v2.SessionService/GetSession", + }, + }, + }}, + {ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ + Method: "/zitadel.session.v2.SessionService/CreateSession", + }, + }, + }}, + {ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ + Method: "/zitadel.session.v2.SessionService/SetSession", + }, + }, + }}, + }, + }, + }, + } + + cond1 := request.Filters[0].GetInConditionsFilter().GetConditions()[0] + resp1 := instance.SetExecution(ctx, t, cond1, []string{targetResp.GetId()}) + response.Executions[2] = &action.Execution{ + CreationDate: resp1.GetSetDate(), + ChangeDate: resp1.GetSetDate(), + Condition: cond1, + Targets: []string{targetResp.GetId()}, + } + + cond2 := request.Filters[0].GetInConditionsFilter().GetConditions()[1] + resp2 := instance.SetExecution(ctx, t, cond2, []string{targetResp.GetId()}) + response.Executions[1] = &action.Execution{ + CreationDate: resp2.GetSetDate(), + ChangeDate: resp2.GetSetDate(), + Condition: cond2, + Targets: []string{targetResp.GetId()}, + } + + cond3 := request.Filters[0].GetInConditionsFilter().GetConditions()[2] + resp3 := instance.SetExecution(ctx, t, cond3, []string{targetResp.GetId()}) + response.Executions[0] = &action.Execution{ + CreationDate: resp3.GetSetDate(), + ChangeDate: resp3.GetSetDate(), + Condition: cond3, + Targets: []string{targetResp.GetId()}, + } + }, + req: &action.ListExecutionsRequest{ + Filters: []*action.ExecutionSearchFilter{ + {}, + }, + }, + }, + want: &action.ListExecutionsResponse{ + Pagination: &filter.PaginationResponse{ + TotalResult: 3, + AppliedLimit: 100, + }, + Executions: []*action.Execution{ + {}, {}, {}, + }, + }, + }, + { + name: "list multiple conditions all types", + args: args{ + ctx: isolatedIAMOwnerCTX, + dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) { + conditions := request.Filters[0].GetInConditionsFilter().GetConditions() + for i, cond := range conditions { + resp := instance.SetExecution(ctx, t, cond, []string{targetResp.GetId()}) + response.Executions[(len(conditions)-1)-i] = &action.Execution{ + CreationDate: resp.GetSetDate(), + ChangeDate: resp.GetSetDate(), + Condition: cond, + Targets: []string{targetResp.GetId()}, + } + } + }, + req: &action.ListExecutionsRequest{ + Filters: []*action.ExecutionSearchFilter{{ + Filter: &action.ExecutionSearchFilter_InConditionsFilter{ + InConditionsFilter: &action.InConditionsFilter{ + Conditions: []*action.Condition{ + {ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_Method{Method: "/zitadel.session.v2.SessionService/GetSession"}}}}, + {ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_Service{Service: "zitadel.session.v2.SessionService"}}}}, + {ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_All{All: true}}}}, + {ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_Method{Method: "/zitadel.session.v2.SessionService/GetSession"}}}}, + {ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_Service{Service: "zitadel.session.v2.SessionService"}}}}, + {ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_All{All: true}}}}, + {ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_Event{Event: "user.added"}}}}, + {ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_Group{Group: "user"}}}}, + {ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_All{All: true}}}}, + {ConditionType: &action.Condition_Function{Function: &action.FunctionExecution{Name: "presamlresponse"}}}, + }, + }, + }, + }}, + }, + }, + want: &action.ListExecutionsResponse{ + Pagination: &filter.PaginationResponse{ + TotalResult: 10, + AppliedLimit: 100, + }, + Executions: []*action.Execution{ + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + }, + }, + }, + { + name: "list multiple conditions all types, sort id", + args: args{ + ctx: isolatedIAMOwnerCTX, + dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) { + conditions := request.Filters[0].GetInConditionsFilter().GetConditions() + for i, cond := range conditions { + resp := instance.SetExecution(ctx, t, cond, []string{targetResp.GetId()}) + response.Executions[i] = &action.Execution{ + CreationDate: resp.GetSetDate(), + ChangeDate: resp.GetSetDate(), + Condition: cond, + Targets: []string{targetResp.GetId()}, + } + } + }, + req: &action.ListExecutionsRequest{ + SortingColumn: gu.Ptr(action.ExecutionFieldName_EXECUTION_FIELD_NAME_ID), + Filters: []*action.ExecutionSearchFilter{{ + Filter: &action.ExecutionSearchFilter_InConditionsFilter{ + InConditionsFilter: &action.InConditionsFilter{ + Conditions: []*action.Condition{ + {ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_Method{Method: "/zitadel.session.v2.SessionService/GetSession"}}}}, + {ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_Service{Service: "zitadel.session.v2.SessionService"}}}}, + {ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_All{All: true}}}}, + {ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_Method{Method: "/zitadel.session.v2.SessionService/GetSession"}}}}, + {ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_Service{Service: "zitadel.session.v2.SessionService"}}}}, + {ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_All{All: true}}}}, + {ConditionType: &action.Condition_Function{Function: &action.FunctionExecution{Name: "presamlresponse"}}}, + {ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_Event{Event: "user.added"}}}}, + {ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_Group{Group: "user"}}}}, + {ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_All{All: true}}}}, + }, + }, + }, + }}, + }, + }, + want: &action.ListExecutionsResponse{ + Pagination: &filter.PaginationResponse{ + TotalResult: 10, + AppliedLimit: 100, + }, + Executions: []*action.Execution{ + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.args.dep != nil { + tt.args.dep(tt.args.ctx, tt.args.req, tt.want) + } + + retryDuration, tick := integration.WaitForAndTickWithMaxDuration(isolatedIAMOwnerCTX, time.Minute) + require.EventuallyWithT(t, func(ttt *assert.CollectT) { + got, listErr := instance.Client.ActionV2.ListExecutions(tt.args.ctx, tt.args.req) + if tt.wantErr { + require.Error(ttt, listErr, "Error: "+listErr.Error()) + return + } + require.NoError(ttt, listErr) + // always first check length, otherwise its failed anyway + if assert.Len(ttt, got.Executions, len(tt.want.Executions)) { + assert.EqualExportedValues(ttt, got.Executions, tt.want.Executions) + } + assertPaginationResponse(ttt, tt.want.Pagination, got.Pagination) + }, retryDuration, tick, "timeout waiting for expected execution Executions") + }) + } +} diff --git a/internal/api/grpc/action/v2/integration_test/server_test.go b/internal/api/grpc/action/v2/integration_test/server_test.go new file mode 100644 index 0000000000..07ee051c63 --- /dev/null +++ b/internal/api/grpc/action/v2/integration_test/server_test.go @@ -0,0 +1,23 @@ +//go:build integration + +package action_test + +import ( + "context" + "os" + "testing" + "time" +) + +var ( + CTX context.Context +) + +func TestMain(m *testing.M) { + os.Exit(func() int { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute) + defer cancel() + CTX = ctx + return m.Run() + }()) +} diff --git a/internal/api/grpc/action/v2/integration_test/target_test.go b/internal/api/grpc/action/v2/integration_test/target_test.go new file mode 100644 index 0000000000..5908a9d56e --- /dev/null +++ b/internal/api/grpc/action/v2/integration_test/target_test.go @@ -0,0 +1,549 @@ +//go:build integration + +package action_test + +import ( + "context" + "testing" + "time" + + "github.com/brianvoe/gofakeit/v6" + "github.com/muhlemmer/gu" + "github.com/stretchr/testify/assert" + "google.golang.org/protobuf/types/known/durationpb" + + "github.com/zitadel/zitadel/internal/domain" + "github.com/zitadel/zitadel/internal/integration" + "github.com/zitadel/zitadel/pkg/grpc/action/v2" +) + +func TestServer_CreateTarget(t *testing.T) { + instance := integration.NewInstance(CTX) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + type want struct { + id bool + creationDate bool + signingKey bool + } + alreadyExistingTargetName := gofakeit.AppName() + instance.CreateTarget(isolatedIAMOwnerCTX, t, alreadyExistingTargetName, "https://example.com", domain.TargetTypeAsync, false) + tests := []struct { + name string + ctx context.Context + req *action.CreateTargetRequest + want + wantErr bool + }{ + { + name: "missing permission", + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), + req: &action.CreateTargetRequest{ + Name: gofakeit.Name(), + }, + wantErr: true, + }, + { + name: "empty name", + ctx: isolatedIAMOwnerCTX, + req: &action.CreateTargetRequest{ + Name: "", + }, + wantErr: true, + }, + { + name: "empty type", + ctx: isolatedIAMOwnerCTX, + req: &action.CreateTargetRequest{ + Name: gofakeit.Name(), + TargetType: nil, + }, + wantErr: true, + }, + { + name: "empty webhook url", + ctx: isolatedIAMOwnerCTX, + req: &action.CreateTargetRequest{ + Name: gofakeit.Name(), + TargetType: &action.CreateTargetRequest_RestWebhook{ + RestWebhook: &action.RESTWebhook{}, + }, + }, + wantErr: true, + }, + { + name: "empty request response url", + ctx: isolatedIAMOwnerCTX, + req: &action.CreateTargetRequest{ + Name: gofakeit.Name(), + TargetType: &action.CreateTargetRequest_RestCall{ + RestCall: &action.RESTCall{}, + }, + }, + wantErr: true, + }, + { + name: "empty timeout", + ctx: isolatedIAMOwnerCTX, + req: &action.CreateTargetRequest{ + Name: gofakeit.Name(), + Endpoint: "https://example.com", + TargetType: &action.CreateTargetRequest_RestWebhook{ + RestWebhook: &action.RESTWebhook{}, + }, + Timeout: nil, + }, + wantErr: true, + }, + { + name: "async, already existing, ok", + ctx: isolatedIAMOwnerCTX, + req: &action.CreateTargetRequest{ + Name: alreadyExistingTargetName, + Endpoint: "https://example.com", + TargetType: &action.CreateTargetRequest_RestAsync{ + RestAsync: &action.RESTAsync{}, + }, + Timeout: durationpb.New(10 * time.Second), + }, + wantErr: true, + }, + { + name: "async, ok", + ctx: isolatedIAMOwnerCTX, + req: &action.CreateTargetRequest{ + Name: gofakeit.Name(), + Endpoint: "https://example.com", + TargetType: &action.CreateTargetRequest_RestAsync{ + RestAsync: &action.RESTAsync{}, + }, + Timeout: durationpb.New(10 * time.Second), + }, + want: want{ + id: true, + creationDate: true, + signingKey: true, + }, + }, + { + name: "webhook, ok", + ctx: isolatedIAMOwnerCTX, + req: &action.CreateTargetRequest{ + Name: gofakeit.Name(), + Endpoint: "https://example.com", + TargetType: &action.CreateTargetRequest_RestWebhook{ + RestWebhook: &action.RESTWebhook{ + InterruptOnError: false, + }, + }, + Timeout: durationpb.New(10 * time.Second), + }, + want: want{ + id: true, + creationDate: true, + signingKey: true, + }, + }, + { + name: "webhook, interrupt on error, ok", + ctx: isolatedIAMOwnerCTX, + req: &action.CreateTargetRequest{ + Name: gofakeit.Name(), + Endpoint: "https://example.com", + TargetType: &action.CreateTargetRequest_RestWebhook{ + RestWebhook: &action.RESTWebhook{ + InterruptOnError: true, + }, + }, + Timeout: durationpb.New(10 * time.Second), + }, + want: want{ + id: true, + creationDate: true, + signingKey: true, + }, + }, + { + name: "call, ok", + ctx: isolatedIAMOwnerCTX, + req: &action.CreateTargetRequest{ + Name: gofakeit.Name(), + Endpoint: "https://example.com", + TargetType: &action.CreateTargetRequest_RestCall{ + RestCall: &action.RESTCall{ + InterruptOnError: false, + }, + }, + Timeout: durationpb.New(10 * time.Second), + }, + want: want{ + id: true, + creationDate: true, + signingKey: true, + }, + }, + + { + name: "call, interruptOnError, ok", + ctx: isolatedIAMOwnerCTX, + req: &action.CreateTargetRequest{ + Name: gofakeit.Name(), + Endpoint: "https://example.com", + TargetType: &action.CreateTargetRequest_RestCall{ + RestCall: &action.RESTCall{ + InterruptOnError: true, + }, + }, + Timeout: durationpb.New(10 * time.Second), + }, + want: want{ + id: true, + creationDate: true, + signingKey: true, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + creationDate := time.Now().UTC() + got, err := instance.Client.ActionV2.CreateTarget(tt.ctx, tt.req) + changeDate := time.Now().UTC() + if tt.wantErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + assertCreateTargetResponse(t, creationDate, changeDate, tt.want.creationDate, tt.want.id, tt.want.signingKey, got) + }) + } +} + +func assertCreateTargetResponse(t *testing.T, creationDate, changeDate time.Time, expectedCreationDate, expectedID, expectedSigningKey bool, actualResp *action.CreateTargetResponse) { + if expectedCreationDate { + if !changeDate.IsZero() { + assert.WithinRange(t, actualResp.GetCreationDate().AsTime(), creationDate, changeDate) + } else { + assert.WithinRange(t, actualResp.GetCreationDate().AsTime(), creationDate, time.Now().UTC()) + } + } else { + assert.Nil(t, actualResp.CreationDate) + } + + if expectedID { + assert.NotEmpty(t, actualResp.GetId()) + } else { + assert.Nil(t, actualResp.Id) + } + + if expectedSigningKey { + assert.NotEmpty(t, actualResp.GetSigningKey()) + } else { + assert.Nil(t, actualResp.SigningKey) + } +} + +func TestServer_UpdateTarget(t *testing.T) { + instance := integration.NewInstance(CTX) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + type args struct { + ctx context.Context + req *action.UpdateTargetRequest + } + type want struct { + change bool + changeDate bool + signingKey bool + } + tests := []struct { + name string + prepare func(request *action.UpdateTargetRequest) + args args + want want + wantErr bool + }{ + { + name: "missing permission", + prepare: func(request *action.UpdateTargetRequest) { + targetID := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false).GetId() + request.Id = targetID + }, + args: args{ + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), + req: &action.UpdateTargetRequest{ + Name: gu.Ptr(gofakeit.Name()), + }, + }, + wantErr: true, + }, + { + name: "not existing", + prepare: func(request *action.UpdateTargetRequest) { + request.Id = "notexisting" + }, + args: args{ + ctx: isolatedIAMOwnerCTX, + req: &action.UpdateTargetRequest{ + Name: gu.Ptr(gofakeit.Name()), + }, + }, + wantErr: true, + }, + { + name: "no change, ok", + prepare: func(request *action.UpdateTargetRequest) { + targetID := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false).GetId() + request.Id = targetID + }, + args: args{ + ctx: isolatedIAMOwnerCTX, + req: &action.UpdateTargetRequest{ + Endpoint: gu.Ptr("https://example.com"), + }, + }, + want: want{ + change: false, + changeDate: true, + signingKey: false, + }, + }, + { + name: "change name, ok", + prepare: func(request *action.UpdateTargetRequest) { + targetID := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false).GetId() + request.Id = targetID + }, + args: args{ + ctx: isolatedIAMOwnerCTX, + req: &action.UpdateTargetRequest{ + Name: gu.Ptr(gofakeit.Name()), + }, + }, + want: want{ + change: true, + changeDate: true, + signingKey: false, + }, + }, + { + name: "regenerate signingkey, ok", + prepare: func(request *action.UpdateTargetRequest) { + targetID := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false).GetId() + request.Id = targetID + }, + args: args{ + ctx: isolatedIAMOwnerCTX, + req: &action.UpdateTargetRequest{ + ExpirationSigningKey: durationpb.New(0 * time.Second), + }, + }, + want: want{ + change: true, + changeDate: true, + signingKey: true, + }, + }, + { + name: "change type, ok", + prepare: func(request *action.UpdateTargetRequest) { + targetID := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false).GetId() + request.Id = targetID + }, + args: args{ + ctx: isolatedIAMOwnerCTX, + req: &action.UpdateTargetRequest{ + TargetType: &action.UpdateTargetRequest_RestCall{ + RestCall: &action.RESTCall{ + InterruptOnError: true, + }, + }, + }, + }, + want: want{ + change: true, + changeDate: true, + signingKey: false, + }, + }, + { + name: "change url, ok", + prepare: func(request *action.UpdateTargetRequest) { + targetID := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false).GetId() + request.Id = targetID + }, + args: args{ + ctx: isolatedIAMOwnerCTX, + req: &action.UpdateTargetRequest{ + Endpoint: gu.Ptr("https://example.com/hooks/new"), + }, + }, + want: want{ + change: true, + changeDate: true, + signingKey: false, + }, + }, + { + name: "change timeout, ok", + prepare: func(request *action.UpdateTargetRequest) { + targetID := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false).GetId() + request.Id = targetID + }, + args: args{ + ctx: isolatedIAMOwnerCTX, + req: &action.UpdateTargetRequest{ + Timeout: durationpb.New(20 * time.Second), + }, + }, + want: want{ + change: true, + changeDate: true, + signingKey: false, + }, + }, + { + name: "change type async, ok", + prepare: func(request *action.UpdateTargetRequest) { + targetID := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeAsync, false).GetId() + request.Id = targetID + }, + args: args{ + ctx: isolatedIAMOwnerCTX, + req: &action.UpdateTargetRequest{ + TargetType: &action.UpdateTargetRequest_RestAsync{ + RestAsync: &action.RESTAsync{}, + }, + }, + }, + want: want{ + change: true, + changeDate: true, + signingKey: false, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + creationDate := time.Now().UTC() + tt.prepare(tt.args.req) + + got, err := instance.Client.ActionV2.UpdateTarget(tt.args.ctx, tt.args.req) + if tt.wantErr { + assert.Error(t, err) + return + } + changeDate := time.Time{} + if tt.want.change { + changeDate = time.Now().UTC() + } + assert.NoError(t, err) + assertUpdateTargetResponse(t, creationDate, changeDate, tt.want.changeDate, tt.want.signingKey, got) + }) + } +} + +func assertUpdateTargetResponse(t *testing.T, creationDate, changeDate time.Time, expectedChangeDate, expectedSigningKey bool, actualResp *action.UpdateTargetResponse) { + if expectedChangeDate { + if !changeDate.IsZero() { + assert.WithinRange(t, actualResp.GetChangeDate().AsTime(), creationDate, changeDate) + } else { + assert.WithinRange(t, actualResp.GetChangeDate().AsTime(), creationDate, time.Now().UTC()) + } + } else { + assert.Nil(t, actualResp.ChangeDate) + } + + if expectedSigningKey { + assert.NotEmpty(t, actualResp.GetSigningKey()) + } else { + assert.Nil(t, actualResp.SigningKey) + } +} + +func TestServer_DeleteTarget(t *testing.T) { + instance := integration.NewInstance(CTX) + iamOwnerCtx := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + tests := []struct { + name string + ctx context.Context + prepare func(request *action.DeleteTargetRequest) (time.Time, time.Time) + req *action.DeleteTargetRequest + wantDeletionDate bool + wantErr bool + }{ + { + name: "missing permission", + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), + req: &action.DeleteTargetRequest{ + Id: "notexisting", + }, + wantErr: true, + }, + { + name: "empty id", + ctx: iamOwnerCtx, + req: &action.DeleteTargetRequest{ + Id: "", + }, + wantErr: true, + }, + { + name: "delete target, not existing", + ctx: iamOwnerCtx, + req: &action.DeleteTargetRequest{ + Id: "notexisting", + }, + wantDeletionDate: false, + }, + { + name: "delete target", + ctx: iamOwnerCtx, + prepare: func(request *action.DeleteTargetRequest) (time.Time, time.Time) { + creationDate := time.Now().UTC() + targetID := instance.CreateTarget(iamOwnerCtx, t, "", "https://example.com", domain.TargetTypeWebhook, false).GetId() + request.Id = targetID + return creationDate, time.Time{} + }, + req: &action.DeleteTargetRequest{}, + wantDeletionDate: true, + }, + { + name: "delete target, already removed", + ctx: iamOwnerCtx, + prepare: func(request *action.DeleteTargetRequest) (time.Time, time.Time) { + creationDate := time.Now().UTC() + targetID := instance.CreateTarget(iamOwnerCtx, t, "", "https://example.com", domain.TargetTypeWebhook, false).GetId() + request.Id = targetID + instance.DeleteTarget(iamOwnerCtx, t, targetID) + return creationDate, time.Now().UTC() + }, + req: &action.DeleteTargetRequest{}, + wantDeletionDate: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var creationDate, deletionDate time.Time + if tt.prepare != nil { + creationDate, deletionDate = tt.prepare(tt.req) + } + got, err := instance.Client.ActionV2.DeleteTarget(tt.ctx, tt.req) + if tt.wantErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + assertDeleteTargetResponse(t, creationDate, deletionDate, tt.wantDeletionDate, got) + }) + } +} + +func assertDeleteTargetResponse(t *testing.T, creationDate, deletionDate time.Time, expectedDeletionDate bool, actualResp *action.DeleteTargetResponse) { + if expectedDeletionDate { + if !deletionDate.IsZero() { + assert.WithinRange(t, actualResp.GetDeletionDate().AsTime(), creationDate, deletionDate) + } else { + assert.WithinRange(t, actualResp.GetDeletionDate().AsTime(), creationDate, time.Now().UTC()) + } + } else { + assert.Nil(t, actualResp.DeletionDate) + } +} diff --git a/internal/api/grpc/action/v2/query.go b/internal/api/grpc/action/v2/query.go new file mode 100644 index 0000000000..c900d29d75 --- /dev/null +++ b/internal/api/grpc/action/v2/query.go @@ -0,0 +1,404 @@ +package action + +import ( + "context" + "strings" + + "connectrpc.com/connect" + "google.golang.org/protobuf/types/known/durationpb" + "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/zitadel/zitadel/internal/api/grpc/filter/v2" + "github.com/zitadel/zitadel/internal/command" + "github.com/zitadel/zitadel/internal/domain" + "github.com/zitadel/zitadel/internal/query" + "github.com/zitadel/zitadel/internal/zerrors" + "github.com/zitadel/zitadel/pkg/grpc/action/v2" +) + +const ( + conditionIDAllSegmentCount = 0 + conditionIDRequestResponseServiceSegmentCount = 1 + conditionIDRequestResponseMethodSegmentCount = 2 + conditionIDEventGroupSegmentCount = 1 +) + +func (s *Server) GetTarget(ctx context.Context, req *connect.Request[action.GetTargetRequest]) (*connect.Response[action.GetTargetResponse], error) { + resp, err := s.query.GetTargetByID(ctx, req.Msg.GetId()) + if err != nil { + return nil, err + } + return connect.NewResponse(&action.GetTargetResponse{ + Target: targetToPb(resp), + }), nil +} + +type InstanceContext interface { + GetInstanceId() string + GetInstanceDomain() string +} + +type Context interface { + GetOwner() InstanceContext +} + +func (s *Server) ListTargets(ctx context.Context, req *connect.Request[action.ListTargetsRequest]) (*connect.Response[action.ListTargetsResponse], error) { + queries, err := s.ListTargetsRequestToModel(req.Msg) + if err != nil { + return nil, err + } + resp, err := s.query.SearchTargets(ctx, queries) + if err != nil { + return nil, err + } + return connect.NewResponse(&action.ListTargetsResponse{ + Targets: targetsToPb(resp.Targets), + Pagination: filter.QueryToPaginationPb(queries.SearchRequest, resp.SearchResponse), + }), nil +} + +func (s *Server) ListExecutions(ctx context.Context, req *connect.Request[action.ListExecutionsRequest]) (*connect.Response[action.ListExecutionsResponse], error) { + queries, err := s.ListExecutionsRequestToModel(req.Msg) + if err != nil { + return nil, err + } + resp, err := s.query.SearchExecutions(ctx, queries) + if err != nil { + return nil, err + } + return connect.NewResponse(&action.ListExecutionsResponse{ + Executions: executionsToPb(resp.Executions), + Pagination: filter.QueryToPaginationPb(queries.SearchRequest, resp.SearchResponse), + }), nil +} + +func targetsToPb(targets []*query.Target) []*action.Target { + t := make([]*action.Target, len(targets)) + for i, target := range targets { + t[i] = targetToPb(target) + } + return t +} + +func targetToPb(t *query.Target) *action.Target { + target := &action.Target{ + Id: t.ID, + Name: t.Name, + Timeout: durationpb.New(t.Timeout), + Endpoint: t.Endpoint, + SigningKey: t.SigningKey, + } + switch t.TargetType { + case domain.TargetTypeWebhook: + target.TargetType = &action.Target_RestWebhook{RestWebhook: &action.RESTWebhook{InterruptOnError: t.InterruptOnError}} + case domain.TargetTypeCall: + target.TargetType = &action.Target_RestCall{RestCall: &action.RESTCall{InterruptOnError: t.InterruptOnError}} + case domain.TargetTypeAsync: + target.TargetType = &action.Target_RestAsync{RestAsync: &action.RESTAsync{}} + default: + target.TargetType = nil + } + + if !t.EventDate.IsZero() { + target.ChangeDate = timestamppb.New(t.EventDate) + } + if !t.CreationDate.IsZero() { + target.CreationDate = timestamppb.New(t.CreationDate) + } + return target +} + +func (s *Server) ListTargetsRequestToModel(req *action.ListTargetsRequest) (*query.TargetSearchQueries, error) { + offset, limit, asc, err := filter.PaginationPbToQuery(s.systemDefaults, req.Pagination) + if err != nil { + return nil, err + } + queries, err := targetQueriesToQuery(req.Filters) + if err != nil { + return nil, err + } + return &query.TargetSearchQueries{ + SearchRequest: query.SearchRequest{ + Offset: offset, + Limit: limit, + Asc: asc, + SortingColumn: targetFieldNameToSortingColumn(req.SortingColumn), + }, + Queries: queries, + }, nil +} + +func targetQueriesToQuery(queries []*action.TargetSearchFilter) (_ []query.SearchQuery, err error) { + q := make([]query.SearchQuery, len(queries)) + for i, qry := range queries { + q[i], err = targetQueryToQuery(qry) + if err != nil { + return nil, err + } + } + return q, nil +} + +func targetQueryToQuery(filter *action.TargetSearchFilter) (query.SearchQuery, error) { + switch q := filter.Filter.(type) { + case *action.TargetSearchFilter_TargetNameFilter: + return targetNameQueryToQuery(q.TargetNameFilter) + case *action.TargetSearchFilter_InTargetIdsFilter: + return targetInTargetIdsQueryToQuery(q.InTargetIdsFilter) + default: + return nil, zerrors.ThrowInvalidArgument(nil, "GRPC-vR9nC", "List.Query.Invalid") + } +} + +func targetNameQueryToQuery(q *action.TargetNameFilter) (query.SearchQuery, error) { + return query.NewTargetNameSearchQuery(filter.TextMethodPbToQuery(q.Method), q.GetTargetName()) +} + +func targetInTargetIdsQueryToQuery(q *action.InTargetIDsFilter) (query.SearchQuery, error) { + return query.NewTargetInIDsSearchQuery(q.GetTargetIds()) +} + +// targetFieldNameToSortingColumn defaults to the creation date because this ensures deterministic pagination +func targetFieldNameToSortingColumn(field *action.TargetFieldName) query.Column { + if field == nil { + return query.TargetColumnCreationDate + } + switch *field { + case action.TargetFieldName_TARGET_FIELD_NAME_UNSPECIFIED: + return query.TargetColumnCreationDate + case action.TargetFieldName_TARGET_FIELD_NAME_ID: + return query.TargetColumnID + case action.TargetFieldName_TARGET_FIELD_NAME_CREATED_DATE: + return query.TargetColumnCreationDate + case action.TargetFieldName_TARGET_FIELD_NAME_CHANGED_DATE: + return query.TargetColumnChangeDate + case action.TargetFieldName_TARGET_FIELD_NAME_NAME: + return query.TargetColumnName + case action.TargetFieldName_TARGET_FIELD_NAME_TARGET_TYPE: + return query.TargetColumnTargetType + case action.TargetFieldName_TARGET_FIELD_NAME_URL: + return query.TargetColumnURL + case action.TargetFieldName_TARGET_FIELD_NAME_TIMEOUT: + return query.TargetColumnTimeout + case action.TargetFieldName_TARGET_FIELD_NAME_INTERRUPT_ON_ERROR: + return query.TargetColumnInterruptOnError + default: + return query.TargetColumnCreationDate + } +} + +// executionFieldNameToSortingColumn defaults to the creation date because this ensures deterministic pagination +func executionFieldNameToSortingColumn(field *action.ExecutionFieldName) query.Column { + if field == nil { + return query.ExecutionColumnCreationDate + } + switch *field { + case action.ExecutionFieldName_EXECUTION_FIELD_NAME_UNSPECIFIED: + return query.ExecutionColumnCreationDate + case action.ExecutionFieldName_EXECUTION_FIELD_NAME_ID: + return query.ExecutionColumnID + case action.ExecutionFieldName_EXECUTION_FIELD_NAME_CREATED_DATE: + return query.ExecutionColumnCreationDate + case action.ExecutionFieldName_EXECUTION_FIELD_NAME_CHANGED_DATE: + return query.ExecutionColumnChangeDate + default: + return query.ExecutionColumnCreationDate + } +} + +func (s *Server) ListExecutionsRequestToModel(req *action.ListExecutionsRequest) (*query.ExecutionSearchQueries, error) { + offset, limit, asc, err := filter.PaginationPbToQuery(s.systemDefaults, req.Pagination) + if err != nil { + return nil, err + } + queries, err := executionQueriesToQuery(req.Filters) + if err != nil { + return nil, err + } + return &query.ExecutionSearchQueries{ + SearchRequest: query.SearchRequest{ + Offset: offset, + Limit: limit, + Asc: asc, + SortingColumn: executionFieldNameToSortingColumn(req.SortingColumn), + }, + Queries: queries, + }, nil +} + +func executionQueriesToQuery(queries []*action.ExecutionSearchFilter) (_ []query.SearchQuery, err error) { + q := make([]query.SearchQuery, len(queries)) + for i, query := range queries { + q[i], err = executionQueryToQuery(query) + if err != nil { + return nil, err + } + } + return q, nil +} + +func executionQueryToQuery(searchQuery *action.ExecutionSearchFilter) (query.SearchQuery, error) { + switch q := searchQuery.Filter.(type) { + case *action.ExecutionSearchFilter_InConditionsFilter: + return inConditionsQueryToQuery(q.InConditionsFilter) + case *action.ExecutionSearchFilter_ExecutionTypeFilter: + return executionTypeToQuery(q.ExecutionTypeFilter) + case *action.ExecutionSearchFilter_TargetFilter: + return query.NewTargetSearchQuery(q.TargetFilter.GetTargetId()) + default: + return nil, zerrors.ThrowInvalidArgument(nil, "GRPC-vR9nC", "List.Query.Invalid") + } +} + +func executionTypeToQuery(q *action.ExecutionTypeFilter) (query.SearchQuery, error) { + switch q.ExecutionType { + case action.ExecutionType_EXECUTION_TYPE_UNSPECIFIED: + return query.NewExecutionTypeSearchQuery(domain.ExecutionTypeUnspecified) + case action.ExecutionType_EXECUTION_TYPE_REQUEST: + return query.NewExecutionTypeSearchQuery(domain.ExecutionTypeRequest) + case action.ExecutionType_EXECUTION_TYPE_RESPONSE: + return query.NewExecutionTypeSearchQuery(domain.ExecutionTypeResponse) + case action.ExecutionType_EXECUTION_TYPE_EVENT: + return query.NewExecutionTypeSearchQuery(domain.ExecutionTypeEvent) + case action.ExecutionType_EXECUTION_TYPE_FUNCTION: + return query.NewExecutionTypeSearchQuery(domain.ExecutionTypeFunction) + default: + return query.NewExecutionTypeSearchQuery(domain.ExecutionTypeUnspecified) + } +} + +func inConditionsQueryToQuery(q *action.InConditionsFilter) (query.SearchQuery, error) { + values := make([]string, len(q.GetConditions())) + for i, condition := range q.GetConditions() { + id, err := conditionToID(condition) + if err != nil { + return nil, err + } + values[i] = id + } + return query.NewExecutionInIDsSearchQuery(values) +} + +func conditionToID(q *action.Condition) (string, error) { + switch t := q.GetConditionType().(type) { + case *action.Condition_Request: + cond := &command.ExecutionAPICondition{ + Method: t.Request.GetMethod(), + Service: t.Request.GetService(), + All: t.Request.GetAll(), + } + return cond.ID(domain.ExecutionTypeRequest), nil + case *action.Condition_Response: + cond := &command.ExecutionAPICondition{ + Method: t.Response.GetMethod(), + Service: t.Response.GetService(), + All: t.Response.GetAll(), + } + return cond.ID(domain.ExecutionTypeResponse), nil + case *action.Condition_Event: + cond := &command.ExecutionEventCondition{ + Event: t.Event.GetEvent(), + Group: t.Event.GetGroup(), + All: t.Event.GetAll(), + } + return cond.ID(), nil + case *action.Condition_Function: + return command.ExecutionFunctionCondition(t.Function.GetName()).ID(), nil + default: + return "", zerrors.ThrowInvalidArgument(nil, "GRPC-vR9nC", "List.Query.Invalid") + } +} + +func executionsToPb(executions []*query.Execution) []*action.Execution { + e := make([]*action.Execution, len(executions)) + for i, execution := range executions { + e[i] = executionToPb(execution) + } + return e +} + +func executionToPb(e *query.Execution) *action.Execution { + targets := make([]string, len(e.Targets)) + for i := range e.Targets { + switch e.Targets[i].Type { + case domain.ExecutionTargetTypeTarget: + targets[i] = e.Targets[i].Target + case domain.ExecutionTargetTypeInclude, domain.ExecutionTargetTypeUnspecified: + continue + default: + continue + } + } + + exec := &action.Execution{ + Condition: executionIDToCondition(e.ID), + Targets: targets, + } + if !e.EventDate.IsZero() { + exec.ChangeDate = timestamppb.New(e.EventDate) + } + if !e.CreationDate.IsZero() { + exec.CreationDate = timestamppb.New(e.CreationDate) + } + return exec +} + +func executionIDToCondition(include string) *action.Condition { + if strings.HasPrefix(include, domain.ExecutionTypeRequest.String()) { + return includeRequestToCondition(strings.TrimPrefix(include, domain.ExecutionTypeRequest.String())) + } + if strings.HasPrefix(include, domain.ExecutionTypeResponse.String()) { + return includeResponseToCondition(strings.TrimPrefix(include, domain.ExecutionTypeResponse.String())) + } + if strings.HasPrefix(include, domain.ExecutionTypeEvent.String()) { + return includeEventToCondition(strings.TrimPrefix(include, domain.ExecutionTypeEvent.String())) + } + if strings.HasPrefix(include, domain.ExecutionTypeFunction.String()) { + return includeFunctionToCondition(strings.TrimPrefix(include, domain.ExecutionTypeFunction.String())) + } + return nil +} + +func includeRequestToCondition(id string) *action.Condition { + switch strings.Count(id, "/") { + case conditionIDRequestResponseMethodSegmentCount: + return &action.Condition{ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_Method{Method: id}}}} + case conditionIDRequestResponseServiceSegmentCount: + return &action.Condition{ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_Service{Service: strings.TrimPrefix(id, "/")}}}} + case conditionIDAllSegmentCount: + return &action.Condition{ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_All{All: true}}}} + default: + return nil + } +} +func includeResponseToCondition(id string) *action.Condition { + switch strings.Count(id, "/") { + case conditionIDRequestResponseMethodSegmentCount: + return &action.Condition{ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_Method{Method: id}}}} + case conditionIDRequestResponseServiceSegmentCount: + return &action.Condition{ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_Service{Service: strings.TrimPrefix(id, "/")}}}} + case conditionIDAllSegmentCount: + return &action.Condition{ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_All{All: true}}}} + default: + return nil + } +} + +func includeEventToCondition(id string) *action.Condition { + switch strings.Count(id, "/") { + case conditionIDEventGroupSegmentCount: + if strings.HasSuffix(id, command.EventGroupSuffix) { + return &action.Condition{ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_Group{Group: strings.TrimSuffix(strings.TrimPrefix(id, "/"), command.EventGroupSuffix)}}}} + } else { + return &action.Condition{ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_Event{Event: strings.TrimPrefix(id, "/")}}}} + } + case conditionIDAllSegmentCount: + return &action.Condition{ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_All{All: true}}}} + default: + return nil + } +} + +func includeFunctionToCondition(id string) *action.Condition { + return &action.Condition{ConditionType: &action.Condition_Function{Function: &action.FunctionExecution{Name: strings.TrimPrefix(id, "/")}}} +} diff --git a/internal/api/grpc/action/v2/server.go b/internal/api/grpc/action/v2/server.go new file mode 100644 index 0000000000..b94e43ef6b --- /dev/null +++ b/internal/api/grpc/action/v2/server.go @@ -0,0 +1,71 @@ +package action + +import ( + "net/http" + + "connectrpc.com/connect" + "google.golang.org/protobuf/reflect/protoreflect" + + "github.com/zitadel/zitadel/internal/api/authz" + "github.com/zitadel/zitadel/internal/api/grpc/server" + "github.com/zitadel/zitadel/internal/command" + "github.com/zitadel/zitadel/internal/config/systemdefaults" + "github.com/zitadel/zitadel/internal/query" + "github.com/zitadel/zitadel/pkg/grpc/action/v2" + "github.com/zitadel/zitadel/pkg/grpc/action/v2/actionconnect" +) + +var _ actionconnect.ActionServiceHandler = (*Server)(nil) + +type Server struct { + systemDefaults systemdefaults.SystemDefaults + command *command.Commands + query *query.Queries + ListActionFunctions func() []string + ListGRPCMethods func() []string + ListGRPCServices func() []string +} + +type Config struct{} + +func CreateServer( + systemDefaults systemdefaults.SystemDefaults, + command *command.Commands, + query *query.Queries, + listActionFunctions func() []string, + listGRPCMethods func() []string, + listGRPCServices func() []string, +) *Server { + return &Server{ + systemDefaults: systemDefaults, + command: command, + query: query, + ListActionFunctions: listActionFunctions, + ListGRPCMethods: listGRPCMethods, + ListGRPCServices: listGRPCServices, + } +} + +func (s *Server) RegisterConnectServer(interceptors ...connect.Interceptor) (string, http.Handler) { + return actionconnect.NewActionServiceHandler(s, connect.WithInterceptors(interceptors...)) +} + +func (s *Server) FileDescriptor() protoreflect.FileDescriptor { + return action.File_zitadel_action_v2_action_service_proto +} + +func (s *Server) AppName() string { + return action.ActionService_ServiceDesc.ServiceName +} + +func (s *Server) MethodPrefix() string { + return action.ActionService_ServiceDesc.ServiceName +} + +func (s *Server) AuthMethods() authz.MethodMapping { + return action.ActionService_AuthMethods +} + +func (s *Server) RegisterGateway() server.RegisterGatewayFunc { + return action.RegisterActionServiceHandler +} diff --git a/internal/api/grpc/action/v2/target.go b/internal/api/grpc/action/v2/target.go new file mode 100644 index 0000000000..971a6b871e --- /dev/null +++ b/internal/api/grpc/action/v2/target.go @@ -0,0 +1,123 @@ +package action + +import ( + "context" + + "connectrpc.com/connect" + "github.com/muhlemmer/gu" + "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/zitadel/zitadel/internal/api/authz" + "github.com/zitadel/zitadel/internal/command" + "github.com/zitadel/zitadel/internal/domain" + "github.com/zitadel/zitadel/internal/eventstore/v1/models" + "github.com/zitadel/zitadel/pkg/grpc/action/v2" +) + +func (s *Server) CreateTarget(ctx context.Context, req *connect.Request[action.CreateTargetRequest]) (*connect.Response[action.CreateTargetResponse], error) { + add := createTargetToCommand(req.Msg) + instanceID := authz.GetInstance(ctx).InstanceID() + createdAt, err := s.command.AddTarget(ctx, add, instanceID) + if err != nil { + return nil, err + } + var creationDate *timestamppb.Timestamp + if !createdAt.IsZero() { + creationDate = timestamppb.New(createdAt) + } + return connect.NewResponse(&action.CreateTargetResponse{ + Id: add.AggregateID, + CreationDate: creationDate, + SigningKey: add.SigningKey, + }), nil +} + +func (s *Server) UpdateTarget(ctx context.Context, req *connect.Request[action.UpdateTargetRequest]) (*connect.Response[action.UpdateTargetResponse], error) { + instanceID := authz.GetInstance(ctx).InstanceID() + update := updateTargetToCommand(req.Msg) + changedAt, err := s.command.ChangeTarget(ctx, update, instanceID) + if err != nil { + return nil, err + } + var changeDate *timestamppb.Timestamp + if !changedAt.IsZero() { + changeDate = timestamppb.New(changedAt) + } + return connect.NewResponse(&action.UpdateTargetResponse{ + ChangeDate: changeDate, + SigningKey: update.SigningKey, + }), nil +} + +func (s *Server) DeleteTarget(ctx context.Context, req *connect.Request[action.DeleteTargetRequest]) (*connect.Response[action.DeleteTargetResponse], error) { + instanceID := authz.GetInstance(ctx).InstanceID() + deletedAt, err := s.command.DeleteTarget(ctx, req.Msg.GetId(), instanceID) + if err != nil { + return nil, err + } + var deletionDate *timestamppb.Timestamp + if !deletedAt.IsZero() { + deletionDate = timestamppb.New(deletedAt) + } + return connect.NewResponse(&action.DeleteTargetResponse{ + DeletionDate: deletionDate, + }), nil +} + +func createTargetToCommand(req *action.CreateTargetRequest) *command.AddTarget { + var ( + targetType domain.TargetType + interruptOnError bool + ) + switch t := req.GetTargetType().(type) { + case *action.CreateTargetRequest_RestWebhook: + targetType = domain.TargetTypeWebhook + interruptOnError = t.RestWebhook.InterruptOnError + case *action.CreateTargetRequest_RestCall: + targetType = domain.TargetTypeCall + interruptOnError = t.RestCall.InterruptOnError + case *action.CreateTargetRequest_RestAsync: + targetType = domain.TargetTypeAsync + } + return &command.AddTarget{ + Name: req.GetName(), + TargetType: targetType, + Endpoint: req.GetEndpoint(), + Timeout: req.GetTimeout().AsDuration(), + InterruptOnError: interruptOnError, + } +} + +func updateTargetToCommand(req *action.UpdateTargetRequest) *command.ChangeTarget { + // TODO handle expiration, currently only immediate expiration is supported + expirationSigningKey := req.GetExpirationSigningKey() != nil + + if req == nil { + return nil + } + target := &command.ChangeTarget{ + ObjectRoot: models.ObjectRoot{ + AggregateID: req.GetId(), + }, + Name: req.Name, + Endpoint: req.Endpoint, + ExpirationSigningKey: expirationSigningKey, + } + if req.TargetType != nil { + switch t := req.GetTargetType().(type) { + case *action.UpdateTargetRequest_RestWebhook: + target.TargetType = gu.Ptr(domain.TargetTypeWebhook) + target.InterruptOnError = gu.Ptr(t.RestWebhook.InterruptOnError) + case *action.UpdateTargetRequest_RestCall: + target.TargetType = gu.Ptr(domain.TargetTypeCall) + target.InterruptOnError = gu.Ptr(t.RestCall.InterruptOnError) + case *action.UpdateTargetRequest_RestAsync: + target.TargetType = gu.Ptr(domain.TargetTypeAsync) + target.InterruptOnError = gu.Ptr(false) + } + } + if req.Timeout != nil { + target.Timeout = gu.Ptr(req.GetTimeout().AsDuration()) + } + return target +} diff --git a/internal/api/grpc/action/v2/target_test.go b/internal/api/grpc/action/v2/target_test.go new file mode 100644 index 0000000000..f41932933a --- /dev/null +++ b/internal/api/grpc/action/v2/target_test.go @@ -0,0 +1,229 @@ +package action + +import ( + "testing" + "time" + + "github.com/muhlemmer/gu" + "github.com/stretchr/testify/assert" + "google.golang.org/protobuf/types/known/durationpb" + + "github.com/zitadel/zitadel/internal/command" + "github.com/zitadel/zitadel/internal/domain" + "github.com/zitadel/zitadel/pkg/grpc/action/v2" +) + +func Test_createTargetToCommand(t *testing.T) { + type args struct { + req *action.CreateTargetRequest + } + tests := []struct { + name string + args args + want *command.AddTarget + }{ + { + name: "nil", + args: args{nil}, + want: &command.AddTarget{ + Name: "", + Endpoint: "", + Timeout: 0, + InterruptOnError: false, + }, + }, + { + name: "all fields (webhook)", + args: args{&action.CreateTargetRequest{ + Name: "target 1", + Endpoint: "https://example.com/hooks/1", + TargetType: &action.CreateTargetRequest_RestWebhook{ + RestWebhook: &action.RESTWebhook{}, + }, + Timeout: durationpb.New(10 * time.Second), + }}, + want: &command.AddTarget{ + Name: "target 1", + TargetType: domain.TargetTypeWebhook, + Endpoint: "https://example.com/hooks/1", + Timeout: 10 * time.Second, + InterruptOnError: false, + }, + }, + { + name: "all fields (async)", + args: args{&action.CreateTargetRequest{ + Name: "target 1", + Endpoint: "https://example.com/hooks/1", + TargetType: &action.CreateTargetRequest_RestAsync{ + RestAsync: &action.RESTAsync{}, + }, + Timeout: durationpb.New(10 * time.Second), + }}, + want: &command.AddTarget{ + Name: "target 1", + TargetType: domain.TargetTypeAsync, + Endpoint: "https://example.com/hooks/1", + Timeout: 10 * time.Second, + InterruptOnError: false, + }, + }, + { + name: "all fields (interrupting response)", + args: args{&action.CreateTargetRequest{ + Name: "target 1", + Endpoint: "https://example.com/hooks/1", + TargetType: &action.CreateTargetRequest_RestCall{ + RestCall: &action.RESTCall{ + InterruptOnError: true, + }, + }, + Timeout: durationpb.New(10 * time.Second), + }}, + want: &command.AddTarget{ + Name: "target 1", + TargetType: domain.TargetTypeCall, + Endpoint: "https://example.com/hooks/1", + Timeout: 10 * time.Second, + InterruptOnError: true, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := createTargetToCommand(tt.args.req) + assert.Equal(t, tt.want, got) + }) + } +} + +func Test_updateTargetToCommand(t *testing.T) { + type args struct { + req *action.UpdateTargetRequest + } + tests := []struct { + name string + args args + want *command.ChangeTarget + }{ + { + name: "nil", + args: args{nil}, + want: nil, + }, + { + name: "all fields nil", + args: args{&action.UpdateTargetRequest{ + Name: nil, + TargetType: nil, + Timeout: nil, + }}, + want: &command.ChangeTarget{ + Name: nil, + TargetType: nil, + Endpoint: nil, + Timeout: nil, + InterruptOnError: nil, + }, + }, + { + name: "all fields empty", + args: args{&action.UpdateTargetRequest{ + Name: gu.Ptr(""), + TargetType: nil, + Timeout: durationpb.New(0), + }}, + want: &command.ChangeTarget{ + Name: gu.Ptr(""), + TargetType: nil, + Endpoint: nil, + Timeout: gu.Ptr(0 * time.Second), + InterruptOnError: nil, + }, + }, + { + name: "all fields (webhook)", + args: args{&action.UpdateTargetRequest{ + Name: gu.Ptr("target 1"), + Endpoint: gu.Ptr("https://example.com/hooks/1"), + TargetType: &action.UpdateTargetRequest_RestWebhook{ + RestWebhook: &action.RESTWebhook{ + InterruptOnError: false, + }, + }, + Timeout: durationpb.New(10 * time.Second), + }}, + want: &command.ChangeTarget{ + Name: gu.Ptr("target 1"), + TargetType: gu.Ptr(domain.TargetTypeWebhook), + Endpoint: gu.Ptr("https://example.com/hooks/1"), + Timeout: gu.Ptr(10 * time.Second), + InterruptOnError: gu.Ptr(false), + }, + }, + { + name: "all fields (webhook interrupt)", + args: args{&action.UpdateTargetRequest{ + Name: gu.Ptr("target 1"), + Endpoint: gu.Ptr("https://example.com/hooks/1"), + TargetType: &action.UpdateTargetRequest_RestWebhook{ + RestWebhook: &action.RESTWebhook{ + InterruptOnError: true, + }, + }, + Timeout: durationpb.New(10 * time.Second), + }}, + want: &command.ChangeTarget{ + Name: gu.Ptr("target 1"), + TargetType: gu.Ptr(domain.TargetTypeWebhook), + Endpoint: gu.Ptr("https://example.com/hooks/1"), + Timeout: gu.Ptr(10 * time.Second), + InterruptOnError: gu.Ptr(true), + }, + }, + { + name: "all fields (async)", + args: args{&action.UpdateTargetRequest{ + Name: gu.Ptr("target 1"), + Endpoint: gu.Ptr("https://example.com/hooks/1"), + TargetType: &action.UpdateTargetRequest_RestAsync{ + RestAsync: &action.RESTAsync{}, + }, + Timeout: durationpb.New(10 * time.Second), + }}, + want: &command.ChangeTarget{ + Name: gu.Ptr("target 1"), + TargetType: gu.Ptr(domain.TargetTypeAsync), + Endpoint: gu.Ptr("https://example.com/hooks/1"), + Timeout: gu.Ptr(10 * time.Second), + InterruptOnError: gu.Ptr(false), + }, + }, + { + name: "all fields (interrupting response)", + args: args{&action.UpdateTargetRequest{ + Name: gu.Ptr("target 1"), + Endpoint: gu.Ptr("https://example.com/hooks/1"), + TargetType: &action.UpdateTargetRequest_RestCall{ + RestCall: &action.RESTCall{ + InterruptOnError: true, + }, + }, + Timeout: durationpb.New(10 * time.Second), + }}, + want: &command.ChangeTarget{ + Name: gu.Ptr("target 1"), + TargetType: gu.Ptr(domain.TargetTypeCall), + Endpoint: gu.Ptr("https://example.com/hooks/1"), + Timeout: gu.Ptr(10 * time.Second), + InterruptOnError: gu.Ptr(true), + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := updateTargetToCommand(tt.args.req) + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/internal/api/grpc/action/v2beta/integration_test/execution_target_test.go b/internal/api/grpc/action/v2beta/integration_test/execution_target_test.go index a2e6131e11..4db254fe30 100644 --- a/internal/api/grpc/action/v2beta/integration_test/execution_target_test.go +++ b/internal/api/grpc/action/v2beta/integration_test/execution_target_test.go @@ -48,7 +48,7 @@ var ( func TestServer_ExecutionTarget(t *testing.T) { instance := integration.NewInstance(CTX) - isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) fullMethod := action.ActionService_GetTarget_FullMethodName tests := []struct { @@ -164,8 +164,8 @@ func TestServer_ExecutionTarget(t *testing.T) { } }, clean: func(ctx context.Context) { - instance.DeleteExecution(ctx, t, conditionRequestFullMethod(fullMethod)) - instance.DeleteExecution(ctx, t, conditionResponseFullMethod(fullMethod)) + deleteExecution(ctx, t, instance, conditionRequestFullMethod(fullMethod)) + deleteExecution(ctx, t, instance, conditionResponseFullMethod(fullMethod)) }, req: &action.GetTargetRequest{ Id: "something", @@ -197,7 +197,7 @@ func TestServer_ExecutionTarget(t *testing.T) { } }, clean: func(ctx context.Context) { - instance.DeleteExecution(ctx, t, conditionRequestFullMethod(fullMethod)) + deleteExecution(ctx, t, instance, conditionRequestFullMethod(fullMethod)) }, req: &action.GetTargetRequest{}, wantErr: true, @@ -259,7 +259,7 @@ func TestServer_ExecutionTarget(t *testing.T) { } }, clean: func(ctx context.Context) { - instance.DeleteExecution(ctx, t, conditionResponseFullMethod(fullMethod)) + deleteExecution(ctx, t, instance, conditionResponseFullMethod(fullMethod)) }, req: &action.GetTargetRequest{}, wantErr: true, @@ -290,9 +290,16 @@ func TestServer_ExecutionTarget(t *testing.T) { } } +func deleteExecution(ctx context.Context, t *testing.T, instance *integration.Instance, cond *action.Condition) { + _, err := instance.Client.ActionV2beta.SetExecution(ctx, &action.SetExecutionRequest{ + Condition: cond, + }) + require.NoError(t, err) +} + func TestServer_ExecutionTarget_Event(t *testing.T) { instance := integration.NewInstance(CTX) - isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) event := "session.added" urlRequest, closeF, calledF, resetF := integration.TestServerCall(nil, 0, http.StatusOK, nil) @@ -349,7 +356,7 @@ func TestServer_ExecutionTarget_Event(t *testing.T) { func TestServer_ExecutionTarget_Event_LongerThanTargetTimeout(t *testing.T) { instance := integration.NewInstance(CTX) - isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) event := "session.added" // call takes longer than timeout of target @@ -401,7 +408,7 @@ func TestServer_ExecutionTarget_Event_LongerThanTargetTimeout(t *testing.T) { func TestServer_ExecutionTarget_Event_LongerThanTransactionTimeout(t *testing.T) { instance := integration.NewInstance(CTX) - isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) event := "session.added" urlRequest, closeF, calledF, resetF := integration.TestServerCall(nil, 1*time.Second, http.StatusOK, nil) @@ -463,7 +470,7 @@ func TestServer_ExecutionTarget_Event_LongerThanTransactionTimeout(t *testing.T) } func waitForExecutionOnCondition(ctx context.Context, t *testing.T, instance *integration.Instance, condition *action.Condition, targets []string) { - instance.SetExecution(ctx, t, condition, targets) + setExecution(ctx, t, instance, condition, targets) retryDuration, tick := integration.WaitForAndTickWithMaxDuration(ctx, time.Minute) require.EventuallyWithT(t, func(ttt *assert.CollectT) { @@ -488,11 +495,19 @@ func waitForExecutionOnCondition(ctx context.Context, t *testing.T, instance *in } } }, retryDuration, tick, "timeout waiting for expected execution result") - return +} + +func setExecution(ctx context.Context, t *testing.T, instance *integration.Instance, cond *action.Condition, targets []string) *action.SetExecutionResponse { + target, err := instance.Client.ActionV2beta.SetExecution(ctx, &action.SetExecutionRequest{ + Condition: cond, + Targets: targets, + }) + require.NoError(t, err) + return target } func waitForTarget(ctx context.Context, t *testing.T, instance *integration.Instance, endpoint string, ty domain.TargetType, interrupt bool) *action.CreateTargetResponse { - resp := instance.CreateTarget(ctx, t, "", endpoint, ty, interrupt) + resp := createTarget(ctx, t, instance, "", endpoint, ty, interrupt) retryDuration, tick := integration.WaitForAndTickWithMaxDuration(ctx, time.Minute) require.EventuallyWithT(t, func(ttt *assert.CollectT) { @@ -529,6 +544,38 @@ func waitForTarget(ctx context.Context, t *testing.T, instance *integration.Inst return resp } +func createTarget(ctx context.Context, t *testing.T, instance *integration.Instance, name, endpoint string, ty domain.TargetType, interrupt bool) *action.CreateTargetResponse { + if name == "" { + name = gofakeit.Name() + } + req := &action.CreateTargetRequest{ + Name: name, + Endpoint: endpoint, + Timeout: durationpb.New(5 * time.Second), + } + switch ty { + case domain.TargetTypeWebhook: + req.TargetType = &action.CreateTargetRequest_RestWebhook{ + RestWebhook: &action.RESTWebhook{ + InterruptOnError: interrupt, + }, + } + case domain.TargetTypeCall: + req.TargetType = &action.CreateTargetRequest_RestCall{ + RestCall: &action.RESTCall{ + InterruptOnError: interrupt, + }, + } + case domain.TargetTypeAsync: + req.TargetType = &action.CreateTargetRequest_RestAsync{ + RestAsync: &action.RESTAsync{}, + } + } + target, err := instance.Client.ActionV2beta.CreateTarget(ctx, req) + require.NoError(t, err) + return target +} + func conditionRequestFullMethod(fullMethod string) *action.Condition { return &action.Condition{ ConditionType: &action.Condition_Request{ @@ -577,8 +624,8 @@ func conditionFunction(function string) *action.Condition { func TestServer_ExecutionTargetPreUserinfo(t *testing.T) { instance := integration.NewInstance(CTX) - isolatedIAMCtx := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) - ctxLoginClient := instance.WithAuthorization(CTX, integration.UserTypeLogin) + isolatedIAMCtx := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + ctxLoginClient := instance.WithAuthorizationToken(CTX, integration.UserTypeLogin) client, err := instance.CreateOIDCImplicitFlowClient(isolatedIAMCtx, t, redirectURIImplicit, loginV2) require.NoError(t, err) @@ -893,8 +940,8 @@ func contextInfoForUserOIDC(instance *integration.Instance, function string, cli func TestServer_ExecutionTargetPreAccessToken(t *testing.T) { instance := integration.NewInstance(CTX) - isolatedIAMCtx := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) - ctxLoginClient := instance.WithAuthorization(CTX, integration.UserTypeLogin) + isolatedIAMCtx := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + ctxLoginClient := instance.WithAuthorizationToken(CTX, integration.UserTypeLogin) client, err := instance.CreateOIDCImplicitFlowClient(isolatedIAMCtx, t, redirectURIImplicit, loginV2) require.NoError(t, err) @@ -1086,8 +1133,8 @@ func expectPreAccessTokenExecution(ctx context.Context, t *testing.T, instance * func TestServer_ExecutionTargetPreSAMLResponse(t *testing.T) { instance := integration.NewInstance(CTX) - isolatedIAMCtx := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) - ctxLoginClient := instance.WithAuthorization(CTX, integration.UserTypeLogin) + isolatedIAMCtx := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) + ctxLoginClient := instance.WithAuthorizationToken(CTX, integration.UserTypeLogin) idpMetadata, err := instance.GetSAMLIDPMetadata() require.NoError(t, err) diff --git a/internal/api/grpc/action/v2beta/integration_test/execution_test.go b/internal/api/grpc/action/v2beta/integration_test/execution_test.go index 2199b9f454..dee736991b 100644 --- a/internal/api/grpc/action/v2beta/integration_test/execution_test.go +++ b/internal/api/grpc/action/v2beta/integration_test/execution_test.go @@ -17,7 +17,7 @@ import ( func TestServer_SetExecution_Request(t *testing.T) { instance := integration.NewInstance(CTX) - isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://notexisting", domain.TargetTypeWebhook, false) tests := []struct { @@ -29,7 +29,7 @@ func TestServer_SetExecution_Request(t *testing.T) { }{ { name: "missing permission", - ctx: instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner), + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), req: &action.SetExecutionRequest{ Condition: &action.Condition{ ConditionType: &action.Condition_Request{ @@ -155,7 +155,7 @@ func TestServer_SetExecution_Request(t *testing.T) { assertSetExecutionResponse(t, creationDate, setDate, tt.wantSetDate, got) // cleanup to not impact other requests - instance.DeleteExecution(tt.ctx, t, tt.req.GetCondition()) + deleteExecution(tt.ctx, t, instance, tt.req.GetCondition()) }) } } @@ -174,7 +174,7 @@ func assertSetExecutionResponse(t *testing.T, creationDate, setDate time.Time, e func TestServer_SetExecution_Response(t *testing.T) { instance := integration.NewInstance(CTX) - isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://notexisting", domain.TargetTypeWebhook, false) tests := []struct { @@ -186,7 +186,7 @@ func TestServer_SetExecution_Response(t *testing.T) { }{ { name: "missing permission", - ctx: instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner), + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), req: &action.SetExecutionRequest{ Condition: &action.Condition{ ConditionType: &action.Condition_Response{ @@ -311,14 +311,14 @@ func TestServer_SetExecution_Response(t *testing.T) { assertSetExecutionResponse(t, creationDate, setDate, tt.wantSetDate, got) // cleanup to not impact other requests - instance.DeleteExecution(tt.ctx, t, tt.req.GetCondition()) + deleteExecution(tt.ctx, t, instance, tt.req.GetCondition()) }) } } func TestServer_SetExecution_Event(t *testing.T) { instance := integration.NewInstance(CTX) - isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://notexisting", domain.TargetTypeWebhook, false) tests := []struct { @@ -330,7 +330,7 @@ func TestServer_SetExecution_Event(t *testing.T) { }{ { name: "missing permission", - ctx: instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner), + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), req: &action.SetExecutionRequest{ Condition: &action.Condition{ ConditionType: &action.Condition_Event{ @@ -474,14 +474,14 @@ func TestServer_SetExecution_Event(t *testing.T) { assertSetExecutionResponse(t, creationDate, setDate, tt.wantSetDate, got) // cleanup to not impact other requests - instance.DeleteExecution(tt.ctx, t, tt.req.GetCondition()) + deleteExecution(tt.ctx, t, instance, tt.req.GetCondition()) }) } } func TestServer_SetExecution_Function(t *testing.T) { instance := integration.NewInstance(CTX) - isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://notexisting", domain.TargetTypeWebhook, false) tests := []struct { @@ -493,7 +493,7 @@ func TestServer_SetExecution_Function(t *testing.T) { }{ { name: "missing permission", - ctx: instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner), + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), req: &action.SetExecutionRequest{ Condition: &action.Condition{ ConditionType: &action.Condition_Response{ @@ -559,7 +559,7 @@ func TestServer_SetExecution_Function(t *testing.T) { assertSetExecutionResponse(t, creationDate, setDate, tt.wantSetDate, got) // cleanup to not impact other requests - instance.DeleteExecution(tt.ctx, t, tt.req.GetCondition()) + deleteExecution(tt.ctx, t, instance, tt.req.GetCondition()) }) } } diff --git a/internal/api/grpc/action/v2beta/integration_test/query_test.go b/internal/api/grpc/action/v2beta/integration_test/query_test.go index 65cc541123..1118311bd2 100644 --- a/internal/api/grpc/action/v2beta/integration_test/query_test.go +++ b/internal/api/grpc/action/v2beta/integration_test/query_test.go @@ -21,7 +21,7 @@ import ( func TestServer_GetTarget(t *testing.T) { instance := integration.NewInstance(CTX) - isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) type args struct { ctx context.Context dep func(context.Context, *action.GetTargetRequest, *action.GetTargetResponse) error @@ -36,7 +36,7 @@ func TestServer_GetTarget(t *testing.T) { { name: "missing permission", args: args{ - ctx: instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner), + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), req: &action.GetTargetRequest{}, }, wantErr: true, @@ -213,7 +213,7 @@ func TestServer_GetTarget(t *testing.T) { func TestServer_ListTargets(t *testing.T) { instance := integration.NewInstance(CTX) - isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) type args struct { ctx context.Context dep func(context.Context, *action.ListTargetsRequest, *action.ListTargetsResponse) @@ -228,7 +228,7 @@ func TestServer_ListTargets(t *testing.T) { { name: "missing permission", args: args{ - ctx: instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner), + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), req: &action.ListTargetsRequest{}, }, wantErr: true, @@ -445,7 +445,7 @@ func assertPaginationResponse(t *assert.CollectT, expected *filter.PaginationRes func TestServer_ListExecutions(t *testing.T) { instance := integration.NewInstance(CTX) - isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false) type args struct { @@ -462,7 +462,7 @@ func TestServer_ListExecutions(t *testing.T) { { name: "missing permission", args: args{ - ctx: instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner), + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), req: &action.ListExecutionsRequest{}, }, wantErr: true, @@ -473,7 +473,7 @@ func TestServer_ListExecutions(t *testing.T) { ctx: isolatedIAMOwnerCTX, dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) { cond := request.Filters[0].GetInConditionsFilter().GetConditions()[0] - resp := instance.SetExecution(ctx, t, cond, []string{targetResp.GetId()}) + resp := setExecution(ctx, t, instance, cond, []string{targetResp.GetId()}) // Set expected response with used values for SetExecution response.Executions[0].CreationDate = resp.GetSetDate() @@ -542,7 +542,7 @@ func TestServer_ListExecutions(t *testing.T) { }, }, } - resp := instance.SetExecution(ctx, t, cond, []string{target.GetId()}) + resp := setExecution(ctx, t, instance, cond, []string{target.GetId()}) response.Executions[0].CreationDate = resp.GetSetDate() response.Executions[0].ChangeDate = resp.GetSetDate() @@ -603,7 +603,7 @@ func TestServer_ListExecutions(t *testing.T) { } cond1 := request.Filters[0].GetInConditionsFilter().GetConditions()[0] - resp1 := instance.SetExecution(ctx, t, cond1, []string{targetResp.GetId()}) + resp1 := setExecution(ctx, t, instance, cond1, []string{targetResp.GetId()}) response.Executions[2] = &action.Execution{ CreationDate: resp1.GetSetDate(), ChangeDate: resp1.GetSetDate(), @@ -612,7 +612,7 @@ func TestServer_ListExecutions(t *testing.T) { } cond2 := request.Filters[0].GetInConditionsFilter().GetConditions()[1] - resp2 := instance.SetExecution(ctx, t, cond2, []string{targetResp.GetId()}) + resp2 := setExecution(ctx, t, instance, cond2, []string{targetResp.GetId()}) response.Executions[1] = &action.Execution{ CreationDate: resp2.GetSetDate(), ChangeDate: resp2.GetSetDate(), @@ -621,7 +621,7 @@ func TestServer_ListExecutions(t *testing.T) { } cond3 := request.Filters[0].GetInConditionsFilter().GetConditions()[2] - resp3 := instance.SetExecution(ctx, t, cond3, []string{targetResp.GetId()}) + resp3 := setExecution(ctx, t, instance, cond3, []string{targetResp.GetId()}) response.Executions[0] = &action.Execution{ CreationDate: resp3.GetSetDate(), ChangeDate: resp3.GetSetDate(), @@ -652,7 +652,7 @@ func TestServer_ListExecutions(t *testing.T) { dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) { conditions := request.Filters[0].GetInConditionsFilter().GetConditions() for i, cond := range conditions { - resp := instance.SetExecution(ctx, t, cond, []string{targetResp.GetId()}) + resp := setExecution(ctx, t, instance, cond, []string{targetResp.GetId()}) response.Executions[(len(conditions)-1)-i] = &action.Execution{ CreationDate: resp.GetSetDate(), ChangeDate: resp.GetSetDate(), @@ -708,7 +708,7 @@ func TestServer_ListExecutions(t *testing.T) { dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) { conditions := request.Filters[0].GetInConditionsFilter().GetConditions() for i, cond := range conditions { - resp := instance.SetExecution(ctx, t, cond, []string{targetResp.GetId()}) + resp := setExecution(ctx, t, instance, cond, []string{targetResp.GetId()}) response.Executions[i] = &action.Execution{ CreationDate: resp.GetSetDate(), ChangeDate: resp.GetSetDate(), diff --git a/internal/api/grpc/action/v2beta/integration_test/target_test.go b/internal/api/grpc/action/v2beta/integration_test/target_test.go index 8238d3146d..25a4e5f550 100644 --- a/internal/api/grpc/action/v2beta/integration_test/target_test.go +++ b/internal/api/grpc/action/v2beta/integration_test/target_test.go @@ -19,7 +19,7 @@ import ( func TestServer_CreateTarget(t *testing.T) { instance := integration.NewInstance(CTX) - isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) type want struct { id bool creationDate bool @@ -36,7 +36,7 @@ func TestServer_CreateTarget(t *testing.T) { }{ { name: "missing permission", - ctx: instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner), + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), req: &action.CreateTargetRequest{ Name: gofakeit.Name(), }, @@ -243,7 +243,7 @@ func assertCreateTargetResponse(t *testing.T, creationDate, changeDate time.Time func TestServer_UpdateTarget(t *testing.T) { instance := integration.NewInstance(CTX) - isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) type args struct { ctx context.Context req *action.UpdateTargetRequest @@ -267,7 +267,7 @@ func TestServer_UpdateTarget(t *testing.T) { request.Id = targetID }, args: args{ - ctx: instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner), + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), req: &action.UpdateTargetRequest{ Name: gu.Ptr(gofakeit.Name()), }, @@ -278,7 +278,6 @@ func TestServer_UpdateTarget(t *testing.T) { name: "not existing", prepare: func(request *action.UpdateTargetRequest) { request.Id = "notexisting" - return }, args: args{ ctx: isolatedIAMOwnerCTX, @@ -461,7 +460,7 @@ func assertUpdateTargetResponse(t *testing.T, creationDate, changeDate time.Time func TestServer_DeleteTarget(t *testing.T) { instance := integration.NewInstance(CTX) - iamOwnerCtx := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + iamOwnerCtx := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner) tests := []struct { name string ctx context.Context @@ -472,7 +471,7 @@ func TestServer_DeleteTarget(t *testing.T) { }{ { name: "missing permission", - ctx: instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner), + ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner), req: &action.DeleteTargetRequest{ Id: "notexisting", }, diff --git a/internal/api/grpc/action/v2beta/query.go b/internal/api/grpc/action/v2beta/query.go index 64cf3b7618..164283b890 100644 --- a/internal/api/grpc/action/v2beta/query.go +++ b/internal/api/grpc/action/v2beta/query.go @@ -82,7 +82,7 @@ func targetsToPb(targets []*query.Target) []*action.Target { func targetToPb(t *query.Target) *action.Target { target := &action.Target{ - Id: t.ObjectDetails.ID, + Id: t.ID, Name: t.Name, Timeout: durationpb.New(t.Timeout), Endpoint: t.Endpoint, @@ -99,11 +99,11 @@ func targetToPb(t *query.Target) *action.Target { target.TargetType = nil } - if !t.ObjectDetails.EventDate.IsZero() { - target.ChangeDate = timestamppb.New(t.ObjectDetails.EventDate) + if !t.EventDate.IsZero() { + target.ChangeDate = timestamppb.New(t.EventDate) } - if !t.ObjectDetails.CreationDate.IsZero() { - target.CreationDate = timestamppb.New(t.ObjectDetails.CreationDate) + if !t.CreationDate.IsZero() { + target.CreationDate = timestamppb.New(t.CreationDate) } return target } @@ -334,11 +334,11 @@ func executionToPb(e *query.Execution) *action.Execution { Condition: executionIDToCondition(e.ID), Targets: targets, } - if !e.ObjectDetails.EventDate.IsZero() { - exec.ChangeDate = timestamppb.New(e.ObjectDetails.EventDate) + if !e.EventDate.IsZero() { + exec.ChangeDate = timestamppb.New(e.EventDate) } - if !e.ObjectDetails.CreationDate.IsZero() { - exec.CreationDate = timestamppb.New(e.ObjectDetails.CreationDate) + if !e.CreationDate.IsZero() { + exec.CreationDate = timestamppb.New(e.CreationDate) } return exec } diff --git a/internal/idp/providers/saml/session.go b/internal/idp/providers/saml/session.go index e1f32209b0..f49f50f4e6 100644 --- a/internal/idp/providers/saml/session.go +++ b/internal/idp/providers/saml/session.go @@ -6,6 +6,7 @@ import ( "errors" "net/http" "net/url" + "strings" "time" "github.com/beevik/etree" @@ -75,21 +76,31 @@ func (s *Session) FetchUser(ctx context.Context) (user idp.User, err error) { return nil, zerrors.ThrowInvalidArgument(err, "SAML-nuo0vphhh9", "Errors.Intent.ResponseInvalid") } + userMapper := NewUser() // nameID is required, but at least in ADFS it will not be sent unless explicitly configured if s.Assertion.Subject == nil || s.Assertion.Subject.NameID == nil { - return nil, zerrors.ThrowInvalidArgument(err, "SAML-EFG32", "Errors.Intent.ResponseInvalid") - } - nameID := s.Assertion.Subject.NameID - userMapper := NewUser() - // use the nameID as default mapping id - userMapper.SetID(nameID.Value) - if nameID.Format == string(saml.TransientNameIDFormat) { + if strings.TrimSpace(s.TransientMappingAttributeName) == "" { + return nil, zerrors.ThrowInvalidArgument(err, "SAML-EFG32", "Errors.Intent.MissingTransientMappingAttributeName") + } + // workaround to use the transient mapping attribute when the subject / nameID are missing (e.g. in ADFS, Shibboleth) mappingID, err := s.transientMappingID() if err != nil { return nil, err } userMapper.SetID(mappingID) + } else { + nameID := s.Assertion.Subject.NameID + // use the nameID as default mapping id + userMapper.SetID(nameID.Value) + if nameID.Format == string(saml.TransientNameIDFormat) { + mappingID, err := s.transientMappingID() + if err != nil { + return nil, err + } + userMapper.SetID(mappingID) + } } + for _, statement := range s.Assertion.AttributeStatements { for _, attribute := range statement.Attributes { values := make([]string, len(attribute.Values)) diff --git a/internal/idp/providers/saml/session_test.go b/internal/idp/providers/saml/session_test.go index ea3e510d60..836462c5d8 100644 --- a/internal/idp/providers/saml/session_test.go +++ b/internal/idp/providers/saml/session_test.go @@ -138,7 +138,49 @@ func TestSession_FetchUser(t *testing.T) { }, }, { - name: "response invalid (missing nameID)", + name: "missing nameID, custom transient mapping attribute config is set and also present in the response", + fields: fields{ + name: "saml", + key: []byte("-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEAxHd087RoEm9ywVWZ/H+tDWxQsmVvhfRz4jAq/RfU+OWXNH4J\njMMSHdFs0Q+WP98nNXRyc7fgbMb8NdmlB2yD4qLYapN5SDaBc5dh/3EnyFt53oSs\njTlKnQUPAeJr2qh/NY046CfyUyQMM4JR5OiQFo4TssfWnqdcgamGt0AEnk2lvbMZ\nKQdAqNS9lDzYbjMGavEQPTZE35mFXFQXjaooZXq+TIa7hbaq7/idH7cHNbLcPLgj\nfPQA8q+DYvnvhXlmq0LPQZH3Oiixf+SF2vRwrBzT2mqGD2OiOkUmhuPwyqEiiBHt\nfxklRtRU6WfLa1Gcb1PsV0uoBGpV3KybIl/GlwIDAQABAoIBAEQjDduLgOCL6Gem\n0X3hpdnW6/HC/jed/Sa//9jBECq2LYeWAqff64ON40hqOHi0YvvGA/+gEOSI6mWe\nsv5tIxxRz+6+cLybsq+tG96kluCE4TJMHy/nY7orS/YiWbd+4odnEApr+D3fbZ/b\nnZ1fDsHTyn8hkYx6jLmnWsJpIHDp7zxD76y7k2Bbg6DZrCGiVxngiLJk23dvz79W\np03lHLM7XE92aFwXQmhfxHGxrbuoB/9eY4ai5IHp36H4fw0vL6NXdNQAo/bhe0p9\nAYB7y0ZumF8Hg0Z/BmMeEzLy6HrYB+VE8cO93pNjhSyH+p2yDB/BlUyTiRLQAoM0\nVTmOZXECgYEA7NGlzpKNhyQEJihVqt0MW0LhKIO/xbBn+XgYfX6GpqPa/ucnMx5/\nVezpl3gK8IU4wPUhAyXXAHJiqNBcEeyxrw0MXLujDVMJgYaLysCLJdvMVgoY08mS\nK5IQivpbozpf4+0y3mOnA+Sy1kbfxv2X8xiWLODRQW3f3q/xoklwOR8CgYEA1GEe\nfaibOFTQAYcIVj77KXtBfYZsX3EGAyfAN9O7cKHq5oaxVstwnF47WxpuVtoKZxCZ\nbNm9D5WvQ9b+Ztpioe42tzwE7Bff/Osj868GcDdRPK7nFlh9N2yVn/D514dOYVwR\n4MBr1KrJzgRWt4QqS4H+to1GzudDTSNlG7gnK4kCgYBUi6AbOHzoYzZL/RhgcJwp\ntJ23nhmH1Su5h2OO4e3mbhcP66w19sxU+8iFN+kH5zfUw26utgKk+TE5vXExQQRK\nT2k7bg2PAzcgk80ybD0BHhA8I0yrx4m0nmfjhe/TPVLgh10iwgbtP+eM0i6v1vc5\nZWyvxu9N4ZEL6lpkqr0y1wKBgG/NAIQd8jhhTW7Aav8cAJQBsqQl038avJOEpYe+\nCnpsgoAAf/K0/f8TDCQVceh+t+MxtdK7fO9rWOxZjWsPo8Si5mLnUaAHoX4/OpnZ\nlYYVWMqdOEFnK+O1Yb7k2GFBdV2DXlX2dc1qavntBsls5ecB89id3pyk2aUN8Pf6\npYQhAoGAMGtrHFely9wyaxI0RTCyfmJbWZHGVGkv6ELK8wneJjdjl82XOBUGCg5q\naRCrTZ3dPitKwrUa6ibJCIFCIziiriBmjDvTHzkMvoJEap2TVxYNDR6IfINVsQ57\nlOsiC4A2uGq4Lbfld+gjoplJ5GX6qXtTgZ6m7eo0y7U6zm2tkN0=\n-----END RSA PRIVATE KEY-----\n"), + certificate: []byte("-----BEGIN CERTIFICATE-----\nMIIC2zCCAcOgAwIBAgIIAy/jm1gAAdEwDQYJKoZIhvcNAQELBQAwEjEQMA4GA1UE\nChMHWklUQURFTDAeFw0yMzA4MzAwNzExMTVaFw0yNDA4MjkwNzExMTVaMBIxEDAO\nBgNVBAoTB1pJVEFERUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDE\nd3TztGgSb3LBVZn8f60NbFCyZW+F9HPiMCr9F9T45Zc0fgmMwxId0WzRD5Y/3yc1\ndHJzt+Bsxvw12aUHbIPiothqk3lINoFzl2H/cSfIW3nehKyNOUqdBQ8B4mvaqH81\njTjoJ/JTJAwzglHk6JAWjhOyx9aep1yBqYa3QASeTaW9sxkpB0Co1L2UPNhuMwZq\n8RA9NkTfmYVcVBeNqihler5MhruFtqrv+J0ftwc1stw8uCN89ADyr4Ni+e+FeWar\nQs9Bkfc6KLF/5IXa9HCsHNPaaoYPY6I6RSaG4/DKoSKIEe1/GSVG1FTpZ8trUZxv\nU+xXS6gEalXcrJsiX8aXAgMBAAGjNTAzMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUE\nDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQCx\n/dRNIj0N/16zJhZR/ahkc2AkvDXYxyr4JRT5wK9GQDNl/oaX3debRuSi/tfaXFIX\naJA6PxM4J49ZaiEpLrKfxMz5kAhjKchCBEMcH3mGt+iNZH7EOyTvHjpGrP2OZrsh\nO17yrvN3HuQxIU6roJlqtZz2iAADsoPtwOO4D7hupm9XTMkSnAmlMWOo/q46Jz89\n1sMxB+dXmH/zV0wgwh0omZfLV0u89mvdq269VhcjNBpBYSnN1ccqYWd5iwziob3I\nvaavGHGfkbvRUn/tKftYuTK30q03R+e9YbmlWZ0v695owh2e/apCzowQsCKfSVC8\nOxVyt5XkHq1tWwVyBmFp\n-----END CERTIFICATE-----\n"), + metadata: []byte("\n \n \n \n \n MIIFFTCCAv2gAwIBAgIUGdd3KdAmoGLcSBBpGD91vfiwtNAwDQYJKoZIhvcNAQELBQAwGjEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tMB4XDTI0MTAwMjE2MTQ0MVoXDTM0MDkzMDE2MTQ0MVowGjEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlVkeF2COiZAuvuA68ZaanoExvG+xynhEbNB9RgJUltkp6AiMlyhju+fLBzqH635FjNZHgkKoCTfxPW5Rq+iRSm9qyP86QogZsUYnLpyrnmDVJc8l75Flf+3USdIKnVA9mUAKyxUnYBMR/QCsNFcNTkGcFzx/GUGdRq0iWY6cF73o8DJR0c/liJjNL5kpxlKa28DVEgZceFb9w+/16PoNJ51XO4C7eOyEggKOGK9JBC845H8dUpFAs7Vl1Pal+dCUiNm+cwPQQz9ypIBqt1J6uICUiVXJtAhk5QN8yuEpp47T8FV3hcAmj4vERTNCV3JCB0Ft186X2WVe3RDUTKZ4pVkRes8ihP2Waxkphzd1qRBHMTgMDkBP3siraTDjkdtbyfpp25cfq2T8GcZVw4q2ObaiKheOAxRdO1rrOBrMffujMO8SZxRGh12ZqtPqQIDl4IfB65Ktri1po/Mw6s/s+r592BUm7drRq7wSXRcyk9uy1KWKho8n1fwx00M7FvPXPZpEq3kQyQgCI+ZazBCwtZlcSl4EJ5DDkRtrzjx+642kApr+XcKW1V3mp9beQwvXNmtt+krHvshft6JBVea9osJs3r9kKFQg+A1L7mSSg87xqvkCkfttHUFzHqkWTyvhjxZCbw45dzM+6U5hecgy3Xv6sL93ChB5VINipkQ85jECAwEAAaNTMFEwHQYDVR0OBBYEFOJ5SUCf3Kw787313G5AaRk2LnUyMB8GA1UdIwQYMBaAFOJ5SUCf3Kw787313G5AaRk2LnUyMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBADhZUpklgAgNCSPqrKSqfz60R0CNYQI2t6kyKm+QqwCf68HshEiPZefNv+YAmQdE5qZCdWP2PSYXfbk6sfVfQBlfOQiI2C6Du08Y652A7kbYQe4/itJLibxUAuV1T1Rg8dKAjt3GSqVhEuUbbxbTlu8xlM+gmyPM3JLFo1AC+SSZ85PS9S1PsiWoV2rDa+3qOGek0+1ct0fesZo7VwnF/mlWSqvFa0W7lzozDOPj48DPhr+2VRGPX7ZLuuYwxhxihSljMiRBLdlhAS4kK4tgIpacP/iBr3l0GgVaTKE1saL5lPn5vulgzoM8Ar1dGcs6M/fKOAtdWIuc9iizvU0m25kW8WUT+31ouxpXEDqVQjbKsk1aifnqf8OjCKZlFpTSNNV+M6wrDYwvTxF/L//JlfaGozjAmGUMJpOI4kLSt7VrhCx+lCL+4Foz4wZ1/XQOJtpn/nD4VsRtdgVvVG7+P19yGwKAGvVSDZHbd2hGDiRFtevrO+R+Ysq/OijbFy2rCjUvkIwZd0fNWfRjd9kyMlVzlpe9SyOu9nVVcZHceRXBiTq891eTChz/+8sw6Z3yIUjfovafLNisZ6f+Dohb6TwwwBApkCe+iCab4kIXWym54dUBZ4Mjgz7ruoPwAi2lMt5ej7Un8rGNYuklr5CFozQOfh+TNTJDow6hHq3Eo18m\n \n \n \n \n \n \n MIIFFTCCAv2gAwIBAgIUGdd3KdAmoGLcSBBpGD91vfiwtNAwDQYJKoZIhvcNAQELBQAwGjEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tMB4XDTI0MTAwMjE2MTQ0MVoXDTM0MDkzMDE2MTQ0MVowGjEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlVkeF2COiZAuvuA68ZaanoExvG+xynhEbNB9RgJUltkp6AiMlyhju+fLBzqH635FjNZHgkKoCTfxPW5Rq+iRSm9qyP86QogZsUYnLpyrnmDVJc8l75Flf+3USdIKnVA9mUAKyxUnYBMR/QCsNFcNTkGcFzx/GUGdRq0iWY6cF73o8DJR0c/liJjNL5kpxlKa28DVEgZceFb9w+/16PoNJ51XO4C7eOyEggKOGK9JBC845H8dUpFAs7Vl1Pal+dCUiNm+cwPQQz9ypIBqt1J6uICUiVXJtAhk5QN8yuEpp47T8FV3hcAmj4vERTNCV3JCB0Ft186X2WVe3RDUTKZ4pVkRes8ihP2Waxkphzd1qRBHMTgMDkBP3siraTDjkdtbyfpp25cfq2T8GcZVw4q2ObaiKheOAxRdO1rrOBrMffujMO8SZxRGh12ZqtPqQIDl4IfB65Ktri1po/Mw6s/s+r592BUm7drRq7wSXRcyk9uy1KWKho8n1fwx00M7FvPXPZpEq3kQyQgCI+ZazBCwtZlcSl4EJ5DDkRtrzjx+642kApr+XcKW1V3mp9beQwvXNmtt+krHvshft6JBVea9osJs3r9kKFQg+A1L7mSSg87xqvkCkfttHUFzHqkWTyvhjxZCbw45dzM+6U5hecgy3Xv6sL93ChB5VINipkQ85jECAwEAAaNTMFEwHQYDVR0OBBYEFOJ5SUCf3Kw787313G5AaRk2LnUyMB8GA1UdIwQYMBaAFOJ5SUCf3Kw787313G5AaRk2LnUyMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBADhZUpklgAgNCSPqrKSqfz60R0CNYQI2t6kyKm+QqwCf68HshEiPZefNv+YAmQdE5qZCdWP2PSYXfbk6sfVfQBlfOQiI2C6Du08Y652A7kbYQe4/itJLibxUAuV1T1Rg8dKAjt3GSqVhEuUbbxbTlu8xlM+gmyPM3JLFo1AC+SSZ85PS9S1PsiWoV2rDa+3qOGek0+1ct0fesZo7VwnF/mlWSqvFa0W7lzozDOPj48DPhr+2VRGPX7ZLuuYwxhxihSljMiRBLdlhAS4kK4tgIpacP/iBr3l0GgVaTKE1saL5lPn5vulgzoM8Ar1dGcs6M/fKOAtdWIuc9iizvU0m25kW8WUT+31ouxpXEDqVQjbKsk1aifnqf8OjCKZlFpTSNNV+M6wrDYwvTxF/L//JlfaGozjAmGUMJpOI4kLSt7VrhCx+lCL+4Foz4wZ1/XQOJtpn/nD4VsRtdgVvVG7+P19yGwKAGvVSDZHbd2hGDiRFtevrO+R+Ysq/OijbFy2rCjUvkIwZd0fNWfRjd9kyMlVzlpe9SyOu9nVVcZHceRXBiTq891eTChz/+8sw6Z3yIUjfovafLNisZ6f+Dohb6TwwwBApkCe+iCab4kIXWym54dUBZ4Mjgz7ruoPwAi2lMt5ej7Un8rGNYuklr5CFozQOfh+TNTJDow6hHq3Eo18m\n \n \n \n \n \n \n \n urn:oasis:names:tc:SAML:2.0:nameid-format:transient\n \n \n \n"), + options: []ProviderOpts{ + WithLinkingAllowed(), + WithCreationAllowed(), + WithAutoCreation(), + WithAutoUpdate(), + WithBinding(saml.HTTPRedirectBinding), + WithSignedRequest(), + WithCustomRequestTracker(&requesttracker.RequestTracker{}), + WithTransientMappingAttributeName("urn:oid:1.3.6.1.4.1.5923.1.1.1.6"), + }, + rootURL: "http://localhost:8080/idps/228968792372281708/", + timeNow: func() time.Time { + return time.Date(2025, 9, 21, 13, 47, 40, 0, time.UTC) + }, + }, + args: args{ + request: httpPostFormRequest(t, + "http://localhost:8080/idps/228968792372281708/saml/acs", + "232881438356144492", + "PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzYW1scDpSZXNwb25zZSB4bWxuczpzYW1sPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiB4bWxuczpzYW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIElEPSJwZng0M2UzZjA2YS1lMWU3LWQ5NjctOTZhNi1mY2EyODg5NmM5YjkiIEluUmVzcG9uc2VUbz0iaWQtYjIyYzkwZGI4OGJmMDFkODJmZmIwYTdiNmZlMjVhYzlmY2IyYzY3OSIgVmVyc2lvbj0iMi4wIiBJc3N1ZUluc3RhbnQ9IjIwMjUtMDktMjFUMTM6NDk6MjMuOTM4WiIgRGVzdGluYXRpb249Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9pZHBzLzIyODk2ODc5MjM3MjI4MTcwOC9zYW1sL2FjcyI+PHNhbWw6SXNzdWVyIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6ZW50aXR5Ij5odHRwOi8vbG9jYWxob3N0OjgwMDAvbWV0YWRhdGE8L3NhbWw6SXNzdWVyPjxkczpTaWduYXR1cmUgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPgogIDxkczpTaWduZWRJbmZvPjxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+CiAgICA8ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3JzYS1zaGExIi8+CiAgPGRzOlJlZmVyZW5jZSBVUkk9IiNwZng0M2UzZjA2YS1lMWU3LWQ5NjctOTZhNi1mY2EyODg5NmM5YjkiPjxkczpUcmFuc2Zvcm1zPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48L2RzOlRyYW5zZm9ybXM+PGRzOkRpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNzaGExIi8+PGRzOkRpZ2VzdFZhbHVlPmRTb2M2VmUvbGFrdmM5cUVrYTlLZlo3ekJxWT08L2RzOkRpZ2VzdFZhbHVlPjwvZHM6UmVmZXJlbmNlPjwvZHM6U2lnbmVkSW5mbz48ZHM6U2lnbmF0dXJlVmFsdWU+VWdrdklwVSsreFZPRjlFNG1rZ1hkNUIvRUdmVkc4eEFFd0hPS3BjZDQzQ0dhV3FoTTBGVTZEQ1FyOE5wcC84dENpaHVvWENMMnNGRjZydy9DUmRGUEpFWUhqdldSVm9ESTVwdGRnRDZlZXVqRnN4bzRzTWU5aW83cHhvYVd6STFRWUFSM3oxUER6bDNvaTRnWG9oVXhsSEovTldaRzV1VkdSMnd6dXdLdjA4Uit6U2liOHhiZ3dsUUZiTEdNTzFNZVdJL1pxV0x6UURvY0hxZWxjbG9SL1V4cWsxMnRJU3B2Y25tTEpROVNid1JnYmtrZWZsQng5NzZIUVdURFEyS2M4b1lqZjVZSzlYbDdJVFFFQzE1UFYvZ3hMQXNTU2x0VDlJKzh1YXI1L2lKZlV1eWhVbG5KR0oxd3dSRW9XVXh3aEM0ckhjSFF1K05qUjM0akMvdlRWU1JZSkZNVVpieHp0MXdJVGpsdkxveGlMTktzeG9MbDFhcHArMHk1ZjVlcWJvRGtxTnFCcTdEQ3NjTXk0WTQ2aWdWdWt1Vk1YM21HLzdZeFJCS3lPcTZKQjc0TFVvb0Y3U3oxQTBuU3U4ekNKQ0JJTWVUNXdGdURXYlNaOUw2NC9qbFJYRFpOWEtlMGx6bkRaU2h6UllZdC9EUjFMWTNyQ3BwNTdzT0tVWDJSVzdJYld0Mmp2bDdHc1VELzBUVEZncHZ1M29UMENrRTRSSnhFVDluQnpYRkNtckY4VzVjWE9zWThrSEpZOGJtYk1IbUlNNVRuWkM0QVZaaUd3aGdEKzZBUWpnc3piVnh4amlvRWt6Q1Q1SndKR2NZUEtsQ2I2QWtjY2pRcnpUeUJLZzdaSzBEUEdVbFcrSDYxMGREN3hpM1A0Qit5MlBqRitmMkhqRi9kaUE9PC9kczpTaWduYXR1cmVWYWx1ZT4KPGRzOktleUluZm8+PGRzOlg1MDlEYXRhPjxkczpYNTA5Q2VydGlmaWNhdGU+TUlJRkZUQ0NBdjJnQXdJQkFnSVVHZGQzS2RBbW9HTGNTQkJwR0Q5MXZmaXd0TkF3RFFZSktvWklodmNOQVFFTEJRQXdHakVZTUJZR0ExVUVBd3dQZDNkM0xtVjRZVzF3YkdVdVkyOXRNQjRYRFRJME1UQXdNakUyTVRRME1Wb1hEVE0wTURrek1ERTJNVFEwTVZvd0dqRVlNQllHQTFVRUF3d1BkM2QzTG1WNFlXMXdiR1V1WTI5dE1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBbFZrZUYyQ09pWkF1dnVBNjhaYWFub0V4dkcreHluaEViTkI5UmdKVWx0a3A2QWlNbHloanUrZkxCenFINjM1RmpOWkhna0tvQ1RmeFBXNVJxK2lSU205cXlQODZRb2dac1VZbkxweXJubURWSmM4bDc1RmxmKzNVU2RJS25WQTltVUFLeXhVbllCTVIvUUNzTkZjTlRrR2NGengvR1VHZFJxMGlXWTZjRjczbzhESlIwYy9saUpqTkw1a3B4bEthMjhEVkVnWmNlRmI5dysvMTZQb05KNTFYTzRDN2VPeUVnZ0tPR0s5SkJDODQ1SDhkVXBGQXM3VmwxUGFsK2RDVWlObStjd1BRUXo5eXBJQnF0MUo2dUlDVWlWWEp0QWhrNVFOOHl1RXBwNDdUOEZWM2hjQW1qNHZFUlROQ1YzSkNCMEZ0MTg2WDJXVmUzUkRVVEtaNHBWa1JlczhpaFAyV2F4a3BoemQxcVJCSE1UZ01Ea0JQM3NpcmFURGprZHRieWZwcDI1Y2ZxMlQ4R2NaVnc0cTJPYmFpS2hlT0F4UmRPMXJyT0JyTWZmdWpNTzhTWnhSR2gxMlpxdFBxUUlEbDRJZkI2NUt0cmkxcG8vTXc2cy9zK3I1OTJCVW03ZHJScTd3U1hSY3lrOXV5MUtXS2hvOG4xZnd4MDBNN0Z2UFhQWnBFcTNrUXlRZ0NJK1phekJDd3RabGNTbDRFSjVERGtSdHJ6angrNjQya0FwcitYY0tXMVYzbXA5YmVRd3ZYTm10dCtrckh2c2hmdDZKQlZlYTlvc0pzM3I5a0tGUWcrQTFMN21TU2c4N3hxdmtDa2Z0dEhVRnpIcWtXVHl2aGp4WkNidzQ1ZHpNKzZVNWhlY2d5M1h2NnNMOTNDaEI1VklOaXBrUTg1akVDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRk9KNVNVQ2YzS3c3ODczMTNHNUFhUmsyTG5VeU1COEdBMVVkSXdRWU1CYUFGT0o1U1VDZjNLdzc4NzMxM0c1QWFSazJMblV5TUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFTEJRQURnZ0lCQURoWlVwa2xnQWdOQ1NQcXJLU3FmejYwUjBDTllRSTJ0Nmt5S20rUXF3Q2Y2OEhzaEVpUFplZk52K1lBbVFkRTVxWkNkV1AyUFNZWGZiazZzZlZmUUJsZk9RaUkyQzZEdTA4WTY1MkE3a2JZUWU0L2l0SkxpYnhVQXVWMVQxUmc4ZEtBanQzR1NxVmhFdVViYnhiVGx1OHhsTStnbXlQTTNKTEZvMUFDK1NTWjg1UFM5UzFQc2lXb1YyckRhKzNxT0dlazArMWN0MGZlc1pvN1Z3bkYvbWxXU3F2RmEwVzdsem96RE9QajQ4RFBocisyVlJHUFg3Wkx1dVl3eGh4aWhTbGpNaVJCTGRsaEFTNGtLNHRnSXBhY1AvaUJyM2wwR2dWYVRLRTFzYUw1bFBuNXZ1bGd6b004QXIxZEdjczZNL2ZLT0F0ZFdJdWM5aWl6dlUwbTI1a1c4V1VUKzMxb3V4cFhFRHFWUWpiS3NrMWFpZm5xZjhPakNLWmxGcFRTTk5WK002d3JEWXd2VHhGL0wvL0psZmFHb3pqQW1HVU1KcE9JNGtMU3Q3VnJoQ3grbENMKzRGb3o0d1oxL1hRT0p0cG4vbkQ0VnNSdGRnVnZWRzcrUDE5eUd3S0FHdlZTRFpIYmQyaEdEaVJGdGV2ck8rUitZc3EvT2lqYkZ5MnJDalV2a0l3WmQwZk5XZlJqZDlreU1sVnpscGU5U3lPdTluVlZjWkhjZVJYQmlUcTg5MWVUQ2h6Lys4c3c2WjN5SVVqZm92YWZMTmlzWjZmK0RvaGI2VHd3d0JBcGtDZStpQ2FiNGtJWFd5bTU0ZFVCWjRNamd6N3J1b1B3QWkybE10NWVqN1VuOHJHTll1a2xyNUNGb3pRT2ZoK1ROVEpEb3c2aEhxM0VvMThtPC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+PHNhbWxwOlN0YXR1cz48c2FtbHA6U3RhdHVzQ29kZSBWYWx1ZT0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnN0YXR1czpTdWNjZXNzIi8+PC9zYW1scDpTdGF0dXM+PHNhbWw6QXNzZXJ0aW9uIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIElEPSJwZng5NGJjNjJjOS1kZDQ1LWYxNGEtOGFlNS1mNWIwZGM2ZTQ4OTciIElzc3VlSW5zdGFudD0iMjAyNS0wOS0yMVQxMzo0OToyMy45NDFaIiBWZXJzaW9uPSIyLjAiPjxzYW1sOklzc3VlciBGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpuYW1laWQtZm9ybWF0OmVudGl0eSI+aHR0cDovL2xvY2FsaG9zdDo4MDAwL21ldGFkYXRhPC9zYW1sOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4KICA8ZHM6U2lnbmVkSW5mbz48ZHM6Q2Fub25pY2FsaXphdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPgogICAgPGRzOlNpZ25hdHVyZU1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNyc2Etc2hhMSIvPgogIDxkczpSZWZlcmVuY2UgVVJJPSIjcGZ4OTRiYzYyYzktZGQ0NS1mMTRhLThhZTUtZjViMGRjNmU0ODk3Ij48ZHM6VHJhbnNmb3Jtcz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIvPjxkczpEaWdlc3RWYWx1ZT55eW94RlJ4OUt5SEZoTkM0cDN4SmEvVDI0Q2M9PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8+PGRzOlNpZ25hdHVyZVZhbHVlPkVVOUJKOVdHSnVjKzVINko2a2I2STRFU0ZidlEyQ3kxbnFtanFyTWgxL0NTdU1xODBDek1QSDlaN1l2TUlMeFpKUlZFaVZqRGxQSXFwYnpHUFhKQlJYMkQ5TnI2SXduM3RBa0VtcW9WVXRmdmJ0dUhwV05DdENhcE5BM3NCalB6WEFFZnEzZElIWnBVSE5Nd1R4WGZkTEtTOXZXd1pNNUtLL1htQWlYNnpnTmgydW9FMitZZTgvUHViMFg1NFVIaUcyeUdhYlhpbEV5VUlqWE1FV0pZS1BySU9tMlR5TXZDeENvSndJOUYwYWIxOGdJVkVBL0szVG8xc2Z4Q3pWZ0FJZFgxbzM3enQzdnYvcVJwQkxka3JZdTg3OVpXZVBxenVHT2RTbWFLdkRUd01mWFJYYWhicFhScTloQ3pSaXBzaHg3blc2dExwYUFFNlhBYkJjS1Rndkg3SlBET240ajhpclJOVmtpTEhRM2cvaGlDVWhBUHh2S1NyaURNWEJ5UUszeHBlbTRZUGZVaWRuSU04cmtxUU1UVjYySGpDMjZFV0pDZm5taHBoNUNBNDBPQ0lIbEZzMVZMOXBoQTdaeUZqa0s5Q3FqRkpjR21qQ3JUMDFvK0I2UDYzdmFQeDBrOTBtVjd5MFB2MDdxQmo3UVluNVZMMzRvOUptbU5XWDk0azFFNDdZWGtyUG1IOS9idy9BWGpKTXI0SDAzSXVvRmU3S3ROOTdRL1NwTlhMOVAxaFlEcEk0QjEvRUxISGhUSXR6REpXZk0wU3Z3MndBM1U4VVV6UHBqeWlJajJKT3pCeDhWUFdHSWMvWHZhNkU4V3BKUmMyaFNkbGtVS3grTTNHeGxJeExPNE5jQWZzZGs4aXR0NDNOd2I4bWc2WFRrTVZLdVBhY0xxeVJ3PTwvZHM6U2lnbmF0dXJlVmFsdWU+CjxkczpLZXlJbmZvPjxkczpYNTA5RGF0YT48ZHM6WDUwOUNlcnRpZmljYXRlPk1JSUZGVENDQXYyZ0F3SUJBZ0lVR2RkM0tkQW1vR0xjU0JCcEdEOTF2Zml3dE5Bd0RRWUpLb1pJaHZjTkFRRUxCUUF3R2pFWU1CWUdBMVVFQXd3UGQzZDNMbVY0WVcxd2JHVXVZMjl0TUI0WERUSTBNVEF3TWpFMk1UUTBNVm9YRFRNME1Ea3pNREUyTVRRME1Wb3dHakVZTUJZR0ExVUVBd3dQZDNkM0xtVjRZVzF3YkdVdVkyOXRNSUlDSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQWc4QU1JSUNDZ0tDQWdFQWxWa2VGMkNPaVpBdXZ1QTY4WmFhbm9FeHZHK3h5bmhFYk5COVJnSlVsdGtwNkFpTWx5aGp1K2ZMQnpxSDYzNUZqTlpIZ2tLb0NUZnhQVzVScStpUlNtOXF5UDg2UW9nWnNVWW5McHlybm1EVkpjOGw3NUZsZiszVVNkSUtuVkE5bVVBS3l4VW5ZQk1SL1FDc05GY05Ua0djRnp4L0dVR2RScTBpV1k2Y0Y3M284REpSMGMvbGlKak5MNWtweGxLYTI4RFZFZ1pjZUZiOXcrLzE2UG9OSjUxWE80QzdlT3lFZ2dLT0dLOUpCQzg0NUg4ZFVwRkFzN1ZsMVBhbCtkQ1VpTm0rY3dQUVF6OXlwSUJxdDFKNnVJQ1VpVlhKdEFoazVRTjh5dUVwcDQ3VDhGVjNoY0FtajR2RVJUTkNWM0pDQjBGdDE4NlgyV1ZlM1JEVVRLWjRwVmtSZXM4aWhQMldheGtwaHpkMXFSQkhNVGdNRGtCUDNzaXJhVERqa2R0YnlmcHAyNWNmcTJUOEdjWlZ3NHEyT2JhaUtoZU9BeFJkTzFyck9Cck1mZnVqTU84U1p4UkdoMTJacXRQcVFJRGw0SWZCNjVLdHJpMXBvL013NnMvcytyNTkyQlVtN2RyUnE3d1NYUmN5azl1eTFLV0tobzhuMWZ3eDAwTTdGdlBYUFpwRXEza1F5UWdDSStaYXpCQ3d0WmxjU2w0RUo1RERrUnRyemp4KzY0MmtBcHIrWGNLVzFWM21wOWJlUXd2WE5tdHQra3JIdnNoZnQ2SkJWZWE5b3NKczNyOWtLRlFnK0ExTDdtU1NnODd4cXZrQ2tmdHRIVUZ6SHFrV1R5dmhqeFpDYnc0NWR6TSs2VTVoZWNneTNYdjZzTDkzQ2hCNVZJTmlwa1E4NWpFQ0F3RUFBYU5UTUZFd0hRWURWUjBPQkJZRUZPSjVTVUNmM0t3Nzg3MzEzRzVBYVJrMkxuVXlNQjhHQTFVZEl3UVlNQmFBRk9KNVNVQ2YzS3c3ODczMTNHNUFhUmsyTG5VeU1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dJQkFEaFpVcGtsZ0FnTkNTUHFyS1NxZno2MFIwQ05ZUUkydDZreUttK1Fxd0NmNjhIc2hFaVBaZWZOditZQW1RZEU1cVpDZFdQMlBTWVhmYms2c2ZWZlFCbGZPUWlJMkM2RHUwOFk2NTJBN2tiWVFlNC9pdEpMaWJ4VUF1VjFUMVJnOGRLQWp0M0dTcVZoRXVVYmJ4YlRsdTh4bE0rZ215UE0zSkxGbzFBQytTU1o4NVBTOVMxUHNpV29WMnJEYSszcU9HZWswKzFjdDBmZXNabzdWd25GL21sV1NxdkZhMFc3bHpvekRPUGo0OERQaHIrMlZSR1BYN1pMdXVZd3hoeGloU2xqTWlSQkxkbGhBUzRrSzR0Z0lwYWNQL2lCcjNsMEdnVmFUS0Uxc2FMNWxQbjV2dWxnem9NOEFyMWRHY3M2TS9mS09BdGRXSXVjOWlpenZVMG0yNWtXOFdVVCszMW91eHBYRURxVlFqYktzazFhaWZucWY4T2pDS1psRnBUU05OVitNNndyRFl3dlR4Ri9MLy9KbGZhR296akFtR1VNSnBPSTRrTFN0N1ZyaEN4K2xDTCs0Rm96NHdaMS9YUU9KdHBuL25ENFZzUnRkZ1Z2Vkc3K1AxOXlHd0tBR3ZWU0RaSGJkMmhHRGlSRnRldnJPK1IrWXNxL09pamJGeTJyQ2pVdmtJd1pkMGZOV2ZSamQ5a3lNbFZ6bHBlOVN5T3U5blZWY1pIY2VSWEJpVHE4OTFlVENoei8rOHN3NlozeUlVamZvdmFmTE5pc1o2ZitEb2hiNlR3d3dCQXBrQ2UraUNhYjRrSVhXeW01NGRVQlo0TWpnejdydW9Qd0FpMmxNdDVlajdVbjhyR05ZdWtscjVDRm96UU9maCtUTlRKRG93NmhIcTNFbzE4bTwvZHM6WDUwOUNlcnRpZmljYXRlPjwvZHM6WDUwOURhdGE+PC9kczpLZXlJbmZvPjwvZHM6U2lnbmF0dXJlPjxzYW1sOlN1YmplY3Q+PHNhbWw6U3ViamVjdENvbmZpcm1hdGlvbiBNZXRob2Q9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpjbTpiZWFyZXIiPjxzYW1sOlN1YmplY3RDb25maXJtYXRpb25EYXRhIEFkZHJlc3M9Ils6OjFdOjU5MzM0IiBJblJlc3BvbnNlVG89ImlkLWIyMmM5MGRiODhiZjAxZDgyZmZiMGE3YjZmZTI1YWM5ZmNiMmM2NzkiIE5vdE9uT3JBZnRlcj0iMjAyNS0wOS0yMVQxMzo1MDo1My45MzhaIiBSZWNpcGllbnQ9Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9pZHBzLzIyODk2ODc5MjM3MjI4MTcwOC9zYW1sL2FjcyIvPjwvc2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uPjwvc2FtbDpTdWJqZWN0PjxzYW1sOkNvbmRpdGlvbnMgTm90QmVmb3JlPSIyMDI1LTA5LTIxVDEzOjQ5OjE0LjI5OFoiIE5vdE9uT3JBZnRlcj0iMjAyNS0wOS0yMVQxMzo1MDo0NC4yOThaIj48c2FtbDpBdWRpZW5jZVJlc3RyaWN0aW9uPjxzYW1sOkF1ZGllbmNlPmh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9pZHBzLzIyODk2ODc5MjM3MjI4MTcwOC9zYW1sL21ldGFkYXRhPC9zYW1sOkF1ZGllbmNlPjwvc2FtbDpBdWRpZW5jZVJlc3RyaWN0aW9uPjwvc2FtbDpDb25kaXRpb25zPjxzYW1sOkF1dGhuU3RhdGVtZW50IEF1dGhuSW5zdGFudD0iMjAyNS0wOS0yMVQxMzo0NzozNS4xMDNaIiBTZXNzaW9uSW5kZXg9IjRjMzliMTk1NDJjN2NlMWMzOWU5YzA1YmUxN2E3MmE2ZDg4ZTU1YTdkYWJhZGFlZDc4NjEwMGI5ZTM4MGZhMDgiPjxzYW1sOlN1YmplY3RMb2NhbGl0eSBBZGRyZXNzPSJbOjoxXTo1OTMzNCIvPjxzYW1sOkF1dGhuQ29udGV4dD48c2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj51cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YWM6Y2xhc3NlczpQYXNzd29yZFByb3RlY3RlZFRyYW5zcG9ydDwvc2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj48L3NhbWw6QXV0aG5Db250ZXh0Pjwvc2FtbDpBdXRoblN0YXRlbWVudD48c2FtbDpBdHRyaWJ1dGVTdGF0ZW1lbnQ+PHNhbWw6QXR0cmlidXRlIEZyaWVuZGx5TmFtZT0idWlkIiBOYW1lPSJ1cm46b2lkOjAuOS4yMzQyLjE5MjAwMzAwLjEwMC4xLjEiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6dXJpIj48c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5hbGljZTwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT48L3NhbWw6QXR0cmlidXRlPjxzYW1sOkF0dHJpYnV0ZSBGcmllbmRseU5hbWU9ImVkdVBlcnNvblByaW5jaXBhbE5hbWUiIE5hbWU9InVybjpvaWQ6MS4zLjYuMS40LjEuNTkyMy4xLjEuMS42IiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OnVyaSI+PHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnR5cGU9InhzOnN0cmluZyI+YWxpY2VAZXhhbXBsZS5jb208L3NhbWw6QXR0cmlidXRlVmFsdWU+PC9zYW1sOkF0dHJpYnV0ZT48c2FtbDpBdHRyaWJ1dGUgRnJpZW5kbHlOYW1lPSJzbiIgTmFtZT0idXJuOm9pZDoyLjUuNC40IiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OnVyaSI+PHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnR5cGU9InhzOnN0cmluZyI+U21pdGg8L3NhbWw6QXR0cmlidXRlVmFsdWU+PC9zYW1sOkF0dHJpYnV0ZT48c2FtbDpBdHRyaWJ1dGUgRnJpZW5kbHlOYW1lPSJnaXZlbk5hbWUiIE5hbWU9InVybjpvaWQ6Mi41LjQuNDIiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6dXJpIj48c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5BbGljZTwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT48L3NhbWw6QXR0cmlidXRlPjxzYW1sOkF0dHJpYnV0ZSBGcmllbmRseU5hbWU9ImNuIiBOYW1lPSJ1cm46b2lkOjIuNS40LjMiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6dXJpIj48c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5BbGljZSBTbWl0aDwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT48L3NhbWw6QXR0cmlidXRlPjxzYW1sOkF0dHJpYnV0ZSBGcmllbmRseU5hbWU9ImVkdVBlcnNvbkFmZmlsaWF0aW9uIiBOYW1lPSJ1cm46b2lkOjEuMy42LjEuNC4xLjU5MjMuMS4xLjEuMSIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDp1cmkiPjxzYW1sOkF0dHJpYnV0ZVZhbHVlIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPkFkbWluaXN0cmF0b3JzPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPjxzYW1sOkF0dHJpYnV0ZVZhbHVlIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPlVzZXJzPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPjwvc2FtbDpBdHRyaWJ1dGU+PC9zYW1sOkF0dHJpYnV0ZVN0YXRlbWVudD48L3NhbWw6QXNzZXJ0aW9uPjwvc2FtbHA6UmVzcG9uc2U+", + ), + requestID: "id-b22c90db88bf01d82ffb0a7b6fe25ac9fcb2c679", + }, + want: want{ + id: "alice@example.com", + attributes: map[string][]string{ + "urn:oid:0.9.2342.19200300.100.1.1": {"alice"}, + "urn:oid:1.3.6.1.4.1.5923.1.1.1.6": {"alice@example.com"}, + "urn:oid:2.5.4.4": {"Smith"}, + "urn:oid:2.5.4.42": {"Alice"}, + "urn:oid:2.5.4.3": {"Alice Smith"}, + "urn:oid:1.3.6.1.4.1.5923.1.1.1.1": {"Administrators", "Users"}, + }, + }, + }, + { + name: "missing nameID and custom transient mapping attribute config is not set", fields: fields{ name: "saml", key: []byte("-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEAxHd087RoEm9ywVWZ/H+tDWxQsmVvhfRz4jAq/RfU+OWXNH4J\njMMSHdFs0Q+WP98nNXRyc7fgbMb8NdmlB2yD4qLYapN5SDaBc5dh/3EnyFt53oSs\njTlKnQUPAeJr2qh/NY046CfyUyQMM4JR5OiQFo4TssfWnqdcgamGt0AEnk2lvbMZ\nKQdAqNS9lDzYbjMGavEQPTZE35mFXFQXjaooZXq+TIa7hbaq7/idH7cHNbLcPLgj\nfPQA8q+DYvnvhXlmq0LPQZH3Oiixf+SF2vRwrBzT2mqGD2OiOkUmhuPwyqEiiBHt\nfxklRtRU6WfLa1Gcb1PsV0uoBGpV3KybIl/GlwIDAQABAoIBAEQjDduLgOCL6Gem\n0X3hpdnW6/HC/jed/Sa//9jBECq2LYeWAqff64ON40hqOHi0YvvGA/+gEOSI6mWe\nsv5tIxxRz+6+cLybsq+tG96kluCE4TJMHy/nY7orS/YiWbd+4odnEApr+D3fbZ/b\nnZ1fDsHTyn8hkYx6jLmnWsJpIHDp7zxD76y7k2Bbg6DZrCGiVxngiLJk23dvz79W\np03lHLM7XE92aFwXQmhfxHGxrbuoB/9eY4ai5IHp36H4fw0vL6NXdNQAo/bhe0p9\nAYB7y0ZumF8Hg0Z/BmMeEzLy6HrYB+VE8cO93pNjhSyH+p2yDB/BlUyTiRLQAoM0\nVTmOZXECgYEA7NGlzpKNhyQEJihVqt0MW0LhKIO/xbBn+XgYfX6GpqPa/ucnMx5/\nVezpl3gK8IU4wPUhAyXXAHJiqNBcEeyxrw0MXLujDVMJgYaLysCLJdvMVgoY08mS\nK5IQivpbozpf4+0y3mOnA+Sy1kbfxv2X8xiWLODRQW3f3q/xoklwOR8CgYEA1GEe\nfaibOFTQAYcIVj77KXtBfYZsX3EGAyfAN9O7cKHq5oaxVstwnF47WxpuVtoKZxCZ\nbNm9D5WvQ9b+Ztpioe42tzwE7Bff/Osj868GcDdRPK7nFlh9N2yVn/D514dOYVwR\n4MBr1KrJzgRWt4QqS4H+to1GzudDTSNlG7gnK4kCgYBUi6AbOHzoYzZL/RhgcJwp\ntJ23nhmH1Su5h2OO4e3mbhcP66w19sxU+8iFN+kH5zfUw26utgKk+TE5vXExQQRK\nT2k7bg2PAzcgk80ybD0BHhA8I0yrx4m0nmfjhe/TPVLgh10iwgbtP+eM0i6v1vc5\nZWyvxu9N4ZEL6lpkqr0y1wKBgG/NAIQd8jhhTW7Aav8cAJQBsqQl038avJOEpYe+\nCnpsgoAAf/K0/f8TDCQVceh+t+MxtdK7fO9rWOxZjWsPo8Si5mLnUaAHoX4/OpnZ\nlYYVWMqdOEFnK+O1Yb7k2GFBdV2DXlX2dc1qavntBsls5ecB89id3pyk2aUN8Pf6\npYQhAoGAMGtrHFely9wyaxI0RTCyfmJbWZHGVGkv6ELK8wneJjdjl82XOBUGCg5q\naRCrTZ3dPitKwrUa6ibJCIFCIziiriBmjDvTHzkMvoJEap2TVxYNDR6IfINVsQ57\nlOsiC4A2uGq4Lbfld+gjoplJ5GX6qXtTgZ6m7eo0y7U6zm2tkN0=\n-----END RSA PRIVATE KEY-----\n"), @@ -167,7 +209,41 @@ func TestSession_FetchUser(t *testing.T) { requestID: "id-b22c90db88bf01d82ffb0a7b6fe25ac9fcb2c679", }, want: want{ - err: zerrors.ThrowInvalidArgument(nil, "SAML-EFG32", "Errors.Intent.ResponseInvalid"), + err: zerrors.ThrowInvalidArgument(nil, "SAML-EFG32", "Errors.Intent.MissingTransientMappingAttributeName"), + }, + }, + { + name: "missing nameID and missing custom transient mapping attribute in the response", + fields: fields{ + name: "saml", + key: []byte("-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEAxHd087RoEm9ywVWZ/H+tDWxQsmVvhfRz4jAq/RfU+OWXNH4J\njMMSHdFs0Q+WP98nNXRyc7fgbMb8NdmlB2yD4qLYapN5SDaBc5dh/3EnyFt53oSs\njTlKnQUPAeJr2qh/NY046CfyUyQMM4JR5OiQFo4TssfWnqdcgamGt0AEnk2lvbMZ\nKQdAqNS9lDzYbjMGavEQPTZE35mFXFQXjaooZXq+TIa7hbaq7/idH7cHNbLcPLgj\nfPQA8q+DYvnvhXlmq0LPQZH3Oiixf+SF2vRwrBzT2mqGD2OiOkUmhuPwyqEiiBHt\nfxklRtRU6WfLa1Gcb1PsV0uoBGpV3KybIl/GlwIDAQABAoIBAEQjDduLgOCL6Gem\n0X3hpdnW6/HC/jed/Sa//9jBECq2LYeWAqff64ON40hqOHi0YvvGA/+gEOSI6mWe\nsv5tIxxRz+6+cLybsq+tG96kluCE4TJMHy/nY7orS/YiWbd+4odnEApr+D3fbZ/b\nnZ1fDsHTyn8hkYx6jLmnWsJpIHDp7zxD76y7k2Bbg6DZrCGiVxngiLJk23dvz79W\np03lHLM7XE92aFwXQmhfxHGxrbuoB/9eY4ai5IHp36H4fw0vL6NXdNQAo/bhe0p9\nAYB7y0ZumF8Hg0Z/BmMeEzLy6HrYB+VE8cO93pNjhSyH+p2yDB/BlUyTiRLQAoM0\nVTmOZXECgYEA7NGlzpKNhyQEJihVqt0MW0LhKIO/xbBn+XgYfX6GpqPa/ucnMx5/\nVezpl3gK8IU4wPUhAyXXAHJiqNBcEeyxrw0MXLujDVMJgYaLysCLJdvMVgoY08mS\nK5IQivpbozpf4+0y3mOnA+Sy1kbfxv2X8xiWLODRQW3f3q/xoklwOR8CgYEA1GEe\nfaibOFTQAYcIVj77KXtBfYZsX3EGAyfAN9O7cKHq5oaxVstwnF47WxpuVtoKZxCZ\nbNm9D5WvQ9b+Ztpioe42tzwE7Bff/Osj868GcDdRPK7nFlh9N2yVn/D514dOYVwR\n4MBr1KrJzgRWt4QqS4H+to1GzudDTSNlG7gnK4kCgYBUi6AbOHzoYzZL/RhgcJwp\ntJ23nhmH1Su5h2OO4e3mbhcP66w19sxU+8iFN+kH5zfUw26utgKk+TE5vXExQQRK\nT2k7bg2PAzcgk80ybD0BHhA8I0yrx4m0nmfjhe/TPVLgh10iwgbtP+eM0i6v1vc5\nZWyvxu9N4ZEL6lpkqr0y1wKBgG/NAIQd8jhhTW7Aav8cAJQBsqQl038avJOEpYe+\nCnpsgoAAf/K0/f8TDCQVceh+t+MxtdK7fO9rWOxZjWsPo8Si5mLnUaAHoX4/OpnZ\nlYYVWMqdOEFnK+O1Yb7k2GFBdV2DXlX2dc1qavntBsls5ecB89id3pyk2aUN8Pf6\npYQhAoGAMGtrHFely9wyaxI0RTCyfmJbWZHGVGkv6ELK8wneJjdjl82XOBUGCg5q\naRCrTZ3dPitKwrUa6ibJCIFCIziiriBmjDvTHzkMvoJEap2TVxYNDR6IfINVsQ57\nlOsiC4A2uGq4Lbfld+gjoplJ5GX6qXtTgZ6m7eo0y7U6zm2tkN0=\n-----END RSA PRIVATE KEY-----\n"), + certificate: []byte("-----BEGIN CERTIFICATE-----\nMIIC2zCCAcOgAwIBAgIIAy/jm1gAAdEwDQYJKoZIhvcNAQELBQAwEjEQMA4GA1UE\nChMHWklUQURFTDAeFw0yMzA4MzAwNzExMTVaFw0yNDA4MjkwNzExMTVaMBIxEDAO\nBgNVBAoTB1pJVEFERUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDE\nd3TztGgSb3LBVZn8f60NbFCyZW+F9HPiMCr9F9T45Zc0fgmMwxId0WzRD5Y/3yc1\ndHJzt+Bsxvw12aUHbIPiothqk3lINoFzl2H/cSfIW3nehKyNOUqdBQ8B4mvaqH81\njTjoJ/JTJAwzglHk6JAWjhOyx9aep1yBqYa3QASeTaW9sxkpB0Co1L2UPNhuMwZq\n8RA9NkTfmYVcVBeNqihler5MhruFtqrv+J0ftwc1stw8uCN89ADyr4Ni+e+FeWar\nQs9Bkfc6KLF/5IXa9HCsHNPaaoYPY6I6RSaG4/DKoSKIEe1/GSVG1FTpZ8trUZxv\nU+xXS6gEalXcrJsiX8aXAgMBAAGjNTAzMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUE\nDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQCx\n/dRNIj0N/16zJhZR/ahkc2AkvDXYxyr4JRT5wK9GQDNl/oaX3debRuSi/tfaXFIX\naJA6PxM4J49ZaiEpLrKfxMz5kAhjKchCBEMcH3mGt+iNZH7EOyTvHjpGrP2OZrsh\nO17yrvN3HuQxIU6roJlqtZz2iAADsoPtwOO4D7hupm9XTMkSnAmlMWOo/q46Jz89\n1sMxB+dXmH/zV0wgwh0omZfLV0u89mvdq269VhcjNBpBYSnN1ccqYWd5iwziob3I\nvaavGHGfkbvRUn/tKftYuTK30q03R+e9YbmlWZ0v695owh2e/apCzowQsCKfSVC8\nOxVyt5XkHq1tWwVyBmFp\n-----END CERTIFICATE-----\n"), + metadata: []byte("\n \n \n \n \n MIIFFTCCAv2gAwIBAgIUGdd3KdAmoGLcSBBpGD91vfiwtNAwDQYJKoZIhvcNAQELBQAwGjEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tMB4XDTI0MTAwMjE2MTQ0MVoXDTM0MDkzMDE2MTQ0MVowGjEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlVkeF2COiZAuvuA68ZaanoExvG+xynhEbNB9RgJUltkp6AiMlyhju+fLBzqH635FjNZHgkKoCTfxPW5Rq+iRSm9qyP86QogZsUYnLpyrnmDVJc8l75Flf+3USdIKnVA9mUAKyxUnYBMR/QCsNFcNTkGcFzx/GUGdRq0iWY6cF73o8DJR0c/liJjNL5kpxlKa28DVEgZceFb9w+/16PoNJ51XO4C7eOyEggKOGK9JBC845H8dUpFAs7Vl1Pal+dCUiNm+cwPQQz9ypIBqt1J6uICUiVXJtAhk5QN8yuEpp47T8FV3hcAmj4vERTNCV3JCB0Ft186X2WVe3RDUTKZ4pVkRes8ihP2Waxkphzd1qRBHMTgMDkBP3siraTDjkdtbyfpp25cfq2T8GcZVw4q2ObaiKheOAxRdO1rrOBrMffujMO8SZxRGh12ZqtPqQIDl4IfB65Ktri1po/Mw6s/s+r592BUm7drRq7wSXRcyk9uy1KWKho8n1fwx00M7FvPXPZpEq3kQyQgCI+ZazBCwtZlcSl4EJ5DDkRtrzjx+642kApr+XcKW1V3mp9beQwvXNmtt+krHvshft6JBVea9osJs3r9kKFQg+A1L7mSSg87xqvkCkfttHUFzHqkWTyvhjxZCbw45dzM+6U5hecgy3Xv6sL93ChB5VINipkQ85jECAwEAAaNTMFEwHQYDVR0OBBYEFOJ5SUCf3Kw787313G5AaRk2LnUyMB8GA1UdIwQYMBaAFOJ5SUCf3Kw787313G5AaRk2LnUyMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBADhZUpklgAgNCSPqrKSqfz60R0CNYQI2t6kyKm+QqwCf68HshEiPZefNv+YAmQdE5qZCdWP2PSYXfbk6sfVfQBlfOQiI2C6Du08Y652A7kbYQe4/itJLibxUAuV1T1Rg8dKAjt3GSqVhEuUbbxbTlu8xlM+gmyPM3JLFo1AC+SSZ85PS9S1PsiWoV2rDa+3qOGek0+1ct0fesZo7VwnF/mlWSqvFa0W7lzozDOPj48DPhr+2VRGPX7ZLuuYwxhxihSljMiRBLdlhAS4kK4tgIpacP/iBr3l0GgVaTKE1saL5lPn5vulgzoM8Ar1dGcs6M/fKOAtdWIuc9iizvU0m25kW8WUT+31ouxpXEDqVQjbKsk1aifnqf8OjCKZlFpTSNNV+M6wrDYwvTxF/L//JlfaGozjAmGUMJpOI4kLSt7VrhCx+lCL+4Foz4wZ1/XQOJtpn/nD4VsRtdgVvVG7+P19yGwKAGvVSDZHbd2hGDiRFtevrO+R+Ysq/OijbFy2rCjUvkIwZd0fNWfRjd9kyMlVzlpe9SyOu9nVVcZHceRXBiTq891eTChz/+8sw6Z3yIUjfovafLNisZ6f+Dohb6TwwwBApkCe+iCab4kIXWym54dUBZ4Mjgz7ruoPwAi2lMt5ej7Un8rGNYuklr5CFozQOfh+TNTJDow6hHq3Eo18m\n \n \n \n \n \n \n MIIFFTCCAv2gAwIBAgIUGdd3KdAmoGLcSBBpGD91vfiwtNAwDQYJKoZIhvcNAQELBQAwGjEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tMB4XDTI0MTAwMjE2MTQ0MVoXDTM0MDkzMDE2MTQ0MVowGjEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlVkeF2COiZAuvuA68ZaanoExvG+xynhEbNB9RgJUltkp6AiMlyhju+fLBzqH635FjNZHgkKoCTfxPW5Rq+iRSm9qyP86QogZsUYnLpyrnmDVJc8l75Flf+3USdIKnVA9mUAKyxUnYBMR/QCsNFcNTkGcFzx/GUGdRq0iWY6cF73o8DJR0c/liJjNL5kpxlKa28DVEgZceFb9w+/16PoNJ51XO4C7eOyEggKOGK9JBC845H8dUpFAs7Vl1Pal+dCUiNm+cwPQQz9ypIBqt1J6uICUiVXJtAhk5QN8yuEpp47T8FV3hcAmj4vERTNCV3JCB0Ft186X2WVe3RDUTKZ4pVkRes8ihP2Waxkphzd1qRBHMTgMDkBP3siraTDjkdtbyfpp25cfq2T8GcZVw4q2ObaiKheOAxRdO1rrOBrMffujMO8SZxRGh12ZqtPqQIDl4IfB65Ktri1po/Mw6s/s+r592BUm7drRq7wSXRcyk9uy1KWKho8n1fwx00M7FvPXPZpEq3kQyQgCI+ZazBCwtZlcSl4EJ5DDkRtrzjx+642kApr+XcKW1V3mp9beQwvXNmtt+krHvshft6JBVea9osJs3r9kKFQg+A1L7mSSg87xqvkCkfttHUFzHqkWTyvhjxZCbw45dzM+6U5hecgy3Xv6sL93ChB5VINipkQ85jECAwEAAaNTMFEwHQYDVR0OBBYEFOJ5SUCf3Kw787313G5AaRk2LnUyMB8GA1UdIwQYMBaAFOJ5SUCf3Kw787313G5AaRk2LnUyMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBADhZUpklgAgNCSPqrKSqfz60R0CNYQI2t6kyKm+QqwCf68HshEiPZefNv+YAmQdE5qZCdWP2PSYXfbk6sfVfQBlfOQiI2C6Du08Y652A7kbYQe4/itJLibxUAuV1T1Rg8dKAjt3GSqVhEuUbbxbTlu8xlM+gmyPM3JLFo1AC+SSZ85PS9S1PsiWoV2rDa+3qOGek0+1ct0fesZo7VwnF/mlWSqvFa0W7lzozDOPj48DPhr+2VRGPX7ZLuuYwxhxihSljMiRBLdlhAS4kK4tgIpacP/iBr3l0GgVaTKE1saL5lPn5vulgzoM8Ar1dGcs6M/fKOAtdWIuc9iizvU0m25kW8WUT+31ouxpXEDqVQjbKsk1aifnqf8OjCKZlFpTSNNV+M6wrDYwvTxF/L//JlfaGozjAmGUMJpOI4kLSt7VrhCx+lCL+4Foz4wZ1/XQOJtpn/nD4VsRtdgVvVG7+P19yGwKAGvVSDZHbd2hGDiRFtevrO+R+Ysq/OijbFy2rCjUvkIwZd0fNWfRjd9kyMlVzlpe9SyOu9nVVcZHceRXBiTq891eTChz/+8sw6Z3yIUjfovafLNisZ6f+Dohb6TwwwBApkCe+iCab4kIXWym54dUBZ4Mjgz7ruoPwAi2lMt5ej7Un8rGNYuklr5CFozQOfh+TNTJDow6hHq3Eo18m\n \n \n \n \n \n \n \n urn:oasis:names:tc:SAML:2.0:nameid-format:transient\n \n \n \n"), + options: []ProviderOpts{ + WithLinkingAllowed(), + WithCreationAllowed(), + WithAutoCreation(), + WithAutoUpdate(), + WithBinding(saml.HTTPRedirectBinding), + WithSignedRequest(), + WithCustomRequestTracker(&requesttracker.RequestTracker{}), + WithTransientMappingAttributeName("customTransientAttribute"), + }, + rootURL: "http://localhost:8080/idps/228968792372281708/", + timeNow: func() time.Time { + return time.Date(2025, 9, 21, 13, 47, 40, 0, time.UTC) + }, + }, + args: args{ + request: httpPostFormRequest(t, + "http://localhost:8080/idps/228968792372281708/saml/acs", + "232881438356144492", + "PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzYW1scDpSZXNwb25zZSB4bWxuczpzYW1sPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiB4bWxuczpzYW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIElEPSJwZng0M2UzZjA2YS1lMWU3LWQ5NjctOTZhNi1mY2EyODg5NmM5YjkiIEluUmVzcG9uc2VUbz0iaWQtYjIyYzkwZGI4OGJmMDFkODJmZmIwYTdiNmZlMjVhYzlmY2IyYzY3OSIgVmVyc2lvbj0iMi4wIiBJc3N1ZUluc3RhbnQ9IjIwMjUtMDktMjFUMTM6NDk6MjMuOTM4WiIgRGVzdGluYXRpb249Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9pZHBzLzIyODk2ODc5MjM3MjI4MTcwOC9zYW1sL2FjcyI+PHNhbWw6SXNzdWVyIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6ZW50aXR5Ij5odHRwOi8vbG9jYWxob3N0OjgwMDAvbWV0YWRhdGE8L3NhbWw6SXNzdWVyPjxkczpTaWduYXR1cmUgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPgogIDxkczpTaWduZWRJbmZvPjxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+CiAgICA8ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3JzYS1zaGExIi8+CiAgPGRzOlJlZmVyZW5jZSBVUkk9IiNwZng0M2UzZjA2YS1lMWU3LWQ5NjctOTZhNi1mY2EyODg5NmM5YjkiPjxkczpUcmFuc2Zvcm1zPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48L2RzOlRyYW5zZm9ybXM+PGRzOkRpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNzaGExIi8+PGRzOkRpZ2VzdFZhbHVlPmRTb2M2VmUvbGFrdmM5cUVrYTlLZlo3ekJxWT08L2RzOkRpZ2VzdFZhbHVlPjwvZHM6UmVmZXJlbmNlPjwvZHM6U2lnbmVkSW5mbz48ZHM6U2lnbmF0dXJlVmFsdWU+VWdrdklwVSsreFZPRjlFNG1rZ1hkNUIvRUdmVkc4eEFFd0hPS3BjZDQzQ0dhV3FoTTBGVTZEQ1FyOE5wcC84dENpaHVvWENMMnNGRjZydy9DUmRGUEpFWUhqdldSVm9ESTVwdGRnRDZlZXVqRnN4bzRzTWU5aW83cHhvYVd6STFRWUFSM3oxUER6bDNvaTRnWG9oVXhsSEovTldaRzV1VkdSMnd6dXdLdjA4Uit6U2liOHhiZ3dsUUZiTEdNTzFNZVdJL1pxV0x6UURvY0hxZWxjbG9SL1V4cWsxMnRJU3B2Y25tTEpROVNid1JnYmtrZWZsQng5NzZIUVdURFEyS2M4b1lqZjVZSzlYbDdJVFFFQzE1UFYvZ3hMQXNTU2x0VDlJKzh1YXI1L2lKZlV1eWhVbG5KR0oxd3dSRW9XVXh3aEM0ckhjSFF1K05qUjM0akMvdlRWU1JZSkZNVVpieHp0MXdJVGpsdkxveGlMTktzeG9MbDFhcHArMHk1ZjVlcWJvRGtxTnFCcTdEQ3NjTXk0WTQ2aWdWdWt1Vk1YM21HLzdZeFJCS3lPcTZKQjc0TFVvb0Y3U3oxQTBuU3U4ekNKQ0JJTWVUNXdGdURXYlNaOUw2NC9qbFJYRFpOWEtlMGx6bkRaU2h6UllZdC9EUjFMWTNyQ3BwNTdzT0tVWDJSVzdJYld0Mmp2bDdHc1VELzBUVEZncHZ1M29UMENrRTRSSnhFVDluQnpYRkNtckY4VzVjWE9zWThrSEpZOGJtYk1IbUlNNVRuWkM0QVZaaUd3aGdEKzZBUWpnc3piVnh4amlvRWt6Q1Q1SndKR2NZUEtsQ2I2QWtjY2pRcnpUeUJLZzdaSzBEUEdVbFcrSDYxMGREN3hpM1A0Qit5MlBqRitmMkhqRi9kaUE9PC9kczpTaWduYXR1cmVWYWx1ZT4KPGRzOktleUluZm8+PGRzOlg1MDlEYXRhPjxkczpYNTA5Q2VydGlmaWNhdGU+TUlJRkZUQ0NBdjJnQXdJQkFnSVVHZGQzS2RBbW9HTGNTQkJwR0Q5MXZmaXd0TkF3RFFZSktvWklodmNOQVFFTEJRQXdHakVZTUJZR0ExVUVBd3dQZDNkM0xtVjRZVzF3YkdVdVkyOXRNQjRYRFRJME1UQXdNakUyTVRRME1Wb1hEVE0wTURrek1ERTJNVFEwTVZvd0dqRVlNQllHQTFVRUF3d1BkM2QzTG1WNFlXMXdiR1V1WTI5dE1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBbFZrZUYyQ09pWkF1dnVBNjhaYWFub0V4dkcreHluaEViTkI5UmdKVWx0a3A2QWlNbHloanUrZkxCenFINjM1RmpOWkhna0tvQ1RmeFBXNVJxK2lSU205cXlQODZRb2dac1VZbkxweXJubURWSmM4bDc1RmxmKzNVU2RJS25WQTltVUFLeXhVbllCTVIvUUNzTkZjTlRrR2NGengvR1VHZFJxMGlXWTZjRjczbzhESlIwYy9saUpqTkw1a3B4bEthMjhEVkVnWmNlRmI5dysvMTZQb05KNTFYTzRDN2VPeUVnZ0tPR0s5SkJDODQ1SDhkVXBGQXM3VmwxUGFsK2RDVWlObStjd1BRUXo5eXBJQnF0MUo2dUlDVWlWWEp0QWhrNVFOOHl1RXBwNDdUOEZWM2hjQW1qNHZFUlROQ1YzSkNCMEZ0MTg2WDJXVmUzUkRVVEtaNHBWa1JlczhpaFAyV2F4a3BoemQxcVJCSE1UZ01Ea0JQM3NpcmFURGprZHRieWZwcDI1Y2ZxMlQ4R2NaVnc0cTJPYmFpS2hlT0F4UmRPMXJyT0JyTWZmdWpNTzhTWnhSR2gxMlpxdFBxUUlEbDRJZkI2NUt0cmkxcG8vTXc2cy9zK3I1OTJCVW03ZHJScTd3U1hSY3lrOXV5MUtXS2hvOG4xZnd4MDBNN0Z2UFhQWnBFcTNrUXlRZ0NJK1phekJDd3RabGNTbDRFSjVERGtSdHJ6angrNjQya0FwcitYY0tXMVYzbXA5YmVRd3ZYTm10dCtrckh2c2hmdDZKQlZlYTlvc0pzM3I5a0tGUWcrQTFMN21TU2c4N3hxdmtDa2Z0dEhVRnpIcWtXVHl2aGp4WkNidzQ1ZHpNKzZVNWhlY2d5M1h2NnNMOTNDaEI1VklOaXBrUTg1akVDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRk9KNVNVQ2YzS3c3ODczMTNHNUFhUmsyTG5VeU1COEdBMVVkSXdRWU1CYUFGT0o1U1VDZjNLdzc4NzMxM0c1QWFSazJMblV5TUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFTEJRQURnZ0lCQURoWlVwa2xnQWdOQ1NQcXJLU3FmejYwUjBDTllRSTJ0Nmt5S20rUXF3Q2Y2OEhzaEVpUFplZk52K1lBbVFkRTVxWkNkV1AyUFNZWGZiazZzZlZmUUJsZk9RaUkyQzZEdTA4WTY1MkE3a2JZUWU0L2l0SkxpYnhVQXVWMVQxUmc4ZEtBanQzR1NxVmhFdVViYnhiVGx1OHhsTStnbXlQTTNKTEZvMUFDK1NTWjg1UFM5UzFQc2lXb1YyckRhKzNxT0dlazArMWN0MGZlc1pvN1Z3bkYvbWxXU3F2RmEwVzdsem96RE9QajQ4RFBocisyVlJHUFg3Wkx1dVl3eGh4aWhTbGpNaVJCTGRsaEFTNGtLNHRnSXBhY1AvaUJyM2wwR2dWYVRLRTFzYUw1bFBuNXZ1bGd6b004QXIxZEdjczZNL2ZLT0F0ZFdJdWM5aWl6dlUwbTI1a1c4V1VUKzMxb3V4cFhFRHFWUWpiS3NrMWFpZm5xZjhPakNLWmxGcFRTTk5WK002d3JEWXd2VHhGL0wvL0psZmFHb3pqQW1HVU1KcE9JNGtMU3Q3VnJoQ3grbENMKzRGb3o0d1oxL1hRT0p0cG4vbkQ0VnNSdGRnVnZWRzcrUDE5eUd3S0FHdlZTRFpIYmQyaEdEaVJGdGV2ck8rUitZc3EvT2lqYkZ5MnJDalV2a0l3WmQwZk5XZlJqZDlreU1sVnpscGU5U3lPdTluVlZjWkhjZVJYQmlUcTg5MWVUQ2h6Lys4c3c2WjN5SVVqZm92YWZMTmlzWjZmK0RvaGI2VHd3d0JBcGtDZStpQ2FiNGtJWFd5bTU0ZFVCWjRNamd6N3J1b1B3QWkybE10NWVqN1VuOHJHTll1a2xyNUNGb3pRT2ZoK1ROVEpEb3c2aEhxM0VvMThtPC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+PHNhbWxwOlN0YXR1cz48c2FtbHA6U3RhdHVzQ29kZSBWYWx1ZT0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnN0YXR1czpTdWNjZXNzIi8+PC9zYW1scDpTdGF0dXM+PHNhbWw6QXNzZXJ0aW9uIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIElEPSJwZng5NGJjNjJjOS1kZDQ1LWYxNGEtOGFlNS1mNWIwZGM2ZTQ4OTciIElzc3VlSW5zdGFudD0iMjAyNS0wOS0yMVQxMzo0OToyMy45NDFaIiBWZXJzaW9uPSIyLjAiPjxzYW1sOklzc3VlciBGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpuYW1laWQtZm9ybWF0OmVudGl0eSI+aHR0cDovL2xvY2FsaG9zdDo4MDAwL21ldGFkYXRhPC9zYW1sOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4KICA8ZHM6U2lnbmVkSW5mbz48ZHM6Q2Fub25pY2FsaXphdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPgogICAgPGRzOlNpZ25hdHVyZU1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNyc2Etc2hhMSIvPgogIDxkczpSZWZlcmVuY2UgVVJJPSIjcGZ4OTRiYzYyYzktZGQ0NS1mMTRhLThhZTUtZjViMGRjNmU0ODk3Ij48ZHM6VHJhbnNmb3Jtcz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIvPjxkczpEaWdlc3RWYWx1ZT55eW94RlJ4OUt5SEZoTkM0cDN4SmEvVDI0Q2M9PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8+PGRzOlNpZ25hdHVyZVZhbHVlPkVVOUJKOVdHSnVjKzVINko2a2I2STRFU0ZidlEyQ3kxbnFtanFyTWgxL0NTdU1xODBDek1QSDlaN1l2TUlMeFpKUlZFaVZqRGxQSXFwYnpHUFhKQlJYMkQ5TnI2SXduM3RBa0VtcW9WVXRmdmJ0dUhwV05DdENhcE5BM3NCalB6WEFFZnEzZElIWnBVSE5Nd1R4WGZkTEtTOXZXd1pNNUtLL1htQWlYNnpnTmgydW9FMitZZTgvUHViMFg1NFVIaUcyeUdhYlhpbEV5VUlqWE1FV0pZS1BySU9tMlR5TXZDeENvSndJOUYwYWIxOGdJVkVBL0szVG8xc2Z4Q3pWZ0FJZFgxbzM3enQzdnYvcVJwQkxka3JZdTg3OVpXZVBxenVHT2RTbWFLdkRUd01mWFJYYWhicFhScTloQ3pSaXBzaHg3blc2dExwYUFFNlhBYkJjS1Rndkg3SlBET240ajhpclJOVmtpTEhRM2cvaGlDVWhBUHh2S1NyaURNWEJ5UUszeHBlbTRZUGZVaWRuSU04cmtxUU1UVjYySGpDMjZFV0pDZm5taHBoNUNBNDBPQ0lIbEZzMVZMOXBoQTdaeUZqa0s5Q3FqRkpjR21qQ3JUMDFvK0I2UDYzdmFQeDBrOTBtVjd5MFB2MDdxQmo3UVluNVZMMzRvOUptbU5XWDk0azFFNDdZWGtyUG1IOS9idy9BWGpKTXI0SDAzSXVvRmU3S3ROOTdRL1NwTlhMOVAxaFlEcEk0QjEvRUxISGhUSXR6REpXZk0wU3Z3MndBM1U4VVV6UHBqeWlJajJKT3pCeDhWUFdHSWMvWHZhNkU4V3BKUmMyaFNkbGtVS3grTTNHeGxJeExPNE5jQWZzZGs4aXR0NDNOd2I4bWc2WFRrTVZLdVBhY0xxeVJ3PTwvZHM6U2lnbmF0dXJlVmFsdWU+CjxkczpLZXlJbmZvPjxkczpYNTA5RGF0YT48ZHM6WDUwOUNlcnRpZmljYXRlPk1JSUZGVENDQXYyZ0F3SUJBZ0lVR2RkM0tkQW1vR0xjU0JCcEdEOTF2Zml3dE5Bd0RRWUpLb1pJaHZjTkFRRUxCUUF3R2pFWU1CWUdBMVVFQXd3UGQzZDNMbVY0WVcxd2JHVXVZMjl0TUI0WERUSTBNVEF3TWpFMk1UUTBNVm9YRFRNME1Ea3pNREUyTVRRME1Wb3dHakVZTUJZR0ExVUVBd3dQZDNkM0xtVjRZVzF3YkdVdVkyOXRNSUlDSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQWc4QU1JSUNDZ0tDQWdFQWxWa2VGMkNPaVpBdXZ1QTY4WmFhbm9FeHZHK3h5bmhFYk5COVJnSlVsdGtwNkFpTWx5aGp1K2ZMQnpxSDYzNUZqTlpIZ2tLb0NUZnhQVzVScStpUlNtOXF5UDg2UW9nWnNVWW5McHlybm1EVkpjOGw3NUZsZiszVVNkSUtuVkE5bVVBS3l4VW5ZQk1SL1FDc05GY05Ua0djRnp4L0dVR2RScTBpV1k2Y0Y3M284REpSMGMvbGlKak5MNWtweGxLYTI4RFZFZ1pjZUZiOXcrLzE2UG9OSjUxWE80QzdlT3lFZ2dLT0dLOUpCQzg0NUg4ZFVwRkFzN1ZsMVBhbCtkQ1VpTm0rY3dQUVF6OXlwSUJxdDFKNnVJQ1VpVlhKdEFoazVRTjh5dUVwcDQ3VDhGVjNoY0FtajR2RVJUTkNWM0pDQjBGdDE4NlgyV1ZlM1JEVVRLWjRwVmtSZXM4aWhQMldheGtwaHpkMXFSQkhNVGdNRGtCUDNzaXJhVERqa2R0YnlmcHAyNWNmcTJUOEdjWlZ3NHEyT2JhaUtoZU9BeFJkTzFyck9Cck1mZnVqTU84U1p4UkdoMTJacXRQcVFJRGw0SWZCNjVLdHJpMXBvL013NnMvcytyNTkyQlVtN2RyUnE3d1NYUmN5azl1eTFLV0tobzhuMWZ3eDAwTTdGdlBYUFpwRXEza1F5UWdDSStaYXpCQ3d0WmxjU2w0RUo1RERrUnRyemp4KzY0MmtBcHIrWGNLVzFWM21wOWJlUXd2WE5tdHQra3JIdnNoZnQ2SkJWZWE5b3NKczNyOWtLRlFnK0ExTDdtU1NnODd4cXZrQ2tmdHRIVUZ6SHFrV1R5dmhqeFpDYnc0NWR6TSs2VTVoZWNneTNYdjZzTDkzQ2hCNVZJTmlwa1E4NWpFQ0F3RUFBYU5UTUZFd0hRWURWUjBPQkJZRUZPSjVTVUNmM0t3Nzg3MzEzRzVBYVJrMkxuVXlNQjhHQTFVZEl3UVlNQmFBRk9KNVNVQ2YzS3c3ODczMTNHNUFhUmsyTG5VeU1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dJQkFEaFpVcGtsZ0FnTkNTUHFyS1NxZno2MFIwQ05ZUUkydDZreUttK1Fxd0NmNjhIc2hFaVBaZWZOditZQW1RZEU1cVpDZFdQMlBTWVhmYms2c2ZWZlFCbGZPUWlJMkM2RHUwOFk2NTJBN2tiWVFlNC9pdEpMaWJ4VUF1VjFUMVJnOGRLQWp0M0dTcVZoRXVVYmJ4YlRsdTh4bE0rZ215UE0zSkxGbzFBQytTU1o4NVBTOVMxUHNpV29WMnJEYSszcU9HZWswKzFjdDBmZXNabzdWd25GL21sV1NxdkZhMFc3bHpvekRPUGo0OERQaHIrMlZSR1BYN1pMdXVZd3hoeGloU2xqTWlSQkxkbGhBUzRrSzR0Z0lwYWNQL2lCcjNsMEdnVmFUS0Uxc2FMNWxQbjV2dWxnem9NOEFyMWRHY3M2TS9mS09BdGRXSXVjOWlpenZVMG0yNWtXOFdVVCszMW91eHBYRURxVlFqYktzazFhaWZucWY4T2pDS1psRnBUU05OVitNNndyRFl3dlR4Ri9MLy9KbGZhR296akFtR1VNSnBPSTRrTFN0N1ZyaEN4K2xDTCs0Rm96NHdaMS9YUU9KdHBuL25ENFZzUnRkZ1Z2Vkc3K1AxOXlHd0tBR3ZWU0RaSGJkMmhHRGlSRnRldnJPK1IrWXNxL09pamJGeTJyQ2pVdmtJd1pkMGZOV2ZSamQ5a3lNbFZ6bHBlOVN5T3U5blZWY1pIY2VSWEJpVHE4OTFlVENoei8rOHN3NlozeUlVamZvdmFmTE5pc1o2ZitEb2hiNlR3d3dCQXBrQ2UraUNhYjRrSVhXeW01NGRVQlo0TWpnejdydW9Qd0FpMmxNdDVlajdVbjhyR05ZdWtscjVDRm96UU9maCtUTlRKRG93NmhIcTNFbzE4bTwvZHM6WDUwOUNlcnRpZmljYXRlPjwvZHM6WDUwOURhdGE+PC9kczpLZXlJbmZvPjwvZHM6U2lnbmF0dXJlPjxzYW1sOlN1YmplY3Q+PHNhbWw6U3ViamVjdENvbmZpcm1hdGlvbiBNZXRob2Q9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpjbTpiZWFyZXIiPjxzYW1sOlN1YmplY3RDb25maXJtYXRpb25EYXRhIEFkZHJlc3M9Ils6OjFdOjU5MzM0IiBJblJlc3BvbnNlVG89ImlkLWIyMmM5MGRiODhiZjAxZDgyZmZiMGE3YjZmZTI1YWM5ZmNiMmM2NzkiIE5vdE9uT3JBZnRlcj0iMjAyNS0wOS0yMVQxMzo1MDo1My45MzhaIiBSZWNpcGllbnQ9Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9pZHBzLzIyODk2ODc5MjM3MjI4MTcwOC9zYW1sL2FjcyIvPjwvc2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uPjwvc2FtbDpTdWJqZWN0PjxzYW1sOkNvbmRpdGlvbnMgTm90QmVmb3JlPSIyMDI1LTA5LTIxVDEzOjQ5OjE0LjI5OFoiIE5vdE9uT3JBZnRlcj0iMjAyNS0wOS0yMVQxMzo1MDo0NC4yOThaIj48c2FtbDpBdWRpZW5jZVJlc3RyaWN0aW9uPjxzYW1sOkF1ZGllbmNlPmh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9pZHBzLzIyODk2ODc5MjM3MjI4MTcwOC9zYW1sL21ldGFkYXRhPC9zYW1sOkF1ZGllbmNlPjwvc2FtbDpBdWRpZW5jZVJlc3RyaWN0aW9uPjwvc2FtbDpDb25kaXRpb25zPjxzYW1sOkF1dGhuU3RhdGVtZW50IEF1dGhuSW5zdGFudD0iMjAyNS0wOS0yMVQxMzo0NzozNS4xMDNaIiBTZXNzaW9uSW5kZXg9IjRjMzliMTk1NDJjN2NlMWMzOWU5YzA1YmUxN2E3MmE2ZDg4ZTU1YTdkYWJhZGFlZDc4NjEwMGI5ZTM4MGZhMDgiPjxzYW1sOlN1YmplY3RMb2NhbGl0eSBBZGRyZXNzPSJbOjoxXTo1OTMzNCIvPjxzYW1sOkF1dGhuQ29udGV4dD48c2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj51cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YWM6Y2xhc3NlczpQYXNzd29yZFByb3RlY3RlZFRyYW5zcG9ydDwvc2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj48L3NhbWw6QXV0aG5Db250ZXh0Pjwvc2FtbDpBdXRoblN0YXRlbWVudD48c2FtbDpBdHRyaWJ1dGVTdGF0ZW1lbnQ+PHNhbWw6QXR0cmlidXRlIEZyaWVuZGx5TmFtZT0idWlkIiBOYW1lPSJ1cm46b2lkOjAuOS4yMzQyLjE5MjAwMzAwLjEwMC4xLjEiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6dXJpIj48c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5hbGljZTwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT48L3NhbWw6QXR0cmlidXRlPjxzYW1sOkF0dHJpYnV0ZSBGcmllbmRseU5hbWU9ImVkdVBlcnNvblByaW5jaXBhbE5hbWUiIE5hbWU9InVybjpvaWQ6MS4zLjYuMS40LjEuNTkyMy4xLjEuMS42IiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OnVyaSI+PHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnR5cGU9InhzOnN0cmluZyI+YWxpY2VAZXhhbXBsZS5jb208L3NhbWw6QXR0cmlidXRlVmFsdWU+PC9zYW1sOkF0dHJpYnV0ZT48c2FtbDpBdHRyaWJ1dGUgRnJpZW5kbHlOYW1lPSJzbiIgTmFtZT0idXJuOm9pZDoyLjUuNC40IiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OnVyaSI+PHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnR5cGU9InhzOnN0cmluZyI+U21pdGg8L3NhbWw6QXR0cmlidXRlVmFsdWU+PC9zYW1sOkF0dHJpYnV0ZT48c2FtbDpBdHRyaWJ1dGUgRnJpZW5kbHlOYW1lPSJnaXZlbk5hbWUiIE5hbWU9InVybjpvaWQ6Mi41LjQuNDIiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6dXJpIj48c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5BbGljZTwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT48L3NhbWw6QXR0cmlidXRlPjxzYW1sOkF0dHJpYnV0ZSBGcmllbmRseU5hbWU9ImNuIiBOYW1lPSJ1cm46b2lkOjIuNS40LjMiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6dXJpIj48c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5BbGljZSBTbWl0aDwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT48L3NhbWw6QXR0cmlidXRlPjxzYW1sOkF0dHJpYnV0ZSBGcmllbmRseU5hbWU9ImVkdVBlcnNvbkFmZmlsaWF0aW9uIiBOYW1lPSJ1cm46b2lkOjEuMy42LjEuNC4xLjU5MjMuMS4xLjEuMSIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDp1cmkiPjxzYW1sOkF0dHJpYnV0ZVZhbHVlIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPkFkbWluaXN0cmF0b3JzPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPjxzYW1sOkF0dHJpYnV0ZVZhbHVlIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPlVzZXJzPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPjwvc2FtbDpBdHRyaWJ1dGU+PC9zYW1sOkF0dHJpYnV0ZVN0YXRlbWVudD48L3NhbWw6QXNzZXJ0aW9uPjwvc2FtbHA6UmVzcG9uc2U+", + ), + requestID: "id-b22c90db88bf01d82ffb0a7b6fe25ac9fcb2c679", + }, + want: want{ + err: zerrors.ThrowInvalidArgument(nil, "SAML-swwg2", "Errors.Intent.MissingSingleMappingAttribute"), }, }, { diff --git a/internal/integration/client.go b/internal/integration/client.go index d4e57d06d0..5365b1fca8 100644 --- a/internal/integration/client.go +++ b/internal/integration/client.go @@ -21,7 +21,8 @@ import ( "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/integration/scim" - action "github.com/zitadel/zitadel/pkg/grpc/action/v2beta" + "github.com/zitadel/zitadel/pkg/grpc/action/v2" + action_v2beta "github.com/zitadel/zitadel/pkg/grpc/action/v2beta" "github.com/zitadel/zitadel/pkg/grpc/admin" app "github.com/zitadel/zitadel/pkg/grpc/app/v2beta" "github.com/zitadel/zitadel/pkg/grpc/auth" @@ -69,7 +70,8 @@ type Client struct { OIDCv2 oidc_pb.OIDCServiceClient OrgV2beta org_v2beta.OrganizationServiceClient OrgV2 org.OrganizationServiceClient - ActionV2beta action.ActionServiceClient + ActionV2beta action_v2beta.ActionServiceClient + ActionV2 action.ActionServiceClient FeatureV2beta feature_v2beta.FeatureServiceClient FeatureV2 feature.FeatureServiceClient UserSchemaV3 userschema_v3alpha.ZITADELUserSchemasClient @@ -112,7 +114,8 @@ func newClient(ctx context.Context, target string) (*Client, error) { OIDCv2: oidc_pb.NewOIDCServiceClient(cc), OrgV2beta: org_v2beta.NewOrganizationServiceClient(cc), OrgV2: org.NewOrganizationServiceClient(cc), - ActionV2beta: action.NewActionServiceClient(cc), + ActionV2beta: action_v2beta.NewActionServiceClient(cc), + ActionV2: action.NewActionServiceClient(cc), FeatureV2beta: feature_v2beta.NewFeatureServiceClient(cc), FeatureV2: feature.NewFeatureServiceClient(cc), UserSchemaV3: userschema_v3alpha.NewZITADELUserSchemasClient(cc), @@ -1057,27 +1060,27 @@ func (i *Instance) CreateTarget(ctx context.Context, t *testing.T, name, endpoin RestAsync: &action.RESTAsync{}, } } - target, err := i.Client.ActionV2beta.CreateTarget(ctx, req) + target, err := i.Client.ActionV2.CreateTarget(ctx, req) require.NoError(t, err) return target } func (i *Instance) DeleteTarget(ctx context.Context, t *testing.T, id string) { - _, err := i.Client.ActionV2beta.DeleteTarget(ctx, &action.DeleteTargetRequest{ + _, err := i.Client.ActionV2.DeleteTarget(ctx, &action.DeleteTargetRequest{ Id: id, }) require.NoError(t, err) } func (i *Instance) DeleteExecution(ctx context.Context, t *testing.T, cond *action.Condition) { - _, err := i.Client.ActionV2beta.SetExecution(ctx, &action.SetExecutionRequest{ + _, err := i.Client.ActionV2.SetExecution(ctx, &action.SetExecutionRequest{ Condition: cond, }) require.NoError(t, err) } func (i *Instance) SetExecution(ctx context.Context, t *testing.T, cond *action.Condition, targets []string) *action.SetExecutionResponse { - target, err := i.Client.ActionV2beta.SetExecution(ctx, &action.SetExecutionRequest{ + target, err := i.Client.ActionV2.SetExecution(ctx, &action.SetExecutionRequest{ Condition: cond, Targets: targets, }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f3cd239c94..3fe94a017d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -30,7 +30,7 @@ importers: dependencies: '@headlessui/react': specifier: ^2.1.9 - version: 2.2.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 2.2.7(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@heroicons/react': specifier: 2.1.3 version: 2.1.3(react@19.1.0) @@ -42,7 +42,7 @@ importers: version: 0.5.7(tailwindcss@3.4.14) '@vercel/analytics': specifier: ^1.2.2 - version: 1.5.0(next@15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2))(react@19.1.0) + version: 1.5.0(next@15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2))(react@19.1.0) '@zitadel/client': specifier: workspace:* version: link:../../packages/zitadel-client @@ -66,13 +66,13 @@ importers: version: 2.30.1 next: specifier: 15.4.0-canary.86 - version: 15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2) + version: 15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2) next-intl: specifier: ^3.25.1 - version: 3.26.5(next@15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2))(react@19.1.0) + version: 3.26.5(next@15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2))(react@19.1.0) next-themes: specifier: ^0.2.1 - version: 0.2.1(next@15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 0.2.1(next@15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) nice-grpc: specifier: 2.0.1 version: 2.0.1 @@ -100,7 +100,7 @@ importers: version: 7.28.0(@babel/core@7.28.0)(eslint@8.57.1) '@bufbuild/buf': specifier: ^1.53.0 - version: 1.55.1 + version: 1.56.0 '@faker-js/faker': specifier: ^9.7.0 version: 9.9.0 @@ -115,19 +115,19 @@ importers: version: 12.0.1 '@playwright/test': specifier: ^1.52.0 - version: 1.54.1 + version: 1.54.2 '@testing-library/jest-dom': specifier: ^6.6.3 - version: 6.6.3 + version: 6.6.4 '@testing-library/react': specifier: ^16.3.0 - version: 16.3.0(@testing-library/dom@10.4.0)(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@types/ms': specifier: 2.1.0 version: 2.1.0 '@types/node': specifier: ^22.14.1 - version: 22.16.5 + version: 22.17.0 '@types/react': specifier: 19.1.2 version: 19.1.2 @@ -142,16 +142,16 @@ importers: version: 10.0.0 '@typescript-eslint/eslint-plugin': specifier: ^7.0.0 - version: 7.18.0(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3) + version: 7.18.0(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.35.1 - version: 8.38.0(eslint@8.57.1)(typescript@5.8.3) + version: 8.38.0(eslint@8.57.1)(typescript@5.9.2) '@vercel/git-hooks': specifier: 1.0.0 version: 1.0.0 '@vitejs/plugin-react': specifier: ^4.4.1 - version: 4.7.0(vite@5.4.19(@types/node@22.16.5)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)) + version: 4.7.0(vite@5.4.19(@types/node@22.17.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)) autoprefixer: specifier: 10.4.21 version: 10.4.21(postcss@8.5.3) @@ -160,7 +160,7 @@ importers: version: 9.2.0 cypress: specifier: ^14.5.2 - version: 14.5.2 + version: 14.5.3 dotenv-cli: specifier: ^8.0.0 version: 8.0.0 @@ -172,7 +172,7 @@ importers: version: 8.57.1 eslint-config-next: specifier: 15.4.0-canary.86 - version: 15.4.0-canary.86(eslint@8.57.1)(typescript@5.8.3) + version: 15.4.0-canary.86(eslint@8.57.1)(typescript@5.9.2) eslint-config-prettier: specifier: ^9.1.0 version: 9.1.2(eslint@8.57.1) @@ -202,10 +202,10 @@ importers: version: 3.6.2 prettier-plugin-organize-imports: specifier: ^3.2.0 - version: 3.2.4(prettier@3.6.2)(typescript@5.8.3) + version: 3.2.4(prettier@3.6.2)(typescript@5.9.2) prettier-plugin-tailwindcss: specifier: 0.6.11 - version: 0.6.11(prettier-plugin-organize-imports@3.2.4(prettier@3.6.2)(typescript@5.8.3))(prettier@3.6.2) + version: 0.6.11(prettier-plugin-organize-imports@3.2.4(prettier@3.6.2)(typescript@5.9.2))(prettier@3.6.2) sass: specifier: ^1.87.0 version: 1.89.2 @@ -220,13 +220,13 @@ importers: version: 2.7.5 typescript: specifier: ^5.8.3 - version: 5.8.3 + version: 5.9.2 vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.8.3)(vite@5.4.19(@types/node@22.16.5)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)) + version: 5.1.4(typescript@5.9.2)(vite@5.4.19(@types/node@22.17.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)) vitest: specifier: ^2.0.0 - version: 2.1.9(@types/node@22.16.5)(jsdom@26.1.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1) + version: 2.1.9(@types/node@22.17.0)(jsdom@26.1.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1) wait-on: specifier: ^7.2.0 version: 7.2.0 @@ -274,10 +274,10 @@ importers: version: 2.6.2 '@connectrpc/connect': specifier: ^2.0.0 - version: 2.0.2(@bufbuild/protobuf@2.6.2) + version: 2.0.3(@bufbuild/protobuf@2.6.2) '@connectrpc/connect-web': specifier: ^2.0.0 - version: 2.0.2(@bufbuild/protobuf@2.6.2)(@connectrpc/connect@2.0.2(@bufbuild/protobuf@2.6.2)) + version: 2.0.3(@bufbuild/protobuf@2.6.2)(@connectrpc/connect@2.0.3(@bufbuild/protobuf@2.6.2)) '@ctrl/ngx-codemirror': specifier: ^6.1.0 version: 6.1.0(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3))(@angular/forms@16.2.12(@angular/common@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3))(rxjs@7.8.2))(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3))(@angular/platform-browser@16.2.12(@angular/animations@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3)))(@angular/common@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3))(rxjs@7.8.2))(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3)))(rxjs@7.8.2))(codemirror@5.65.19) @@ -343,7 +343,7 @@ importers: version: 1.3.4 posthog-js: specifier: ^1.232.7 - version: 1.257.2 + version: 1.258.5 rxjs: specifier: ^7.8.2 version: 7.8.2 @@ -362,7 +362,7 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^16.2.2 - version: 16.2.16(@angular/compiler-cli@16.2.12(@angular/compiler@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3)))(typescript@5.1.6))(@angular/service-worker@16.2.12(@angular/common@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3))(rxjs@7.8.2))(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3)))(@swc/core@1.13.2(@swc/helpers@0.5.17))(@types/node@22.16.5)(html-webpack-plugin@5.6.3(@rspack/core@1.4.10(@swc/helpers@0.5.17))(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)))(karma@6.4.4)(lightningcss@1.30.1)(tailwindcss@3.4.14)(typescript@5.1.6) + version: 16.2.16(@angular/compiler-cli@16.2.12(@angular/compiler@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3)))(typescript@5.1.6))(@angular/service-worker@16.2.12(@angular/common@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3))(rxjs@7.8.2))(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3)))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.17.0)(html-webpack-plugin@5.6.3(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)))(karma@6.4.4)(lightningcss@1.30.1)(tailwindcss@3.4.14)(typescript@5.1.6) '@angular-eslint/builder': specifier: 18.3.0 version: 18.3.0(eslint@8.57.1)(typescript@5.1.6) @@ -374,7 +374,7 @@ importers: version: 18.0.0(eslint@8.57.1)(typescript@5.1.6) '@angular-eslint/schematics': specifier: 16.2.0 - version: 16.2.0(@angular/cli@16.2.16(chokidar@3.5.3))(@swc/core@1.13.2(@swc/helpers@0.5.17))(eslint@8.57.1)(typescript@5.1.6) + version: 16.2.0(@angular/cli@16.2.16(chokidar@3.5.3))(@swc/core@1.13.3(@swc/helpers@0.5.17))(eslint@8.57.1)(typescript@5.1.6) '@angular-eslint/template-parser': specifier: 18.3.0 version: 18.3.0(eslint@8.57.1)(typescript@5.1.6) @@ -389,7 +389,7 @@ importers: version: 18.2.13 '@bufbuild/buf': specifier: ^1.55.1 - version: 1.55.1 + version: 1.56.0 '@netlify/framework-info': specifier: ^9.8.13 version: 9.9.3 @@ -410,7 +410,7 @@ importers: version: 9.0.10 '@types/node': specifier: ^22.5.5 - version: 22.16.5 + version: 22.17.0 '@types/opentype.js': specifier: ^1.3.8 version: 1.3.8 @@ -467,22 +467,22 @@ importers: dependencies: '@bufbuild/buf': specifier: ^1.14.0 - version: 1.55.1 + version: 1.56.0 '@docusaurus/core': specifier: ^3.8.1 - version: 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) + version: 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/faster': specifier: ^3.8.1 - version: 3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17) + version: 3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17) '@docusaurus/preset-classic': specifier: ^3.8.1 - version: 3.8.1(@algolia/client-search@5.34.1)(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.8.3) + version: 3.8.1(@algolia/client-search@5.35.0)(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2) '@docusaurus/theme-mermaid': specifier: ^3.8.1 - version: 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) + version: 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/theme-search-algolia': specifier: ^3.8.1 - version: 3.8.1(@algolia/client-search@5.34.1)(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.8.3) + version: 3.8.1(@algolia/client-search@5.35.0)(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2) '@headlessui/react': specifier: ^1.7.4 version: 1.7.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -494,7 +494,7 @@ importers: version: 0.5.96(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@3.25.76) '@signalwire/docusaurus-plugin-llms-txt': specifier: ^1.2.0 - version: 1.2.2(@docusaurus/core@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)) + version: 1.2.2(@docusaurus/core@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)) autoprefixer: specifier: ^10.4.13 version: 10.4.21(postcss@8.5.3) @@ -503,25 +503,25 @@ importers: version: 1.2.1 docusaurus-plugin-image-zoom: specifier: ^3.0.1 - version: 3.0.1(@docusaurus/theme-classic@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)) + version: 3.0.1(@docusaurus/theme-classic@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)) docusaurus-plugin-openapi-docs: specifier: 4.4.0 - version: 4.4.0(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@docusaurus/utils-validation@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@docusaurus/utils@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(encoding@0.1.13)(react@18.3.1) + version: 4.4.0(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@docusaurus/utils-validation@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@docusaurus/utils@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(encoding@0.1.13)(react@18.3.1) docusaurus-theme-github-codeblock: specifier: ^2.0.2 - version: 2.0.2(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 2.0.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) docusaurus-theme-openapi-docs: specifier: 4.4.0 - version: 4.4.0(16229fb59c6dfb52093786e71d2a5baa) + version: 4.4.0(29feb2096fefbad47784d0fa17fc3949) mdx-mermaid: specifier: ^2.0.0 - version: 2.0.3(mermaid@11.9.0)(react@18.3.1)(typescript@5.8.3)(unist-util-visit@5.0.0) + version: 2.0.3(mermaid@11.9.0)(react@18.3.1)(typescript@5.9.2)(unist-util-visit@5.0.0) postcss: specifier: ^8.4.31 version: 8.5.3 raw-loader: specifier: ^4.0.2 - version: 4.0.2(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + version: 4.0.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) react: specifier: ^18.2.0 version: 18.3.1 @@ -540,10 +540,10 @@ importers: devDependencies: '@docusaurus/module-type-aliases': specifier: ^3.8.1 - version: 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/types': specifier: ^3.8.1 - version: 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) tailwindcss: specifier: ^3.2.4 version: 3.4.14 @@ -552,10 +552,10 @@ importers: devDependencies: '@types/node': specifier: ^22.3.0 - version: 22.16.5 + version: 22.17.0 '@types/pg': specifier: ^8.11.6 - version: 8.15.4 + version: 8.15.5 cypress: specifier: ^14.5.3 version: 14.5.3 @@ -576,7 +576,7 @@ importers: version: 3.6.2 typescript: specifier: ^5.5.4 - version: 5.8.3 + version: 5.9.2 uuid: specifier: ^10.0.0 version: 10.0.0 @@ -591,13 +591,13 @@ importers: version: 2.6.2 '@connectrpc/connect': specifier: ^2.0.0 - version: 2.0.2(@bufbuild/protobuf@2.6.2) + version: 2.0.3(@bufbuild/protobuf@2.6.2) '@connectrpc/connect-node': specifier: ^2.0.0 - version: 2.0.2(@bufbuild/protobuf@2.6.2)(@connectrpc/connect@2.0.2(@bufbuild/protobuf@2.6.2)) + version: 2.0.3(@bufbuild/protobuf@2.6.2)(@connectrpc/connect@2.0.3(@bufbuild/protobuf@2.6.2)) '@connectrpc/connect-web': specifier: ^2.0.0 - version: 2.0.2(@bufbuild/protobuf@2.6.2)(@connectrpc/connect@2.0.2(@bufbuild/protobuf@2.6.2)) + version: 2.0.3(@bufbuild/protobuf@2.6.2)(@connectrpc/connect@2.0.3(@bufbuild/protobuf@2.6.2)) '@zitadel/proto': specifier: workspace:* version: link:../zitadel-proto @@ -607,31 +607,31 @@ importers: devDependencies: '@bufbuild/buf': specifier: ^1.53.0 - version: 1.55.1 + version: 1.56.0 '@bufbuild/protocompile': specifier: ^0.0.1 - version: 0.0.1(@bufbuild/buf@1.55.1) + version: 0.0.1(@bufbuild/buf@1.56.0) '@types/node': specifier: ^24.0.14 version: 24.1.0 '@typescript-eslint/eslint-plugin': specifier: ^8.15.0 - version: 8.38.0(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3) + version: 8.38.0(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.35.1 - version: 8.38.0(eslint@8.57.1)(typescript@5.8.3) + version: 8.38.0(eslint@8.57.1)(typescript@5.9.2) eslint: specifier: ^8.57.0 version: 8.57.1 knip: specifier: ^5.61.3 - version: 5.62.0(@types/node@24.1.0)(typescript@5.8.3) + version: 5.62.0(@types/node@24.1.0)(typescript@5.9.2) tsup: specifier: ^8.4.0 - version: 8.5.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(jiti@2.5.0)(postcss@8.5.6)(typescript@5.8.3)(yaml@2.8.0) + version: 8.5.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(jiti@2.5.1)(postcss@8.5.6)(typescript@5.9.2)(yaml@2.8.0) typescript: specifier: ^5.8.3 - version: 5.8.3 + version: 5.9.2 vitest: specifier: ^2.0.0 version: 2.1.9(@types/node@24.1.0)(jsdom@26.1.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1) @@ -644,7 +644,7 @@ importers: devDependencies: '@bufbuild/buf': specifier: ^1.55.1 - version: 1.55.1 + version: 1.56.0 glob: specifier: ^11.0.0 version: 11.0.3 @@ -654,6 +654,10 @@ packages: '@adobe/css-tools@4.4.3': resolution: {integrity: sha512-VQKMkwriZbaOgVCby1UDY/LDk5fIjhQicCvVPFqfe+69fWaPWydbWJ3wRt59/YzIwda1I81loas3oCoHxnqvdA==} + '@algolia/abtesting@1.1.0': + resolution: {integrity: sha512-sEyWjw28a/9iluA37KLGu8vjxEIlb60uxznfTUmXImy7H5NvbpSO6yYgmgH5KiD7j+zTUUihiST0jEP12IoXow==} + engines: {node: '>= 14.0.0'} + '@algolia/autocomplete-core@1.17.9': resolution: {integrity: sha512-O7BxrpLDPJWWHv/DLA9DRFWs+iY1uOJZkqUwjS5HSZAGcl0hIVCQ97LTLewiZmZ402JYUrun+8NqFP+hCknlbQ==} @@ -674,59 +678,59 @@ packages: '@algolia/client-search': '>= 4.9.1 < 6' algoliasearch: '>= 4.9.1 < 6' - '@algolia/client-abtesting@5.34.1': - resolution: {integrity: sha512-M4zb6J7q+pg9V9Xk0k1WDgvupfCtXcxjKGTrNVYemiredLVGOmvVIPAUjg2rx4QmK7DWNApWLsieYwk7PAaOXw==} + '@algolia/client-abtesting@5.35.0': + resolution: {integrity: sha512-uUdHxbfHdoppDVflCHMxRlj49/IllPwwQ2cQ8DLC4LXr3kY96AHBpW0dMyi6ygkn2MtFCc6BxXCzr668ZRhLBQ==} engines: {node: '>= 14.0.0'} - '@algolia/client-analytics@5.34.1': - resolution: {integrity: sha512-h18zlL+bVUlbNE92olo1d/r6HQPkxhmP7yCpA1osERwpgC6F058kWm0O0aYdrHJIHtWBcs9aRqq7IkQSkpjPJg==} + '@algolia/client-analytics@5.35.0': + resolution: {integrity: sha512-SunAgwa9CamLcRCPnPHx1V2uxdQwJGqb1crYrRWktWUdld0+B2KyakNEeVn5lln4VyeNtW17Ia7V7qBWyM/Skw==} engines: {node: '>= 14.0.0'} - '@algolia/client-common@5.34.1': - resolution: {integrity: sha512-otPWALs72KvmVuP0CN0DI6sqVx1jQWKi+/DgAiP8DysVMgiNlva3GDKTtAK6XVGlT08f4h32FNuL0yQODuCfKA==} + '@algolia/client-common@5.35.0': + resolution: {integrity: sha512-ipE0IuvHu/bg7TjT2s+187kz/E3h5ssfTtjpg1LbWMgxlgiaZIgTTbyynM7NfpSJSKsgQvCQxWjGUO51WSCu7w==} engines: {node: '>= 14.0.0'} - '@algolia/client-insights@5.34.1': - resolution: {integrity: sha512-SNDb5wuEpQFM6S5Shk2iytLMusvGycm9uTuYh7cGa1h3U7O65OjjjIgQ0lLY5HPybHNtmXr4Zh/EZ23pZvAJHg==} + '@algolia/client-insights@5.35.0': + resolution: {integrity: sha512-UNbCXcBpqtzUucxExwTSfAe8gknAJ485NfPN6o1ziHm6nnxx97piIbcBQ3edw823Tej2Wxu1C0xBY06KgeZ7gA==} engines: {node: '>= 14.0.0'} - '@algolia/client-personalization@5.34.1': - resolution: {integrity: sha512-T8z9KqYJOup83Hw0mgICYWfJoLh//FNWbf4roFd95ZJzZ4v1cN/hvr7Eqml1qWMoCkJb4y/XQjrXsJ6Y9XnMLw==} + '@algolia/client-personalization@5.35.0': + resolution: {integrity: sha512-/KWjttZ6UCStt4QnWoDAJ12cKlQ+fkpMtyPmBgSS2WThJQdSV/4UWcqCUqGH7YLbwlj3JjNirCu3Y7uRTClxvA==} engines: {node: '>= 14.0.0'} - '@algolia/client-query-suggestions@5.34.1': - resolution: {integrity: sha512-YA0kC4CwO1mc1dliNgbFgToweRa7Uihjz3izEaV4cXninF1v4SaOrPkQUsiFPprAffjMzOUoT7vahQZ/HZyiKQ==} + '@algolia/client-query-suggestions@5.35.0': + resolution: {integrity: sha512-8oCuJCFf/71IYyvQQC+iu4kgViTODbXDk3m7yMctEncRSRV+u2RtDVlpGGfPlJQOrAY7OONwJlSHkmbbm2Kp/w==} engines: {node: '>= 14.0.0'} - '@algolia/client-search@5.34.1': - resolution: {integrity: sha512-bt5hC9vvjaKvdvsgzfXJ42Sl3qjQqoi/FD8V7HOQgtNFhwSauZOlgLwFoUiw67sM+r7ehF7QDk5WRDgY7fAkIg==} + '@algolia/client-search@5.35.0': + resolution: {integrity: sha512-FfmdHTrXhIduWyyuko1YTcGLuicVbhUyRjO3HbXE4aP655yKZgdTIfMhZ/V5VY9bHuxv/fGEh3Od1Lvv2ODNTg==} engines: {node: '>= 14.0.0'} '@algolia/events@4.0.1': resolution: {integrity: sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==} - '@algolia/ingestion@1.34.1': - resolution: {integrity: sha512-QLxiBskQxFGzPqKZvBNEvNN95kgDCbBd2X29ZGfh6Sr2QOSU34US6Z9x2duiF4o9FwsB0i6eQ2c9vHfuH0lAQg==} + '@algolia/ingestion@1.35.0': + resolution: {integrity: sha512-gPzACem9IL1Co8mM1LKMhzn1aSJmp+Vp434An4C0OBY4uEJRcqsLN3uLBlY+bYvFg8C8ImwM9YRiKczJXRk0XA==} engines: {node: '>= 14.0.0'} - '@algolia/monitoring@1.34.1': - resolution: {integrity: sha512-NteCvWcWXXdnPGyZH8rXHslcf2pM1WGDNMGNZFXLFtOt1Gf1Tjy2t0NZLp+Mxap3JMV4mbYmactbXrvpQf/lLA==} + '@algolia/monitoring@1.35.0': + resolution: {integrity: sha512-w9MGFLB6ashI8BGcQoVt7iLgDIJNCn4OIu0Q0giE3M2ItNrssvb8C0xuwJQyTy1OFZnemG0EB1OvXhIHOvQwWw==} engines: {node: '>= 14.0.0'} - '@algolia/recommend@5.34.1': - resolution: {integrity: sha512-UdgDSrunLIBAAAxQlYLXYLnYFN4wkzkrAYx+wMLEk/pzASWyza3BkecbUFVqoYOBIgwo7Mt4iymzVtFkzL2uCQ==} + '@algolia/recommend@5.35.0': + resolution: {integrity: sha512-AhrVgaaXAb8Ue0u2nuRWwugt0dL5UmRgS9LXe0Hhz493a8KFeZVUE56RGIV3hAa6tHzmAV7eIoqcWTQvxzlJeQ==} engines: {node: '>= 14.0.0'} - '@algolia/requester-browser-xhr@5.34.1': - resolution: {integrity: sha512-567LfFTc9VOiPtuySQohoqaWMeohYWbXK71aMSin+SLMgeKX7hz5LrVmkmMQj9udwWK6/mtHEYZGPYHSuXpLQg==} + '@algolia/requester-browser-xhr@5.35.0': + resolution: {integrity: sha512-diY415KLJZ6x1Kbwl9u96Jsz0OstE3asjXtJ9pmk1d+5gPuQ5jQyEsgC+WmEXzlec3iuVszm8AzNYYaqw6B+Zw==} engines: {node: '>= 14.0.0'} - '@algolia/requester-fetch@5.34.1': - resolution: {integrity: sha512-YRbygPgGBEik5U593JvyjgxFjcsyZMR25eIQxNHvSQumdAzt5A4E4Idw3yXnwhrmMdjML54ZXT7EAjnTjWy8Xw==} + '@algolia/requester-fetch@5.35.0': + resolution: {integrity: sha512-uydqnSmpAjrgo8bqhE9N1wgcB98psTRRQXcjc4izwMB7yRl9C8uuAQ/5YqRj04U0mMQ+fdu2fcNF6m9+Z1BzDQ==} engines: {node: '>= 14.0.0'} - '@algolia/requester-node-http@5.34.1': - resolution: {integrity: sha512-o0mqRYbS82Rt4DE02Od7RL6pNtV7oSxScPuIw8LW4aqO2V5eCF05Pry/SnUgcI/Vb2QCYC66hytBCqzyC/toZA==} + '@algolia/requester-node-http@5.35.0': + resolution: {integrity: sha512-RgLX78ojYOrThJHrIiPzT4HW3yfQa0D7K+MQ81rhxqaNyNBu4F1r+72LNHYH/Z+y9I1Mrjrd/c/Ue5zfDgAEjQ==} engines: {node: '>= 14.0.0'} '@alloc/quick-lru@5.2.0': @@ -1739,50 +1743,50 @@ packages: '@braintree/sanitize-url@7.1.1': resolution: {integrity: sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==} - '@bufbuild/buf-darwin-arm64@1.55.1': - resolution: {integrity: sha512-g76yEF2ALyjj+R8KVoIjPPS7zaPy6VDWg2b5PCCK04fKTbe5jyzOdYdvNyuM5hO8xpRPBjBrqO6LUAfS+0aRCQ==} + '@bufbuild/buf-darwin-arm64@1.56.0': + resolution: {integrity: sha512-9neaI9gx1sxOGl9xrL7kw6H+0WmVAFlIQTIDc3vt1qRhfgOt/8AWOHSOWppGTRjNiB0qh6Xie1LYHv/jgDVN0g==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] - '@bufbuild/buf-darwin-x64@1.55.1': - resolution: {integrity: sha512-hCkatzlV7DwHWEyzzcpsZgLtxABidT/EYBmLTy6oSCHimOJzR1c5ezKe75tX7myDAfV0HZExIM7+cSsWg3dTPg==} + '@bufbuild/buf-darwin-x64@1.56.0': + resolution: {integrity: sha512-nRHPMXV8fr/lqU+u/1GGsUg7OvNcxJuCJoJpfRoRg38b+NPzOz2FkQAs5OEJzzprQB5aftn5//cl8YXjgvTuFA==} engines: {node: '>=12'} cpu: [x64] os: [darwin] - '@bufbuild/buf-linux-aarch64@1.55.1': - resolution: {integrity: sha512-hA4jGPZ2N+FUZt03w+hPt6YsbhAdOh2gNKBQnuysj8kdTqZ4mw1wCOUoRg9h7eqOr/2XCcOibWYO36H2eS2OYQ==} + '@bufbuild/buf-linux-aarch64@1.56.0': + resolution: {integrity: sha512-+td559RuKNwYDnq49NrIDGJ4F73Ra4QzVVbsC+UeveA0HMnIGRzFbchGjHtNJyaZsI57sXJ7dCHH0iFV3jcYwQ==} engines: {node: '>=12'} cpu: [arm64] os: [linux] - '@bufbuild/buf-linux-armv7@1.55.1': - resolution: {integrity: sha512-npnzJSAZRUdh8+fmgsbXt+dogA+iU/i/qWh+3XhdLXW220nWpd1jAXcpquaVfer8EwMEcYjqVf8FA7IXOgjGXw==} + '@bufbuild/buf-linux-armv7@1.56.0': + resolution: {integrity: sha512-9v3zmos6wRTBc4QeIg4rfDmPzmTgtUTRCbhr87qws/yddIT8cFtHHhy1whnozBNqtmYOdwZNBNx/QXqGGcRuKw==} engines: {node: '>=12'} cpu: [arm] os: [linux] - '@bufbuild/buf-linux-x64@1.55.1': - resolution: {integrity: sha512-/48IjSA1kh/8kZl1bcDkikgH+9BMnPhhVqad+R7+3ttYOFqifet3n+hf2ipA26NtTpTfvOSRXj1tdx/80x0I1g==} + '@bufbuild/buf-linux-x64@1.56.0': + resolution: {integrity: sha512-3jZHHBol1fuichNke7LJtHJUdw314XBj6OuJHY6IufsaaVIj1mtM2DPbGiDhYB453J7FiV/buadctKBxAAHclg==} engines: {node: '>=12'} cpu: [x64] os: [linux] - '@bufbuild/buf-win32-arm64@1.55.1': - resolution: {integrity: sha512-CE+jAN1ikRTIdny6Q/geccKsLhy4QEXzUaJUfAiUXqjSW2u/Et7+p9Wh6xUgXcSuIoz1aw8MVuCESrNMBt6LBg==} + '@bufbuild/buf-win32-arm64@1.56.0': + resolution: {integrity: sha512-KMGzSf9rIbT01Jb2685JovwRRYEdL7Zbs6ZrjyhIHBgKK6cBwz1AJvEaDrWMEzCdv+opQwjgM6UdtA4e9BWP1A==} engines: {node: '>=12'} cpu: [arm64] os: [win32] - '@bufbuild/buf-win32-x64@1.55.1': - resolution: {integrity: sha512-C4VYS96YBJkLhIKH6yh8BqHgIjqGe+G6yuAOOKxWsYdx3QbT5LYOr38AP1bzkFm0Gz9jOOr5n0pmAFwsOLYjiw==} + '@bufbuild/buf-win32-x64@1.56.0': + resolution: {integrity: sha512-19LFOCyFFVTaaqNGtYTpiF67fcpneWZFlm8UNU+Xs87Kh+N5i/LjDjNytnpFT6snwU4/S+UUkq7WgS6UPjqXIg==} engines: {node: '>=12'} cpu: [x64] os: [win32] - '@bufbuild/buf@1.55.1': - resolution: {integrity: sha512-V9tpe2XlRVyq33cct2lNz9nDDQG95WbPKlxQkMKt5i7tPsfqE3vzbGiEC96K0QJWhIU28OkjYD8+1SyYKBWVYg==} + '@bufbuild/buf@1.56.0': + resolution: {integrity: sha512-1xQWOf3FCDDTi+5B/VScQ73EP6ACwQPCP4ODvCq2L6IVgFtvYX49ur6cQ2qCM8yFitIHESm/Nbff93sh+V/Iog==} engines: {node: '>=12'} hasBin: true @@ -1868,21 +1872,21 @@ packages: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} - '@connectrpc/connect-node@2.0.2': - resolution: {integrity: sha512-33Ut3SRkb6SugpwVCtXXRvUrOdtiyG6z6d5+eijBOLOI75sw1tDCwcs0o/9WL3rUj1M08dLUrPmJB47fjpv6EA==} + '@connectrpc/connect-node@2.0.3': + resolution: {integrity: sha512-GZ8WXBCeoZY31wzmnrrV4IA0nvYzEwqt9yHg304b7y/ovKh0IEbBuSWbee/hJu2Tt7PD0C8D4WUwheECCeLpQA==} engines: {node: '>=18.14.1'} peerDependencies: '@bufbuild/protobuf': ^2.2.0 - '@connectrpc/connect': 2.0.2 + '@connectrpc/connect': 2.0.3 - '@connectrpc/connect-web@2.0.2': - resolution: {integrity: sha512-QANMFPiL2o66BdBEctg4TsQLe5ozsBLqcle3dCBp7BwGlNGTY6NnNnqmt+YRnpeMW88GgomJwWNMGCrRD9pRKA==} + '@connectrpc/connect-web@2.0.3': + resolution: {integrity: sha512-w4LZ2Ci+NW/kcMoHnoczJgyGTmxuv/MQ+tTm2UNL40HimXKWYCAna/fV0AbHRnTiteiwEBpeSCaxF34MetzhAw==} peerDependencies: '@bufbuild/protobuf': ^2.2.0 - '@connectrpc/connect': 2.0.2 + '@connectrpc/connect': 2.0.3 - '@connectrpc/connect@2.0.2': - resolution: {integrity: sha512-xZuylIUNvNlH52e/4eQsZvY4QZyDJRtEFEDnn/yBrv5Xi5ZZI/p8X+GAHH35ucVaBvv9u7OzHZo8+tEh1EFTxA==} + '@connectrpc/connect@2.0.3': + resolution: {integrity: sha512-jAbVMHVtDCydGt2P20VpmLjbLtERqSV0RMSyQF3k2zhK8pzQ2QaCAcyVhufClqrOAFZUKL5BqVYtttaxvhmRgg==} peerDependencies: '@bufbuild/protobuf': ^2.2.0 @@ -2155,10 +2159,6 @@ packages: resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==} engines: {node: '>=10'} - '@cypress/request@3.0.8': - resolution: {integrity: sha512-h0NFgh1mJmm1nr4jCwkGHwKneVYKghUyWe6TMNrk0B9zsjAJxpg8C4/+BAcmLgCPa1vj1V8rNUaILl+zYRUWBQ==} - engines: {node: '>= 6'} - '@cypress/request@3.0.9': resolution: {integrity: sha512-I3l7FdGRXluAS44/0NguwWlO83J18p0vlr2FYHrJkWdNYhgVoiYo61IXPqaOsL+vNxU1ZqMACzItGK3/KKDsdw==} engines: {node: '>= 6'} @@ -2839,14 +2839,14 @@ packages: resolution: {integrity: sha512-OEl393iCOoo/z8bMezRlJu+GlRGlsKbUAN7jKB6LhnKoqKve5DXRpalbItIIcwnCjs1k/FOPjFzcA6Qn+H+YbA==} engines: {node: '>=18.0.0', npm: '>=9.0.0'} - '@floating-ui/core@1.7.2': - resolution: {integrity: sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw==} + '@floating-ui/core@1.7.3': + resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} - '@floating-ui/dom@1.7.2': - resolution: {integrity: sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA==} + '@floating-ui/dom@1.7.3': + resolution: {integrity: sha512-uZA413QEpNuhtb3/iIKoYMSK07keHPYeXF02Zhd6e213j+d1NamLix/mCLxBUDW/Gx52sPH2m+chlUsyaBs/Ag==} - '@floating-ui/react-dom@2.1.4': - resolution: {integrity: sha512-JbbpPhp38UmXDDAu60RJmbeme37Jbgsm7NrHGgzYYFKmblzRUh6Pa641dII6LsjwF4XlScDrde2UAzDo/b9KPw==} + '@floating-ui/react-dom@2.1.5': + resolution: {integrity: sha512-HDO/1/1oH9fjj4eLgegrlH3dklZpHtUYYFiVwMUwfGvk9jWDRWqkklA2/NFScknrcNSspbV868WjXORvreDX+Q==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' @@ -2921,8 +2921,8 @@ packages: react: ^16 || ^17 || ^18 react-dom: ^16 || ^17 || ^18 - '@headlessui/react@2.2.5': - resolution: {integrity: sha512-h1+2Vu1yR5pp/fBcTnwVEW8Kb94Hbxp7MXZLORfDzvSrbmGgiTyaTZ4LI/tPNZnK8eDrYD9s9cMbjm5HS5otIQ==} + '@headlessui/react@2.2.7': + resolution: {integrity: sha512-WKdTymY8Y49H8/gUc/lIyYK1M+/6dq0Iywh4zTZVAaiTDprRfioxSgD0wnXTQTBpjpGJuTL1NO/mqEvc//5SSg==} engines: {node: '>=10'} peerDependencies: react: ^18 || ^19 || ^19.0.0-rc @@ -3333,23 +3333,23 @@ packages: '@mermaid-js/parser@0.6.2': resolution: {integrity: sha512-+PO02uGF6L6Cs0Bw8RpGhikVvMWEysfAyl27qTlroUB8jSWr1lL0Sf6zi78ZxlSnmgSY2AMMKVgghnN9jTtwkQ==} - '@module-federation/error-codes@0.17.0': - resolution: {integrity: sha512-+pZ12frhaDqh4Xs/MQj4Vu4CAjnJTiEb8Z6fqPfn/TLHh4YLWMOzpzxGuMFDHqXwMb3o8FRAUhNB0eX2ZmhwTA==} + '@module-federation/error-codes@0.17.1': + resolution: {integrity: sha512-n6Elm4qKSjwAPxLUGtwnl7qt4y1dxB8OpSgVvXBIzqI9p27a3ZXshLPLnumlpPg1Qudaj8sLnSnFtt9yGpt5yQ==} - '@module-federation/runtime-core@0.17.0': - resolution: {integrity: sha512-MYwDDevYnBB9gXFfNOmJVIX5XZcbCHd0dral7gT7yVmlwOhbuGOLlm2dh2icwwdCYHA9AFDCfU9l1nJR4ex/ng==} + '@module-federation/runtime-core@0.17.1': + resolution: {integrity: sha512-LCtIFuKgWPQ3E+13OyrVpuTPOWBMI/Ggwsq1Q874YeT8Px28b8tJRCj09DjyRFyhpSPyV/uG80T6iXPAUoLIfQ==} - '@module-federation/runtime-tools@0.17.0': - resolution: {integrity: sha512-t4QcKfhmwOHedwByDKUlTQVw4+gPotySYPyNa8GFrBSr1F6wcGdGyOhzP+PdgpiJLIM03cB6V+IKGGHE28SfDQ==} + '@module-federation/runtime-tools@0.17.1': + resolution: {integrity: sha512-4kr6zTFFwGywJx6whBtxsc84V+COAuuBpEdEbPZN//YLXhNB0iz2IGsy9r9wDl+06h84bD+3dQ05l9euRLgXzQ==} - '@module-federation/runtime@0.17.0': - resolution: {integrity: sha512-eMtrtCSSV6neJpMmQ8WdFpYv93raSgsG5RiAPsKUuSCXfZ5D+yzvleZ+gPcEpFT9HokmloxAn0jep50/1upTQw==} + '@module-federation/runtime@0.17.1': + resolution: {integrity: sha512-vKEN32MvUbpeuB/s6UXfkHDZ9N5jFyDDJnj83UTJ8n4N1jHIJu9VZ6Yi4/Ac8cfdvU8UIK9bIbfVXWbUYZUDsw==} - '@module-federation/sdk@0.17.0': - resolution: {integrity: sha512-tjrNaYdDocHZsWu5iXlm83lwEK8A64r4PQB3/kY1cW1iOvggR2RESLAWPxRJXC2cLF8fg8LDKOBdgERZW1HPFA==} + '@module-federation/sdk@0.17.1': + resolution: {integrity: sha512-nlUcN6UTEi+3HWF+k8wPy7gH0yUOmCT+xNatihkIVR9REAnr7BUvHFGlPJmx7WEbLPL46+zJUbtQHvLzXwFhng==} - '@module-federation/webpack-bundler-runtime@0.17.0': - resolution: {integrity: sha512-o8XtXwqTDlqLgcALOfObcCbqXvUcSDHIEXrkcb4W+I8GJY7IqV0+x6rX4mJ3f59tca9qOF8zsZsOA6BU93Pvgw==} + '@module-federation/webpack-bundler-runtime@0.17.1': + resolution: {integrity: sha512-Swspdgf4PzcbvS9SNKFlBzfq8h/Qxwqjq/xRSqw1pqAZWondZQzwTTqPXhgrg0bFlz7qWjBS/6a8KuH/gRvGaQ==} '@napi-rs/wasm-runtime@0.2.12': resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} @@ -3750,8 +3750,8 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@playwright/test@1.54.1': - resolution: {integrity: sha512-FS8hQ12acieG2dYSksmLOF7BNxnVf2afRJdCuM1eMSxj6QTSE6G4InGF7oApGgDb65MX7AwMVlIkpru0yZA4Xw==} + '@playwright/test@1.54.2': + resolution: {integrity: sha512-A+znathYxPf+72riFd1r1ovOLqsIIB0jKIoPjyK2kqEIe30/6jF6BC7QNluHuwUmsD2tv1XZVugN8GqfTMOxsA==} engines: {node: '>=18'} hasBin: true @@ -4506,14 +4506,14 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@redocly/ajv@8.11.2': - resolution: {integrity: sha512-io1JpnwtIcvojV7QKDUSIuMN/ikdOUd1ReEnUnMKGfDVridQZ31J0MmIuqwuRjWDZfmvr+Q0MqCcfHM2gTivOg==} + '@redocly/ajv@8.11.3': + resolution: {integrity: sha512-4P3iZse91TkBiY+Dx5DUgxQ9GXkVJf++cmI0MOyLDxV9b5MUBI4II6ES8zA5JCbO72nKAJxWrw4PUPW+YP3ZDQ==} '@redocly/config@0.22.2': resolution: {integrity: sha512-roRDai8/zr2S9YfmzUfNhKjOF0NdcOIqF7bhf4MVC5UxpjIysDjyudvlAiVbpPHp3eDRWbdzUgtkK1a7YiDNyQ==} - '@redocly/openapi-core@1.34.3': - resolution: {integrity: sha512-3arRdUp1fNx55itnjKiUhO6t4Mf91TsrTIYINDNLAZPS0TPd5YpiXRctwjel0qqWoOOhjA34cZ3m4dksLDFUYg==} + '@redocly/openapi-core@1.34.5': + resolution: {integrity: sha512-0EbE8LRbkogtcCXU7liAyC00n9uNG9hJ+eMyHFdUsy9lB/WGqnEBgwjA9q2cyzAVcdTkQqTBBU1XePNnN3OijA==} engines: {node: '>=18.17.0', npm: '>=9.5.0'} '@reduxjs/toolkit@1.9.7': @@ -4530,160 +4530,160 @@ packages: '@rolldown/pluginutils@1.0.0-beta.27': resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} - '@rollup/rollup-android-arm-eabi@4.45.1': - resolution: {integrity: sha512-NEySIFvMY0ZQO+utJkgoMiCAjMrGvnbDLHvcmlA33UXJpYBCvlBEbMMtV837uCkS+plG2umfhn0T5mMAxGrlRA==} + '@rollup/rollup-android-arm-eabi@4.46.2': + resolution: {integrity: sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.45.1': - resolution: {integrity: sha512-ujQ+sMXJkg4LRJaYreaVx7Z/VMgBBd89wGS4qMrdtfUFZ+TSY5Rs9asgjitLwzeIbhwdEhyj29zhst3L1lKsRQ==} + '@rollup/rollup-android-arm64@4.46.2': + resolution: {integrity: sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.45.1': - resolution: {integrity: sha512-FSncqHvqTm3lC6Y13xncsdOYfxGSLnP+73k815EfNmpewPs+EyM49haPS105Rh4aF5mJKywk9X0ogzLXZzN9lA==} + '@rollup/rollup-darwin-arm64@4.46.2': + resolution: {integrity: sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.45.1': - resolution: {integrity: sha512-2/vVn/husP5XI7Fsf/RlhDaQJ7x9zjvC81anIVbr4b/f0xtSmXQTFcGIQ/B1cXIYM6h2nAhJkdMHTnD7OtQ9Og==} + '@rollup/rollup-darwin-x64@4.46.2': + resolution: {integrity: sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.45.1': - resolution: {integrity: sha512-4g1kaDxQItZsrkVTdYQ0bxu4ZIQ32cotoQbmsAnW1jAE4XCMbcBPDirX5fyUzdhVCKgPcrwWuucI8yrVRBw2+g==} + '@rollup/rollup-freebsd-arm64@4.46.2': + resolution: {integrity: sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.45.1': - resolution: {integrity: sha512-L/6JsfiL74i3uK1Ti2ZFSNsp5NMiM4/kbbGEcOCps99aZx3g8SJMO1/9Y0n/qKlWZfn6sScf98lEOUe2mBvW9A==} + '@rollup/rollup-freebsd-x64@4.46.2': + resolution: {integrity: sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.45.1': - resolution: {integrity: sha512-RkdOTu2jK7brlu+ZwjMIZfdV2sSYHK2qR08FUWcIoqJC2eywHbXr0L8T/pONFwkGukQqERDheaGTeedG+rra6Q==} + '@rollup/rollup-linux-arm-gnueabihf@4.46.2': + resolution: {integrity: sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.45.1': - resolution: {integrity: sha512-3kJ8pgfBt6CIIr1o+HQA7OZ9mp/zDk3ctekGl9qn/pRBgrRgfwiffaUmqioUGN9hv0OHv2gxmvdKOkARCtRb8Q==} + '@rollup/rollup-linux-arm-musleabihf@4.46.2': + resolution: {integrity: sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.45.1': - resolution: {integrity: sha512-k3dOKCfIVixWjG7OXTCOmDfJj3vbdhN0QYEqB+OuGArOChek22hn7Uy5A/gTDNAcCy5v2YcXRJ/Qcnm4/ma1xw==} + '@rollup/rollup-linux-arm64-gnu@4.46.2': + resolution: {integrity: sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.45.1': - resolution: {integrity: sha512-PmI1vxQetnM58ZmDFl9/Uk2lpBBby6B6rF4muJc65uZbxCs0EA7hhKCk2PKlmZKuyVSHAyIw3+/SiuMLxKxWog==} + '@rollup/rollup-linux-arm64-musl@4.46.2': + resolution: {integrity: sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.45.1': - resolution: {integrity: sha512-9UmI0VzGmNJ28ibHW2GpE2nF0PBQqsyiS4kcJ5vK+wuwGnV5RlqdczVocDSUfGX/Na7/XINRVoUgJyFIgipoRg==} + '@rollup/rollup-linux-loongarch64-gnu@4.46.2': + resolution: {integrity: sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.45.1': - resolution: {integrity: sha512-7nR2KY8oEOUTD3pBAxIBBbZr0U7U+R9HDTPNy+5nVVHDXI4ikYniH1oxQz9VoB5PbBU1CZuDGHkLJkd3zLMWsg==} + '@rollup/rollup-linux-ppc64-gnu@4.46.2': + resolution: {integrity: sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.45.1': - resolution: {integrity: sha512-nlcl3jgUultKROfZijKjRQLUu9Ma0PeNv/VFHkZiKbXTBQXhpytS8CIj5/NfBeECZtY2FJQubm6ltIxm/ftxpw==} + '@rollup/rollup-linux-riscv64-gnu@4.46.2': + resolution: {integrity: sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.45.1': - resolution: {integrity: sha512-HJV65KLS51rW0VY6rvZkiieiBnurSzpzore1bMKAhunQiECPuxsROvyeaot/tcK3A3aGnI+qTHqisrpSgQrpgA==} + '@rollup/rollup-linux-riscv64-musl@4.46.2': + resolution: {integrity: sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.45.1': - resolution: {integrity: sha512-NITBOCv3Qqc6hhwFt7jLV78VEO/il4YcBzoMGGNxznLgRQf43VQDae0aAzKiBeEPIxnDrACiMgbqjuihx08OOw==} + '@rollup/rollup-linux-s390x-gnu@4.46.2': + resolution: {integrity: sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.45.1': - resolution: {integrity: sha512-+E/lYl6qu1zqgPEnTrs4WysQtvc/Sh4fC2nByfFExqgYrqkKWp1tWIbe+ELhixnenSpBbLXNi6vbEEJ8M7fiHw==} + '@rollup/rollup-linux-x64-gnu@4.46.2': + resolution: {integrity: sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.45.1': - resolution: {integrity: sha512-a6WIAp89p3kpNoYStITT9RbTbTnqarU7D8N8F2CV+4Cl9fwCOZraLVuVFvlpsW0SbIiYtEnhCZBPLoNdRkjQFw==} + '@rollup/rollup-linux-x64-musl@4.46.2': + resolution: {integrity: sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.45.1': - resolution: {integrity: sha512-T5Bi/NS3fQiJeYdGvRpTAP5P02kqSOpqiopwhj0uaXB6nzs5JVi2XMJb18JUSKhCOX8+UE1UKQufyD6Or48dJg==} + '@rollup/rollup-win32-arm64-msvc@4.46.2': + resolution: {integrity: sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.45.1': - resolution: {integrity: sha512-lxV2Pako3ujjuUe9jiU3/s7KSrDfH6IgTSQOnDWr9aJ92YsFd7EurmClK0ly/t8dzMkDtd04g60WX6yl0sGfdw==} + '@rollup/rollup-win32-ia32-msvc@4.46.2': + resolution: {integrity: sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.45.1': - resolution: {integrity: sha512-M/fKi4sasCdM8i0aWJjCSFm2qEnYRR8AMLG2kxp6wD13+tMGA4Z1tVAuHkNRjud5SW2EM3naLuK35w9twvf6aA==} + '@rollup/rollup-win32-x64-msvc@4.46.2': + resolution: {integrity: sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg==} cpu: [x64] os: [win32] - '@rspack/binding-darwin-arm64@1.4.10': - resolution: {integrity: sha512-PraYGuVSzvEwdoYC8T70qI/8j1QeUe2sysiWmjSdxUpxJsDfw35hK9TfxULeAJULlAUAiiXs03hdZk29DBc3ow==} + '@rspack/binding-darwin-arm64@1.4.11': + resolution: {integrity: sha512-PrmBVhR8MC269jo6uQ+BMy1uwIDx0HAJYLQRQur8gXiehWabUBCRg/d4U9KR7rLzdaSScRyc5JWXR52T7/4MfA==} cpu: [arm64] os: [darwin] - '@rspack/binding-darwin-x64@1.4.10': - resolution: {integrity: sha512-rWTSJ08TE0uqUjqAHkTmWqJu+FLSJ70A199Fk9k/FLZTS8UtHjuzZW7rv4qIN2nwJJLherxFUnP6y69cHuaGNw==} + '@rspack/binding-darwin-x64@1.4.11': + resolution: {integrity: sha512-YIV8Wzy+JY0SoSsVtN4wxFXOjzxxVPnVXNswrrfqVUTPr9jqGOFYUWCGpbt8lcCgfuBFm6zN8HpOsKm1xUNsVA==} cpu: [x64] os: [darwin] - '@rspack/binding-linux-arm64-gnu@1.4.10': - resolution: {integrity: sha512-cs6yu250FzRU1hl+02VLoJRdzbAveTOqvREeHgqL5AiTc6q1dQo1IZ16/Qt4+g0DMjnvM66pELRIO2nphXL8aA==} + '@rspack/binding-linux-arm64-gnu@1.4.11': + resolution: {integrity: sha512-ms6uwECUIcu+6e82C5HJhRMHnfsI+l33v7XQezntzRPN0+sG3EpikEoT7SGbgt4vDwaWLR7wS20suN4qd5r3GA==} cpu: [arm64] os: [linux] - '@rspack/binding-linux-arm64-musl@1.4.10': - resolution: {integrity: sha512-NnOAoWkpZvOa+xM7NAJg25O+tSKt6xCXoga+gOw5XPni1NxHDc3PNh5bU6fAmc2Z29YLLdxeVqPmIDfdk1EkDg==} + '@rspack/binding-linux-arm64-musl@1.4.11': + resolution: {integrity: sha512-9evq0DOdxMN/H8VM8ZmyY9NSuBgILNVV6ydBfVPMHPx4r1E7JZGpWeKDegZcS5Erw3sS9kVSIxyX78L5PDzzKw==} cpu: [arm64] os: [linux] - '@rspack/binding-linux-x64-gnu@1.4.10': - resolution: {integrity: sha512-FcaBqMclADWiqX+Mez15kggwaVYZkoEqDiQwYRpYDbBMsiJEtfp41GnNRstTWxYxFbcmuWoZl2cYy+LepR21ag==} + '@rspack/binding-linux-x64-gnu@1.4.11': + resolution: {integrity: sha512-bHYFLxPPYBOSaHdQbEoCYGMQ1gOrEWj7Mro/DLfSHZi1a0okcQ2Q1y0i1DczReim3ZhLGNrK7k1IpFXCRbAobQ==} cpu: [x64] os: [linux] - '@rspack/binding-linux-x64-musl@1.4.10': - resolution: {integrity: sha512-vgRQhCw+C/Nxv6MZVNUkPzSXs6kIWHIrGKUvOM1ceeAkT+jNFEQdukkQ5LsYgEqEwP9ezWubxN3IGrMxyimlPw==} + '@rspack/binding-linux-x64-musl@1.4.11': + resolution: {integrity: sha512-wrm4E7q2k4+cwT6Uhp6hIQ3eUe/YoaUttj6j5TqHYZX6YeLrNPtD9+ne6lQQ17BV8wmm6NZsmoFIJ5xIptpRhQ==} cpu: [x64] os: [linux] - '@rspack/binding-wasm32-wasi@1.4.10': - resolution: {integrity: sha512-lk647+Ob3yvVS2FgW0vCfo/gz9h0Q7v9HGBFcsD1uW0/tSqXMa2s9ZvIn+B7S9tRgIoosXEAuq8NeCXKGWVj5Q==} + '@rspack/binding-wasm32-wasi@1.4.11': + resolution: {integrity: sha512-hiYxHZjaZ17wQtXyLCK0IdtOvMWreGVTiGsaHCxyeT+SldDG+r16bXNjmlqfZsjlfl1mkAqKz1dg+mMX28OTqw==} cpu: [wasm32] - '@rspack/binding-win32-arm64-msvc@1.4.10': - resolution: {integrity: sha512-9mB3kh4pKaY4wFosZwuxb5EUtt7vv/uKW3OF4TJDC35bH7r54s+YYpHyXROT304r6URl4b6HNHlysL2m7BLihg==} + '@rspack/binding-win32-arm64-msvc@1.4.11': + resolution: {integrity: sha512-+HF/mnjmTr8PC1dccRt1bkrD2tPDGeqvXC1BBLYd/Klq1VbtIcnrhfmvQM6KaXbiLcY9VWKzcZPOTmnyZ8TaHQ==} cpu: [arm64] os: [win32] - '@rspack/binding-win32-ia32-msvc@1.4.10': - resolution: {integrity: sha512-DPlyLZDUWkNcFI7zp1BQVVnihd4j/hCIbxqvIKvUt7whIVYMP52i8lCsa52uNGBSj7BcbcKAFElXC9dHVvoQGA==} + '@rspack/binding-win32-ia32-msvc@1.4.11': + resolution: {integrity: sha512-EU2fQGwrRfwFd/tcOInlD0jy6gNQE4Q3Ayj0Is+cX77sbhPPyyOz0kZDEaQ4qaN2VU8w4Hu/rrD7c0GAKLFvCw==} cpu: [ia32] os: [win32] - '@rspack/binding-win32-x64-msvc@1.4.10': - resolution: {integrity: sha512-FEE6OM0Wh7nj90+1ARXojT0Dnqox9UlIUIj7MQmX09yeMtckR+HITeq75F8y0l7HUvKOl2zQovmenk1KgyJV8Q==} + '@rspack/binding-win32-x64-msvc@1.4.11': + resolution: {integrity: sha512-1Nc5ZzWqfvE+iJc47qtHFzYYnHsC3awavXrCo74GdGip1vxtksM3G30BlvAQHHVtEmULotWqPbjZpflw/Xk9Ag==} cpu: [x64] os: [win32] - '@rspack/binding@1.4.10': - resolution: {integrity: sha512-awiXN7qTTTLWFThbJFL+M4k1if4sb17xKA5TaHbbxs0qKSlpe3adwNrNHaNU2WOQz+PbuF++OMyd+4gUusKuVg==} + '@rspack/binding@1.4.11': + resolution: {integrity: sha512-maGl/zRwnl0QVwkBCkgjn5PH20L9HdlRIdkYhEsfTepy5x2QZ0ti/0T49djjTJQrqb+S1i6wWQymMMMMMsxx6Q==} - '@rspack/core@1.4.10': - resolution: {integrity: sha512-eK3H328pihiM1323OlaClKJ9WlqgGBZpcR5AqFoWsG0KD01tKCJOeZEgtCY6paRLrsQrEJwBrLntkG0fE7WNGg==} + '@rspack/core@1.4.11': + resolution: {integrity: sha512-JtKnL6p7Kc/YgWQJF3Woo4OccbgKGyT/4187W4dyex8BMkdQcbqCNIdi6dFk02hwQzxpOOxRSBI4hlGRbz7oYQ==} engines: {node: '>=16.0.0'} peerDependencies: '@swc/helpers': '>=0.5.1' @@ -4837,68 +4837,68 @@ packages: resolution: {integrity: sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==} engines: {node: '>=14'} - '@swc/core-darwin-arm64@1.13.2': - resolution: {integrity: sha512-44p7ivuLSGFJ15Vly4ivLJjg3ARo4879LtEBAabcHhSZygpmkP8eyjyWxrH3OxkY1eRZSIJe8yRZPFw4kPXFPw==} + '@swc/core-darwin-arm64@1.13.3': + resolution: {integrity: sha512-ux0Ws4pSpBTqbDS9GlVP354MekB1DwYlbxXU3VhnDr4GBcCOimpocx62x7cFJkSpEBF8bmX8+/TTCGKh4PbyXw==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.13.2': - resolution: {integrity: sha512-Lb9EZi7X2XDAVmuUlBm2UvVAgSCbD3qKqDCxSI4jEOddzVOpNCnyZ/xEampdngUIyDDhhJLYU9duC+Mcsv5Y+A==} + '@swc/core-darwin-x64@1.13.3': + resolution: {integrity: sha512-p0X6yhxmNUOMZrbeZ3ZNsPige8lSlSe1llllXvpCLkKKxN/k5vZt1sULoq6Nj4eQ7KeHQVm81/+AwKZyf/e0TA==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.13.2': - resolution: {integrity: sha512-9TDe/92ee1x57x+0OqL1huG4BeljVx0nWW4QOOxp8CCK67Rpc/HHl2wciJ0Kl9Dxf2NvpNtkPvqj9+BUmM9WVA==} + '@swc/core-linux-arm-gnueabihf@1.13.3': + resolution: {integrity: sha512-OmDoiexL2fVWvQTCtoh0xHMyEkZweQAlh4dRyvl8ugqIPEVARSYtaj55TBMUJIP44mSUOJ5tytjzhn2KFxFcBA==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.13.2': - resolution: {integrity: sha512-KJUSl56DBk7AWMAIEcU83zl5mg3vlQYhLELhjwRFkGFMvghQvdqQ3zFOYa4TexKA7noBZa3C8fb24rI5sw9Exg==} + '@swc/core-linux-arm64-gnu@1.13.3': + resolution: {integrity: sha512-STfKku3QfnuUj6k3g9ld4vwhtgCGYIFQmsGPPgT9MK/dI3Lwnpe5Gs5t1inoUIoGNP8sIOLlBB4HV4MmBjQuhw==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-arm64-musl@1.13.2': - resolution: {integrity: sha512-teU27iG1oyWpNh9CzcGQ48ClDRt/RCem7mYO7ehd2FY102UeTws2+OzLESS1TS1tEZipq/5xwx3FzbVgiolCiQ==} + '@swc/core-linux-arm64-musl@1.13.3': + resolution: {integrity: sha512-bc+CXYlFc1t8pv9yZJGus372ldzOVscBl7encUBlU1m/Sig0+NDJLz6cXXRcFyl6ABNOApWeR4Yl7iUWx6C8og==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-x64-gnu@1.13.2': - resolution: {integrity: sha512-dRPsyPyqpLD0HMRCRpYALIh4kdOir8pPg4AhNQZLehKowigRd30RcLXGNVZcc31Ua8CiPI4QSgjOIxK+EQe4LQ==} + '@swc/core-linux-x64-gnu@1.13.3': + resolution: {integrity: sha512-dFXoa0TEhohrKcxn/54YKs1iwNeW6tUkHJgXW33H381SvjKFUV53WR231jh1sWVJETjA3vsAwxKwR23s7UCmUA==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-linux-x64-musl@1.13.2': - resolution: {integrity: sha512-CCxETW+KkYEQDqz1SYC15YIWYheqFC+PJVOW76Maa/8yu8Biw+HTAcblKf2isrlUtK8RvrQN94v3UXkC2NzCEw==} + '@swc/core-linux-x64-musl@1.13.3': + resolution: {integrity: sha512-ieyjisLB+ldexiE/yD8uomaZuZIbTc8tjquYln9Quh5ykOBY7LpJJYBWvWtm1g3pHv6AXlBI8Jay7Fffb6aLfA==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-win32-arm64-msvc@1.13.2': - resolution: {integrity: sha512-Wv/QTA6PjyRLlmKcN6AmSI4jwSMRl0VTLGs57PHTqYRwwfwd7y4s2fIPJVBNbAlXd795dOEP6d/bGSQSyhOX3A==} + '@swc/core-win32-arm64-msvc@1.13.3': + resolution: {integrity: sha512-elTQpnaX5vESSbhCEgcwXjpMsnUbqqHfEpB7ewpkAsLzKEXZaK67ihSRYAuAx6ewRQTo7DS5iTT6X5aQD3MzMw==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.13.2': - resolution: {integrity: sha512-PuCdtNynEkUNbUXX/wsyUC+t4mamIU5y00lT5vJcAvco3/r16Iaxl5UCzhXYaWZSNVZMzPp9qN8NlSL8M5pPxw==} + '@swc/core-win32-ia32-msvc@1.13.3': + resolution: {integrity: sha512-nvehQVEOdI1BleJpuUgPLrclJ0TzbEMc+MarXDmmiRFwEUGqj+pnfkTSb7RZyS1puU74IXdK/YhTirHurtbI9w==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.13.2': - resolution: {integrity: sha512-qlmMkFZJus8cYuBURx1a3YAG2G7IW44i+FEYV5/32ylKkzGNAr9tDJSA53XNnNXkAB5EXSPsOz7bn5C3JlEtdQ==} + '@swc/core-win32-x64-msvc@1.13.3': + resolution: {integrity: sha512-A+JSKGkRbPLVV2Kwx8TaDAV0yXIXm/gc8m98hSkVDGlPBBmydgzNdWy3X7HTUBM7IDk7YlWE7w2+RUGjdgpTmg==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.13.2': - resolution: {integrity: sha512-YWqn+0IKXDhqVLKoac4v2tV6hJqB/wOh8/Br8zjqeqBkKa77Qb0Kw2i7LOFzjFNZbZaPH6AlMGlBwNrxaauaAg==} + '@swc/core@1.13.3': + resolution: {integrity: sha512-ZaDETVWnm6FE0fc+c2UE8MHYVS3Fe91o5vkmGfgwGXFbxYvAjKSqxM/j4cRc9T7VZNSJjriXq58XkfCp3Y6f+w==} engines: {node: '>=10'} peerDependencies: '@swc/helpers': '>=0.5.17' @@ -4915,68 +4915,68 @@ packages: '@swc/helpers@0.5.17': resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} - '@swc/html-darwin-arm64@1.13.2': - resolution: {integrity: sha512-8wK+0zi5Q0xjdfD2oTnzX933a3P7etE7TFgHp0DSPuMhBI2OQkJAWIwzlev8LxM9pLizLTyuMqU2bxHTo5E/pQ==} + '@swc/html-darwin-arm64@1.13.3': + resolution: {integrity: sha512-GYlnVL4Fyjwj1Xgzyhe9DW9fDLGzrDuse947fiWgxleTOFl5gYTwKIIRD5w0UIzEUYRXcKX0PgEzxzSYHDgKwQ==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/html-darwin-x64@1.13.2': - resolution: {integrity: sha512-mBXKMINILwupRreMaR7RvWHPjZ7nNT0BjJHJLNyeeiUSsZMtMUHgbzfW0XGNmtmQio829B/kiWmiGMALtooQmA==} + '@swc/html-darwin-x64@1.13.3': + resolution: {integrity: sha512-stOBPKzTa97Tp5Oa7DieUvdhoCLhyqVFOc/B69gLA1QV2ijJiwC80B6zq++QGNenDOStfqD7vxJEmsRaxBxf4Q==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - '@swc/html-linux-arm-gnueabihf@1.13.2': - resolution: {integrity: sha512-Z1keZTSdaaZCy5H7kI6GQjSI2lnVZGMIzZizyCzvILuuBQ4Z/kyC7dNi7E/fJL7HcJXFmVhoOXZeNnoDHpu8Pw==} + '@swc/html-linux-arm-gnueabihf@1.13.3': + resolution: {integrity: sha512-+BITBek2al/mCrLG7+KmjSr7ecwjd1TUVGrMRVVFP6IoxWm55QrATr9dwODXlR3W+xPywldYpwBRv3pzlrIWRw==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/html-linux-arm64-gnu@1.13.2': - resolution: {integrity: sha512-2WOdwpPUnZWMStX/8b36GAEtVV2FH13Ze86ejqPDyoAJwkVMoyaMeAOzGoQJsprKkodMjBXLxjD6iJ5HL4I3+g==} + '@swc/html-linux-arm64-gnu@1.13.3': + resolution: {integrity: sha512-INExpGWlDhIM3MkTmTl64lJMv300EwEUa63uEAmmY0AqDkv+VLn4cpQV2NRsdyLXZ+7PJQ5rU62UwGiyITTgLg==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/html-linux-arm64-musl@1.13.2': - resolution: {integrity: sha512-9Za5QqeJfyJz7vmY78g6GWU+9Hob0loRIueM2abC9vYYFc878UWNGyavFr0uo8xae6R6tby/qqhqWBx78lxyqQ==} + '@swc/html-linux-arm64-musl@1.13.3': + resolution: {integrity: sha512-Agj9RSZi2qqji37i6jjlDVShO18a3t8rs9H9ljzDE9tUDdNFYg0qjMgrd4EceplAuZQP+wiSi+3vGLN61GFujg==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/html-linux-x64-gnu@1.13.2': - resolution: {integrity: sha512-qU2d3axi7wvbvgNGGZrAfi4705McWsG3DgxNlwFdyO/Nszn3AQooDHenuHWqI6zp24pX+DrXepVL9KJuBf9aLA==} + '@swc/html-linux-x64-gnu@1.13.3': + resolution: {integrity: sha512-C75f4rFfg1ftOqjDmIu2+x4yP+IGhR6g4+SoARqb7bcXwHqlOQ6B6O9OplvQMLZdgDq/t10vQvz4kjaX0hsDVg==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/html-linux-x64-musl@1.13.2': - resolution: {integrity: sha512-TTbBjsTRY/JoVZxTwKe9X7fZIAHp+MlU6fThO+53VRQd+7jo5M8X4PVWOBFUeKrAgI+KclOa2Cqwqx8APNPiXQ==} + '@swc/html-linux-x64-musl@1.13.3': + resolution: {integrity: sha512-Fk5/MNMlgEYto7jprIysYUB9oXC+qPwtxGNp77cab3OTlyIBz3YrgoP6821AngMWZJq5H0RO8XScecrVWCSFxw==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/html-win32-arm64-msvc@1.13.2': - resolution: {integrity: sha512-wvJjLWV9grxfBfEMOG/UNi48KKEvGgCvXQVxMojTvEYrnLvlZDI0RdQI9WYX8PRztDX4t7fXL30U51I4UezYlg==} + '@swc/html-win32-arm64-msvc@1.13.3': + resolution: {integrity: sha512-PsqfbwqGR61cVXxy86+tCimSKDjGOFBHxe7Mku0rWLz0AOJ9oo+ZJZn00UzbMZMKiEkamCZ9BKsAMGccQ5U+KA==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/html-win32-ia32-msvc@1.13.2': - resolution: {integrity: sha512-cSEsCeGrMIyU/5Cox1EfxBfUdKAjtNly+GzueDPj5e7vGoogCEuU4Ggpzbk4a1qbgijgztJ5kjtF369d79/vuQ==} + '@swc/html-win32-ia32-msvc@1.13.3': + resolution: {integrity: sha512-oN/wanFmVnCcI6EOEKOcCwAOcQGUep5g61zh7ieYErbDkpd+hoxNZrRmFsho8iWu4+Fsb5GYhyGv0JYmAQEHWQ==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/html-win32-x64-msvc@1.13.2': - resolution: {integrity: sha512-je+7g0d+oFwhobIsR/mUt1HCLJ9Us9qF/Kon+MYz6WYKFNNfqQS8uJbTDvHEAvifDQAbJKYmqcvvpIWTPE6m4Q==} + '@swc/html-win32-x64-msvc@1.13.3': + resolution: {integrity: sha512-tmJ1YFvWemQ9eq6VSAuTfjgVZkUo4LmVUU6Z5Ml+3URHpH0GdXBoyJdgDA9M8vAP0MD5WSB6AGw7khxnjeO/4A==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/html@1.13.2': - resolution: {integrity: sha512-CHi/y+ROPie2g8Dmfz6MA5bRzCMnrShs7+bC3M6eHQDEP8BO3v9TBvvqF/0UhTe1j5P9rTJzKrtMz91aHi3Trg==} + '@swc/html@1.13.3': + resolution: {integrity: sha512-NLIM1vYKSb/bsWN74BtACLqywoWz1r5l+sMZwMDtC26Ap+xMXtU44LiQQMuenTjYZ6SVL6ovQNLVG5UliKRN1g==} engines: {node: '>=14'} '@swc/types@0.1.23': @@ -5003,12 +5003,12 @@ packages: '@tanstack/virtual-core@3.13.12': resolution: {integrity: sha512-1YBOJfRHV4sXUmWsFSf5rQor4Ss82G8dQWLRbnk3GA4jeP8hQt1hxXh0tmflpC0dz3VgEv/1+qwPyLeWkQuPFA==} - '@testing-library/dom@10.4.0': - resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} + '@testing-library/dom@10.4.1': + resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} - '@testing-library/jest-dom@6.6.3': - resolution: {integrity: sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==} + '@testing-library/jest-dom@6.6.4': + resolution: {integrity: sha512-xDXgLjVunjHqczScfkCJ9iyjdNOVHvvCdqHSSxwM9L0l/wHkTRum67SDc020uAlCoqktJplgO2AAQeLP1wgqDQ==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} '@testing-library/react@16.3.0': @@ -5067,8 +5067,8 @@ packages: '@types/babel__template@7.4.4': resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - '@types/babel__traverse@7.20.7': - resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} '@types/body-parser@1.19.6': resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} @@ -5109,8 +5109,8 @@ packages: '@types/d3-delaunay@6.0.4': resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==} - '@types/d3-dispatch@3.0.6': - resolution: {integrity: sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==} + '@types/d3-dispatch@3.0.7': + resolution: {integrity: sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==} '@types/d3-drag@3.0.7': resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==} @@ -5282,8 +5282,8 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node-fetch@2.6.12': - resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} + '@types/node-fetch@2.6.13': + resolution: {integrity: sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==} '@types/node-forge@1.3.13': resolution: {integrity: sha512-zePQJSW5QkwSHKRApqWCVKeKoSOt4xvEnLENZPjyvm9Ezdf/EyDeJM7jqLzOwjVICQQzvLZ63T55MKdJB5H6ww==} @@ -5294,11 +5294,11 @@ packages: '@types/node@17.0.45': resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} - '@types/node@18.19.120': - resolution: {integrity: sha512-WtCGHFXnVI8WHLxDAt5TbnCM4eSE+nI0QN2NJtwzcgMhht2eNz6V9evJrk+lwC8bCY8OWV5Ym8Jz7ZEyGnKnMA==} + '@types/node@18.19.121': + resolution: {integrity: sha512-bHOrbyztmyYIi4f1R0s17QsPs1uyyYnGcXeZoGEd227oZjry0q6XQBQxd82X1I57zEfwO8h9Xo+Kl5gX1d9MwQ==} - '@types/node@22.16.5': - resolution: {integrity: sha512-bJFoMATwIGaxxx8VJPeM8TonI8t579oRvgAuT8zFugJsJZgzqv0Fu8Mhp68iecjzG7cnN3mO2dJQ5uUM2EFrgQ==} + '@types/node@22.17.0': + resolution: {integrity: sha512-bbAKTCqX5aNVryi7qXVMi+OkB3w/OyblodicMbvE38blyAz7GxXf6XYhklokijuPwwVg9sDLKRxt0ZHXQwZVfQ==} '@types/node@24.1.0': resolution: {integrity: sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==} @@ -5312,8 +5312,8 @@ packages: '@types/parse5@6.0.3': resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==} - '@types/pg@8.15.4': - resolution: {integrity: sha512-I6UNVBAoYbvuWkkU3oosC8yxqH21f4/Jc4DK71JLG3dT2mdlGe1z+ep/LQGXaKaOgcvUrsQoPRqfgtMcvZiJhg==} + '@types/pg@8.15.5': + resolution: {integrity: sha512-LF7lF6zWEKxuT3/OR8wAZGzkg4ENGXFNyiV/JeOt9z5B+0ZVwbql9McqX5c/WStFq1GaGso7H1AzP/qSzmlCKQ==} '@types/prismjs@1.26.5': resolution: {integrity: sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==} @@ -5822,32 +5822,32 @@ packages: resolution: {integrity: sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==} engines: {node: '>=14.15.0'} - '@zag-js/core@1.20.1': - resolution: {integrity: sha512-xlw7HVmp5dnrKy6B9BOeCY3P1JoyA7VsSSJYJnWJX2nBgneY3cWSrlq0xowuFodbWirlVNHW98MQXegBUxbs0g==} + '@zag-js/core@1.21.1': + resolution: {integrity: sha512-bxkrKpT2F6oyy4NovQDRvFhFEf13Owyr100aty+xiYxvrWz0rNAOaid+hmjIP4f+QDvxGF1XiYFmXgqls3sUTw==} - '@zag-js/dom-query@1.20.1': - resolution: {integrity: sha512-d2sw2DbDlzfL1rGYtEjTnTjaGmVHRH0hPmPgmak3K0EOvbXIBRC0zg9eypZTQdn+bZUCvJVhPgJnaJQlCjU7Fg==} + '@zag-js/dom-query@1.21.1': + resolution: {integrity: sha512-O4db9iYvKeHPjBOtE92p01WXKHngzRRsR7Y5p1cNZ4cbBq15PH2lICcWwUyIxx5zjADZHx6HIv3E+Mg/KCauKA==} - '@zag-js/focus-trap@1.20.1': - resolution: {integrity: sha512-Ldo3htQn7+KqWDIibMedPn2e6oQ5JKJA7Q7gK0wST90HmRPGl8yK26kQexDzoN85Xld5JacgKKemi4g8GZPvOw==} + '@zag-js/focus-trap@1.21.1': + resolution: {integrity: sha512-330flR2wL7ymh7UI+n02/VYulLdJMWJH6ez3ERiu8VGah83X7aWGqCQizwfIVWs1wJ6FJ2yKRHBW9iCE2nSkLA==} - '@zag-js/presence@1.20.1': - resolution: {integrity: sha512-DKRbifq3YWifLgfhab9ECU7KAyxKpwDLpC0HjaEI25wkm/JLGxglWVwSsHS+AdgQUlfHeCvAJ38HvSo+SzbGwQ==} + '@zag-js/presence@1.21.1': + resolution: {integrity: sha512-6bMZsXBZ0IMk66qKPxQQ8MXSx3+cfFYMpnjzFN0MlwfG7Otn3BQqbFgLjGUCNxjkiipR8Lt5GnyiuK7L1rAQBQ==} - '@zag-js/react@1.20.1': - resolution: {integrity: sha512-mhSlDwjHkVgQ6zhl+rn4vYA/ZsOLsDgn5wszvl/5dfSyZqiEEyjBeVSrk0c9TFZLsUZ1MvVQpu37mYX7HqdCBA==} + '@zag-js/react@1.21.1': + resolution: {integrity: sha512-v2sOqTi2uQ67lz3n5AfUqASla5vHB3zAzSeTZvO479krmcYw44VatVHtxMmr+gx12p7XFGONkFau+MxURXp9Dw==} peerDependencies: react: '>=18.0.0' react-dom: '>=18.0.0' - '@zag-js/store@1.20.1': - resolution: {integrity: sha512-YXjCkJ02ciZBCAFqlm/VAA75kXgVDS/cqgTWE1a24obrBjwTteDkTE8cuSkGGUTAEE4n/9g15pA0OKqMQO+Xtw==} + '@zag-js/store@1.21.1': + resolution: {integrity: sha512-nuRIWUmL6I80Uxvap54ubuC6wTUBdGrY/LF7snnuK+/bZmcuif/202Oeepo+mlaaiyJ+z3abj2LNosPLKJT4eg==} - '@zag-js/types@1.20.1': - resolution: {integrity: sha512-1Y2P5HF7XT2vJt4zLy9AYigMOMb/OaALRuBPzgSFHq8Uz1PFZF6cFhYzfEi9obr8Uvw7rOmz6sV48t2VBLu6VQ==} + '@zag-js/types@1.21.1': + resolution: {integrity: sha512-KbKMwJnrj6wmi4FOcaIMwqBVPz4KZRAn0D7Il8QjvAaJc5SdqkK18lcxQz4/v02EmQ4uOrHgKchcnB+ZHcBFCw==} - '@zag-js/utils@1.20.1': - resolution: {integrity: sha512-0kJpJoJtcu15Zstx5BNWStG6RDVBV2e19MxG2IjaSBAoGIDjiQeCfqn/G82p6242VJeZ6b3vGoXemp9SXehmxA==} + '@zag-js/utils@1.21.1': + resolution: {integrity: sha512-YXkmKoQilMaCQolPnfyyF1xIDOkvSGUQ3RfNlGCxcfnXZeuLWhV/9kalXql5OhtDMChaSeI5IgoV6zH2KEeN0A==} '@zkochan/js-yaml@0.0.6': resolution: {integrity: sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg==} @@ -5975,8 +5975,8 @@ packages: peerDependencies: algoliasearch: '>= 3.1 < 6' - algoliasearch@5.34.1: - resolution: {integrity: sha512-s70HlfBgswgEdmCYkUJG8i/ULYhbkk8N9+N8JsWUwszcp7eauPEr5tIX4BY0qDGeKWQ/qZvmt4mxwTusYY23sg==} + algoliasearch@5.35.0: + resolution: {integrity: sha512-Y+moNhsqgLmvJdgTsO4GZNgsaDWv8AOGAaPeIeHKlDn/XunoAqYbA+XNpBd1dW8GOXAUDyxC9Rxc7AV4kpFcIg==} engines: {node: '>= 14.0.0'} allof-merge@0.6.6: @@ -6463,8 +6463,8 @@ packages: caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - caniuse-lite@1.0.30001727: - resolution: {integrity: sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==} + caniuse-lite@1.0.30001731: + resolution: {integrity: sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==} case-anything@2.1.13: resolution: {integrity: sha512-zlOQ80VrQ2Ue+ymH5OuM/DlDq64mEm+B9UTdHULv5osUMD6HalNTblf2b1u/m6QecjsnOkBpqVZ+XPwIVsy7Ng==} @@ -6480,10 +6480,6 @@ packages: resolution: {integrity: sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==} engines: {node: '>=18'} - chalk@3.0.0: - resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} - engines: {node: '>=8'} - chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -7042,11 +7038,6 @@ packages: cypress-wait-until@3.0.2: resolution: {integrity: sha512-iemies796dD5CgjG5kV0MnpEmKSH+s7O83ZoJLVzuVbZmm4lheMsZqAVT73hlMx4QlkwhxbyUzhOBUOZwoOe0w==} - cypress@14.5.2: - resolution: {integrity: sha512-O4E4CEBqDHLDrJD/dfStHPcM+8qFgVVZ89Li7xDU0yL/JxO/V0PEcfF2I8aGa7uA2MGNLkNUAnghPM83UcHOJw==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - cypress@14.5.3: resolution: {integrity: sha512-syLwKjDeMg77FRRx68bytLdlqHXDT4yBVh0/PPkcgesChYDjUZbwxLqMXuryYKzAyJsPsQHUDW1YU74/IYEUIA==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -7062,8 +7053,8 @@ packages: peerDependencies: cytoscape: ^3.2.0 - cytoscape@3.32.1: - resolution: {integrity: sha512-dbeqFTLYEwlFg7UGtcZhCCG/2WayX72zK3Sq323CEX29CY81tYfVhw1MIdduCtpstB0cTOhJswWlM/OEB3Xp+Q==} + cytoscape@3.33.0: + resolution: {integrity: sha512-2d2EwwhaxLWC8ahkH1PpQwCyu6EY3xDRdcEJXrLTb4fOUtVc+YWQalHU67rFS1a6ngj1fgv9dQLtJxP/KAFZEw==} engines: {node: '>=0.10'} d3-array@2.12.1: @@ -7579,8 +7570,8 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electron-to-chromium@1.5.190: - resolution: {integrity: sha512-k4McmnB2091YIsdCgkS0fMVMPOJgxl93ltFzaryXqwip1AaxeDqKCGLxkXODDA5Ab/D+tV5EL5+aTx76RvLRxw==} + electron-to-chromium@1.5.194: + resolution: {integrity: sha512-SdnWJwSUot04UR51I2oPD8kuP2VI37/CADR1OHsFOUzZIvfWJBO6q11k5P/uKNyTT3cdOsnyjkrZ+DDShqYqJA==} emoji-regex@10.4.0: resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} @@ -8175,8 +8166,8 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - follow-redirects@1.15.9: - resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -9264,8 +9255,8 @@ packages: resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true - jiti@2.5.0: - resolution: {integrity: sha512-NWDAhdnATItTnRhip9VTd8oXDjVcbhetRN6YzckApnXGxpGUooKMAaf0KVvlZG0+KlJMGkeLElVn4M1ReuxKUQ==} + jiti@2.5.1: + resolution: {integrity: sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==} hasBin: true joi@17.13.3: @@ -9494,8 +9485,8 @@ packages: resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==} engines: {node: '>=14.16'} - launch-editor@2.10.0: - resolution: {integrity: sha512-D7dBRJo/qcGX9xlvt/6wUYzQxjh5G1RvZPgPv8vi4KRU99DVQL/oW7tnVOCCTm2HGeo3C5HvGE5Yrh6UBoZ0vA==} + launch-editor@2.11.0: + resolution: {integrity: sha512-R/PIF14L6e2eHkhvQPu7jDRCr0msfCYCxbYiLgkkAGi0dVPWuM+RrsPu0a5dpuNe0KWGL3jpAkOlv53xGfPheQ==} layout-base@1.0.2: resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} @@ -10689,8 +10680,8 @@ packages: peerDependencies: webpack: ^4.0.0 || ^5.0.0 - nwsapi@2.2.20: - resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==} + nwsapi@2.2.21: + resolution: {integrity: sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==} nx@16.5.1: resolution: {integrity: sha512-I3hJRE4hG7JWAtncWwDEO3GVeGPpN0TtM8xH5ArZXyDuVeTth/i3TtJzdDzqXO1HHtIoAQN0xeq4n9cLuMil5g==} @@ -11147,13 +11138,13 @@ packages: pkg-types@2.2.0: resolution: {integrity: sha512-2SM/GZGAEkPp3KWORxQZns4M+WSeXbC2HEvmOIJe3Cmiv6ieAJvdVhDldtHqM5J1Y7MrR1XhkBT/rMlhh9FdqQ==} - playwright-core@1.54.1: - resolution: {integrity: sha512-Nbjs2zjj0htNhzgiy5wu+3w09YetDx5pkrpI/kZotDlDUaYk0HVA5xrBVPdow4SAUIlhgKcJeJg4GRKW6xHusA==} + playwright-core@1.54.2: + resolution: {integrity: sha512-n5r4HFbMmWsB4twG7tJLDN9gmBUeSPcsBZiWSE4DnYz9mJMAFqr2ID7+eGC9kpEnxExJ1epttwR59LEWCk8mtA==} engines: {node: '>=18'} hasBin: true - playwright@1.54.1: - resolution: {integrity: sha512-peWpSwIBmSLi6aW2auvrUtf2DqY16YYcCMO8rTVx486jKmDTJg7UAhyrraP98GB8BoPURZP8+nxO7TSd4cPr5g==} + playwright@1.54.2: + resolution: {integrity: sha512-Hu/BMoA1NAdRUuulyvQC0pEqZ4vQbGfn8f7wPXcnqQmM+zct9UliKxsIkLNmz/ku7LElUNqmaiv1TG/aL5ACsw==} engines: {node: '>=18'} hasBin: true @@ -11645,8 +11636,8 @@ packages: resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} engines: {node: '>=0.10.0'} - posthog-js@1.257.2: - resolution: {integrity: sha512-E+8wI/ahaiUGrmkilOtAB9aTFL+oELwOEsH1eO/2NyXB5WWcSUk6Rm1loixq8/lC4f3oR+Qqp9rHyXTSYbBDRQ==} + posthog-js@1.258.5: + resolution: {integrity: sha512-Tx6CzS8MsGAQGPrQth5TbkGxGQgAY01SktNW773/KDmVOWiRVZq/WQF/MRJRiuFxJ7qjethZQi3aBWfWKdr1RA==} peerDependencies: '@rrweb/types': 2.0.0-alpha.17 rrweb-snapshot: 2.0.0-alpha.17 @@ -11668,8 +11659,8 @@ packages: resolution: {integrity: sha512-jOrdVvzUXBC7C+9gkIkpDJ3HIxOHTIqjpQ4C1EMt1ZGeMvSEpbFCKq23DEfgsj46vMnDgyQf+1ZLp2Wm+bKSsA==} engines: {node: '>=10'} - preact@10.26.9: - resolution: {integrity: sha512-SSjF9vcnF27mJK1XyFMNJzFd5u3pQiATFqoaDy03XuN00u4ziveVVEGt5RKJrDR8MHE/wJo9Nnad56RLzS2RMA==} + preact@10.27.0: + resolution: {integrity: sha512-/DTYoB6mwwgPytiqQTh/7SFRL98ZdiD8Sk8zIUVOxtwq4oWcwrcd1uno9fE/zZmUaUrFNYzbH14CPebOz9tZQw==} prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} @@ -11989,8 +11980,8 @@ packages: peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 - react-hook-form@7.61.1: - resolution: {integrity: sha512-2vbXUFDYgqEgM2RcXcAT2PwDW/80QARi+PKmHy5q2KhuKvOlG8iIYgf7eIlIANR5trW9fJbP4r5aub3a4egsew==} + react-hook-form@7.62.0: + resolution: {integrity: sha512-7KWFejc98xqG/F4bAxpL41NB3o1nnvQO1RWZT3TqRZYL8RryQETGfEdVnJN2fy1crCiBLLjkRBVK05j24FxJGA==} engines: {node: '>=18.0.0'} peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 @@ -12181,8 +12172,10 @@ packages: recma-build-jsx@1.0.0: resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} - recma-jsx@1.0.0: - resolution: {integrity: sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q==} + recma-jsx@1.0.1: + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 recma-parse@1.0.0: resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} @@ -12417,8 +12410,8 @@ packages: engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true - rollup@4.45.1: - resolution: {integrity: sha512-4iya7Jb76fVpQyLoiVpzUrsjQ12r3dM7fIVz+4NwoYvZOShknRmiv+iu9CClZml5ZLGb0XMcYLutK6w9tgxHDw==} + rollup@4.46.2: + resolution: {integrity: sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -12837,6 +12830,7 @@ packages: source-map@0.8.0-beta.0: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} engines: {node: '>= 8'} + deprecated: The work that was done in this beta branch won't be included in future versions space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} @@ -13496,8 +13490,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - typescript@5.8.3: - resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + typescript@5.9.2: + resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} engines: {node: '>=14.17'} hasBin: true @@ -13826,8 +13820,8 @@ packages: vfile-message@3.1.4: resolution: {integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==} - vfile-message@4.0.2: - resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} vfile@5.3.7: resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==} @@ -14099,8 +14093,8 @@ packages: html-webpack-plugin: optional: true - webpack@5.100.2: - resolution: {integrity: sha512-QaNKAvGCDRh3wW1dsDjeMdDXwZm2vqq3zn6Pvq4rHOEOGSaUMgOOjG2Y9ZbIGzpfkJk9ZYTHpDqgDfeBDcnLaw==} + webpack@5.101.0: + resolution: {integrity: sha512-B4t+nJqytPeuZlHuIKTbalhljIFXeNRqrUGAQgTGlfOl2lXXKXw+yZu6bicycP+PUlM44CxBjCFD6aciKFT3LQ==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -14390,112 +14384,119 @@ snapshots: '@adobe/css-tools@4.4.3': {} - '@algolia/autocomplete-core@1.17.9(@algolia/client-search@5.34.1)(algoliasearch@5.34.1)(search-insights@2.17.3)': + '@algolia/abtesting@1.1.0': dependencies: - '@algolia/autocomplete-plugin-algolia-insights': 1.17.9(@algolia/client-search@5.34.1)(algoliasearch@5.34.1)(search-insights@2.17.3) - '@algolia/autocomplete-shared': 1.17.9(@algolia/client-search@5.34.1)(algoliasearch@5.34.1) + '@algolia/client-common': 5.35.0 + '@algolia/requester-browser-xhr': 5.35.0 + '@algolia/requester-fetch': 5.35.0 + '@algolia/requester-node-http': 5.35.0 + + '@algolia/autocomplete-core@1.17.9(@algolia/client-search@5.35.0)(algoliasearch@5.35.0)(search-insights@2.17.3)': + dependencies: + '@algolia/autocomplete-plugin-algolia-insights': 1.17.9(@algolia/client-search@5.35.0)(algoliasearch@5.35.0)(search-insights@2.17.3) + '@algolia/autocomplete-shared': 1.17.9(@algolia/client-search@5.35.0)(algoliasearch@5.35.0) transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - search-insights - '@algolia/autocomplete-plugin-algolia-insights@1.17.9(@algolia/client-search@5.34.1)(algoliasearch@5.34.1)(search-insights@2.17.3)': + '@algolia/autocomplete-plugin-algolia-insights@1.17.9(@algolia/client-search@5.35.0)(algoliasearch@5.35.0)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-shared': 1.17.9(@algolia/client-search@5.34.1)(algoliasearch@5.34.1) + '@algolia/autocomplete-shared': 1.17.9(@algolia/client-search@5.35.0)(algoliasearch@5.35.0) search-insights: 2.17.3 transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - '@algolia/autocomplete-preset-algolia@1.17.9(@algolia/client-search@5.34.1)(algoliasearch@5.34.1)': + '@algolia/autocomplete-preset-algolia@1.17.9(@algolia/client-search@5.35.0)(algoliasearch@5.35.0)': dependencies: - '@algolia/autocomplete-shared': 1.17.9(@algolia/client-search@5.34.1)(algoliasearch@5.34.1) - '@algolia/client-search': 5.34.1 - algoliasearch: 5.34.1 + '@algolia/autocomplete-shared': 1.17.9(@algolia/client-search@5.35.0)(algoliasearch@5.35.0) + '@algolia/client-search': 5.35.0 + algoliasearch: 5.35.0 - '@algolia/autocomplete-shared@1.17.9(@algolia/client-search@5.34.1)(algoliasearch@5.34.1)': + '@algolia/autocomplete-shared@1.17.9(@algolia/client-search@5.35.0)(algoliasearch@5.35.0)': dependencies: - '@algolia/client-search': 5.34.1 - algoliasearch: 5.34.1 + '@algolia/client-search': 5.35.0 + algoliasearch: 5.35.0 - '@algolia/client-abtesting@5.34.1': + '@algolia/client-abtesting@5.35.0': dependencies: - '@algolia/client-common': 5.34.1 - '@algolia/requester-browser-xhr': 5.34.1 - '@algolia/requester-fetch': 5.34.1 - '@algolia/requester-node-http': 5.34.1 + '@algolia/client-common': 5.35.0 + '@algolia/requester-browser-xhr': 5.35.0 + '@algolia/requester-fetch': 5.35.0 + '@algolia/requester-node-http': 5.35.0 - '@algolia/client-analytics@5.34.1': + '@algolia/client-analytics@5.35.0': dependencies: - '@algolia/client-common': 5.34.1 - '@algolia/requester-browser-xhr': 5.34.1 - '@algolia/requester-fetch': 5.34.1 - '@algolia/requester-node-http': 5.34.1 + '@algolia/client-common': 5.35.0 + '@algolia/requester-browser-xhr': 5.35.0 + '@algolia/requester-fetch': 5.35.0 + '@algolia/requester-node-http': 5.35.0 - '@algolia/client-common@5.34.1': {} + '@algolia/client-common@5.35.0': {} - '@algolia/client-insights@5.34.1': + '@algolia/client-insights@5.35.0': dependencies: - '@algolia/client-common': 5.34.1 - '@algolia/requester-browser-xhr': 5.34.1 - '@algolia/requester-fetch': 5.34.1 - '@algolia/requester-node-http': 5.34.1 + '@algolia/client-common': 5.35.0 + '@algolia/requester-browser-xhr': 5.35.0 + '@algolia/requester-fetch': 5.35.0 + '@algolia/requester-node-http': 5.35.0 - '@algolia/client-personalization@5.34.1': + '@algolia/client-personalization@5.35.0': dependencies: - '@algolia/client-common': 5.34.1 - '@algolia/requester-browser-xhr': 5.34.1 - '@algolia/requester-fetch': 5.34.1 - '@algolia/requester-node-http': 5.34.1 + '@algolia/client-common': 5.35.0 + '@algolia/requester-browser-xhr': 5.35.0 + '@algolia/requester-fetch': 5.35.0 + '@algolia/requester-node-http': 5.35.0 - '@algolia/client-query-suggestions@5.34.1': + '@algolia/client-query-suggestions@5.35.0': dependencies: - '@algolia/client-common': 5.34.1 - '@algolia/requester-browser-xhr': 5.34.1 - '@algolia/requester-fetch': 5.34.1 - '@algolia/requester-node-http': 5.34.1 + '@algolia/client-common': 5.35.0 + '@algolia/requester-browser-xhr': 5.35.0 + '@algolia/requester-fetch': 5.35.0 + '@algolia/requester-node-http': 5.35.0 - '@algolia/client-search@5.34.1': + '@algolia/client-search@5.35.0': dependencies: - '@algolia/client-common': 5.34.1 - '@algolia/requester-browser-xhr': 5.34.1 - '@algolia/requester-fetch': 5.34.1 - '@algolia/requester-node-http': 5.34.1 + '@algolia/client-common': 5.35.0 + '@algolia/requester-browser-xhr': 5.35.0 + '@algolia/requester-fetch': 5.35.0 + '@algolia/requester-node-http': 5.35.0 '@algolia/events@4.0.1': {} - '@algolia/ingestion@1.34.1': + '@algolia/ingestion@1.35.0': dependencies: - '@algolia/client-common': 5.34.1 - '@algolia/requester-browser-xhr': 5.34.1 - '@algolia/requester-fetch': 5.34.1 - '@algolia/requester-node-http': 5.34.1 + '@algolia/client-common': 5.35.0 + '@algolia/requester-browser-xhr': 5.35.0 + '@algolia/requester-fetch': 5.35.0 + '@algolia/requester-node-http': 5.35.0 - '@algolia/monitoring@1.34.1': + '@algolia/monitoring@1.35.0': dependencies: - '@algolia/client-common': 5.34.1 - '@algolia/requester-browser-xhr': 5.34.1 - '@algolia/requester-fetch': 5.34.1 - '@algolia/requester-node-http': 5.34.1 + '@algolia/client-common': 5.35.0 + '@algolia/requester-browser-xhr': 5.35.0 + '@algolia/requester-fetch': 5.35.0 + '@algolia/requester-node-http': 5.35.0 - '@algolia/recommend@5.34.1': + '@algolia/recommend@5.35.0': dependencies: - '@algolia/client-common': 5.34.1 - '@algolia/requester-browser-xhr': 5.34.1 - '@algolia/requester-fetch': 5.34.1 - '@algolia/requester-node-http': 5.34.1 + '@algolia/client-common': 5.35.0 + '@algolia/requester-browser-xhr': 5.35.0 + '@algolia/requester-fetch': 5.35.0 + '@algolia/requester-node-http': 5.35.0 - '@algolia/requester-browser-xhr@5.34.1': + '@algolia/requester-browser-xhr@5.35.0': dependencies: - '@algolia/client-common': 5.34.1 + '@algolia/client-common': 5.35.0 - '@algolia/requester-fetch@5.34.1': + '@algolia/requester-fetch@5.35.0': dependencies: - '@algolia/client-common': 5.34.1 + '@algolia/client-common': 5.35.0 - '@algolia/requester-node-http@5.34.1': + '@algolia/requester-node-http@5.35.0': dependencies: - '@algolia/client-common': 5.34.1 + '@algolia/client-common': 5.35.0 '@alloc/quick-lru@5.2.0': {} @@ -14516,11 +14517,11 @@ snapshots: transitivePeerDependencies: - chokidar - '@angular-devkit/build-angular@16.2.16(@angular/compiler-cli@16.2.12(@angular/compiler@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3)))(typescript@5.1.6))(@angular/service-worker@16.2.12(@angular/common@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3))(rxjs@7.8.2))(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3)))(@swc/core@1.13.2(@swc/helpers@0.5.17))(@types/node@22.16.5)(html-webpack-plugin@5.6.3(@rspack/core@1.4.10(@swc/helpers@0.5.17))(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)))(karma@6.4.4)(lightningcss@1.30.1)(tailwindcss@3.4.14)(typescript@5.1.6)': + '@angular-devkit/build-angular@16.2.16(@angular/compiler-cli@16.2.12(@angular/compiler@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3)))(typescript@5.1.6))(@angular/service-worker@16.2.12(@angular/common@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3))(rxjs@7.8.2))(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3)))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.17.0)(html-webpack-plugin@5.6.3(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)))(karma@6.4.4)(lightningcss@1.30.1)(tailwindcss@3.4.14)(typescript@5.1.6)': dependencies: '@ampproject/remapping': 2.2.1 '@angular-devkit/architect': 0.1602.16(chokidar@3.5.3) - '@angular-devkit/build-webpack': 0.1602.16(chokidar@3.5.3)(webpack-dev-server@4.15.1(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)))(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)) + '@angular-devkit/build-webpack': 0.1602.16(chokidar@3.5.3)(webpack-dev-server@4.15.1(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)))(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)) '@angular-devkit/core': 16.2.16(chokidar@3.5.3) '@angular/compiler-cli': 16.2.12(@angular/compiler@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3)))(typescript@5.1.6) '@babel/core': 7.22.9 @@ -14534,17 +14535,17 @@ snapshots: '@babel/runtime': 7.22.6 '@babel/template': 7.22.5 '@discoveryjs/json-ext': 0.5.7 - '@ngtools/webpack': 16.2.16(@angular/compiler-cli@16.2.12(@angular/compiler@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3)))(typescript@5.1.6))(typescript@5.1.6)(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)) - '@vitejs/plugin-basic-ssl': 1.0.1(vite@4.5.5(@types/node@22.16.5)(less@4.1.3)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.19.2)) + '@ngtools/webpack': 16.2.16(@angular/compiler-cli@16.2.12(@angular/compiler@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3)))(typescript@5.1.6))(typescript@5.1.6)(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)) + '@vitejs/plugin-basic-ssl': 1.0.1(vite@4.5.5(@types/node@22.17.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.19.2)) ansi-colors: 4.1.3 autoprefixer: 10.4.14(postcss@8.4.31) - babel-loader: 9.1.3(@babel/core@7.22.9)(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)) + babel-loader: 9.1.3(@babel/core@7.22.9)(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)) babel-plugin-istanbul: 6.1.1 browserslist: 4.25.1 chokidar: 3.5.3 - copy-webpack-plugin: 11.0.0(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)) + copy-webpack-plugin: 11.0.0(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)) critters: 0.0.20 - css-loader: 6.8.1(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)) + css-loader: 6.8.1(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)) esbuild-wasm: 0.18.17 fast-glob: 3.3.1 guess-parser: 0.4.22(typescript@5.1.6) @@ -14553,11 +14554,11 @@ snapshots: jsonc-parser: 3.2.0 karma-source-map-support: 1.4.0 less: 4.1.3 - less-loader: 11.1.0(less@4.1.3)(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)) - license-webpack-plugin: 4.0.2(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)) + less-loader: 11.1.0(less@4.1.3)(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)) + license-webpack-plugin: 4.0.2(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)) loader-utils: 3.2.1 magic-string: 0.30.1 - mini-css-extract-plugin: 2.7.6(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)) + mini-css-extract-plugin: 2.7.6(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)) mrmime: 1.0.1 open: 8.4.2 ora: 5.4.1 @@ -14565,25 +14566,25 @@ snapshots: picomatch: 2.3.1 piscina: 4.0.0 postcss: 8.4.31 - postcss-loader: 7.3.3(postcss@8.4.31)(typescript@5.1.6)(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)) + postcss-loader: 7.3.3(postcss@8.4.31)(typescript@5.1.6)(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)) resolve-url-loader: 5.0.0 rxjs: 7.8.1 sass: 1.64.1 - sass-loader: 13.3.2(sass@1.64.1)(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)) + sass-loader: 13.3.2(sass@1.64.1)(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)) semver: 7.5.4 - source-map-loader: 4.0.1(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)) + source-map-loader: 4.0.1(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)) source-map-support: 0.5.21 terser: 5.19.2 text-table: 0.2.0 tree-kill: 1.2.2 tslib: 2.6.1 typescript: 5.1.6 - vite: 4.5.5(@types/node@22.16.5)(less@4.1.3)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.19.2) - webpack: 5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17) - webpack-dev-middleware: 6.1.2(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)) - webpack-dev-server: 4.15.1(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)) + vite: 4.5.5(@types/node@22.17.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.19.2) + webpack: 5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17) + webpack-dev-middleware: 6.1.2(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)) + webpack-dev-server: 4.15.1(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)) webpack-merge: 5.9.0 - webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.6.3(@rspack/core@1.4.10(@swc/helpers@0.5.17))(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)))(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)) + webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.6.3(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)))(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)) optionalDependencies: '@angular/service-worker': 16.2.12(@angular/common@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3))(rxjs@7.8.2))(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3)) esbuild: 0.18.17 @@ -14607,12 +14608,12 @@ snapshots: - utf-8-validate - webpack-cli - '@angular-devkit/build-webpack@0.1602.16(chokidar@3.5.3)(webpack-dev-server@4.15.1(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)))(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17))': + '@angular-devkit/build-webpack@0.1602.16(chokidar@3.5.3)(webpack-dev-server@4.15.1(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)))(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17))': dependencies: '@angular-devkit/architect': 0.1602.16(chokidar@3.5.3) rxjs: 7.8.1 - webpack: 5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17) - webpack-dev-server: 4.15.1(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)) + webpack: 5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17) + webpack-dev-server: 4.15.1(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)) transitivePeerDependencies: - chokidar @@ -14692,14 +14693,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@angular-eslint/schematics@16.2.0(@angular/cli@16.2.16(chokidar@3.5.3))(@swc/core@1.13.2(@swc/helpers@0.5.17))(eslint@8.57.1)(typescript@5.1.6)': + '@angular-eslint/schematics@16.2.0(@angular/cli@16.2.16(chokidar@3.5.3))(@swc/core@1.13.3(@swc/helpers@0.5.17))(eslint@8.57.1)(typescript@5.1.6)': dependencies: '@angular-eslint/eslint-plugin': 16.2.0(eslint@8.57.1)(typescript@5.1.6) '@angular-eslint/eslint-plugin-template': 16.2.0(eslint@8.57.1)(typescript@5.1.6) '@angular/cli': 16.2.16(chokidar@3.5.3) - '@nx/devkit': 16.5.1(nx@16.5.1(@swc/core@1.13.2(@swc/helpers@0.5.17))) + '@nx/devkit': 16.5.1(nx@16.5.1(@swc/core@1.13.3(@swc/helpers@0.5.17))) ignore: 5.2.4 - nx: 16.5.1(@swc/core@1.13.2(@swc/helpers@0.5.17)) + nx: 16.5.1(@swc/core@1.13.3(@swc/helpers@0.5.17)) strip-json-comments: 3.1.1 tmp: 0.2.1 transitivePeerDependencies: @@ -16411,42 +16412,42 @@ snapshots: '@braintree/sanitize-url@7.1.1': {} - '@bufbuild/buf-darwin-arm64@1.55.1': + '@bufbuild/buf-darwin-arm64@1.56.0': optional: true - '@bufbuild/buf-darwin-x64@1.55.1': + '@bufbuild/buf-darwin-x64@1.56.0': optional: true - '@bufbuild/buf-linux-aarch64@1.55.1': + '@bufbuild/buf-linux-aarch64@1.56.0': optional: true - '@bufbuild/buf-linux-armv7@1.55.1': + '@bufbuild/buf-linux-armv7@1.56.0': optional: true - '@bufbuild/buf-linux-x64@1.55.1': + '@bufbuild/buf-linux-x64@1.56.0': optional: true - '@bufbuild/buf-win32-arm64@1.55.1': + '@bufbuild/buf-win32-arm64@1.56.0': optional: true - '@bufbuild/buf-win32-x64@1.55.1': + '@bufbuild/buf-win32-x64@1.56.0': optional: true - '@bufbuild/buf@1.55.1': + '@bufbuild/buf@1.56.0': optionalDependencies: - '@bufbuild/buf-darwin-arm64': 1.55.1 - '@bufbuild/buf-darwin-x64': 1.55.1 - '@bufbuild/buf-linux-aarch64': 1.55.1 - '@bufbuild/buf-linux-armv7': 1.55.1 - '@bufbuild/buf-linux-x64': 1.55.1 - '@bufbuild/buf-win32-arm64': 1.55.1 - '@bufbuild/buf-win32-x64': 1.55.1 + '@bufbuild/buf-darwin-arm64': 1.56.0 + '@bufbuild/buf-darwin-x64': 1.56.0 + '@bufbuild/buf-linux-aarch64': 1.56.0 + '@bufbuild/buf-linux-armv7': 1.56.0 + '@bufbuild/buf-linux-x64': 1.56.0 + '@bufbuild/buf-win32-arm64': 1.56.0 + '@bufbuild/buf-win32-x64': 1.56.0 '@bufbuild/protobuf@2.6.2': {} - '@bufbuild/protocompile@0.0.1(@bufbuild/buf@1.55.1)': + '@bufbuild/protocompile@0.0.1(@bufbuild/buf@1.56.0)': dependencies: - '@bufbuild/buf': 1.55.1 + '@bufbuild/buf': 1.56.0 '@bufbuild/protobuf': 2.6.2 fflate: 0.8.2 @@ -16611,17 +16612,17 @@ snapshots: '@colors/colors@1.5.0': {} - '@connectrpc/connect-node@2.0.2(@bufbuild/protobuf@2.6.2)(@connectrpc/connect@2.0.2(@bufbuild/protobuf@2.6.2))': + '@connectrpc/connect-node@2.0.3(@bufbuild/protobuf@2.6.2)(@connectrpc/connect@2.0.3(@bufbuild/protobuf@2.6.2))': dependencies: '@bufbuild/protobuf': 2.6.2 - '@connectrpc/connect': 2.0.2(@bufbuild/protobuf@2.6.2) + '@connectrpc/connect': 2.0.3(@bufbuild/protobuf@2.6.2) - '@connectrpc/connect-web@2.0.2(@bufbuild/protobuf@2.6.2)(@connectrpc/connect@2.0.2(@bufbuild/protobuf@2.6.2))': + '@connectrpc/connect-web@2.0.3(@bufbuild/protobuf@2.6.2)(@connectrpc/connect@2.0.3(@bufbuild/protobuf@2.6.2))': dependencies: '@bufbuild/protobuf': 2.6.2 - '@connectrpc/connect': 2.0.2(@bufbuild/protobuf@2.6.2) + '@connectrpc/connect': 2.0.3(@bufbuild/protobuf@2.6.2) - '@connectrpc/connect@2.0.2(@bufbuild/protobuf@2.6.2)': + '@connectrpc/connect@2.0.3(@bufbuild/protobuf@2.6.2)': dependencies: '@bufbuild/protobuf': 2.6.2 @@ -16896,27 +16897,6 @@ snapshots: '@ctrl/tinycolor@3.6.1': {} - '@cypress/request@3.0.8': - dependencies: - aws-sign2: 0.7.0 - aws4: 1.13.2 - caseless: 0.12.0 - combined-stream: 1.0.8 - extend: 3.0.2 - forever-agent: 0.6.1 - form-data: 4.0.4 - http-signature: 1.4.0 - is-typedarray: 1.0.0 - isstream: 0.1.2 - json-stringify-safe: 5.0.1 - mime-types: 2.1.35 - performance-now: 2.1.0 - qs: 6.14.0 - safe-buffer: 5.2.1 - tough-cookie: 5.1.2 - tunnel-agent: 0.6.0 - uuid: 8.3.2 - '@cypress/request@3.0.9': dependencies: aws-sign2: 0.7.0 @@ -16951,12 +16931,12 @@ snapshots: '@docsearch/css@3.9.0': {} - '@docsearch/react@3.9.0(@algolia/client-search@5.34.1)(@types/react@19.1.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)': + '@docsearch/react@3.9.0(@algolia/client-search@5.35.0)(@types/react@19.1.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-core': 1.17.9(@algolia/client-search@5.34.1)(algoliasearch@5.34.1)(search-insights@2.17.3) - '@algolia/autocomplete-preset-algolia': 1.17.9(@algolia/client-search@5.34.1)(algoliasearch@5.34.1) + '@algolia/autocomplete-core': 1.17.9(@algolia/client-search@5.35.0)(algoliasearch@5.35.0)(search-insights@2.17.3) + '@algolia/autocomplete-preset-algolia': 1.17.9(@algolia/client-search@5.35.0)(algoliasearch@5.35.0) '@docsearch/css': 3.9.0 - algoliasearch: 5.34.1 + algoliasearch: 5.35.0 optionalDependencies: '@types/react': 19.1.2 react: 18.3.1 @@ -16965,7 +16945,7 @@ snapshots: transitivePeerDependencies: - '@algolia/client-search' - '@docusaurus/babel@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/babel@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/core': 7.28.0 '@babel/generator': 7.28.0 @@ -16978,7 +16958,7 @@ snapshots: '@babel/runtime-corejs3': 7.28.2 '@babel/traverse': 7.28.0 '@docusaurus/logger': 3.8.1 - '@docusaurus/utils': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) babel-plugin-dynamic-import-node: 2.3.3 fs-extra: 11.3.0 tslib: 2.8.1 @@ -16992,34 +16972,34 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/bundler@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)': + '@docusaurus/bundler@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: '@babel/core': 7.28.0 - '@docusaurus/babel': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/babel': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/cssnano-preset': 3.8.1 '@docusaurus/logger': 3.8.1 - '@docusaurus/types': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - babel-loader: 9.2.1(@babel/core@7.28.0)(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + '@docusaurus/types': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + babel-loader: 9.2.1(@babel/core@7.28.0)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) clean-css: 5.3.3 - copy-webpack-plugin: 11.0.0(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) - css-loader: 6.11.0(@rspack/core@1.4.10(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) - css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + copy-webpack-plugin: 11.0.0(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) + css-loader: 6.11.0(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) + css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) cssnano: 6.1.2(postcss@8.5.6) - file-loader: 6.2.0(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + file-loader: 6.2.0(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) html-minifier-terser: 7.2.0 - mini-css-extract-plugin: 2.9.2(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) - null-loader: 4.0.1(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + mini-css-extract-plugin: 2.9.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) + null-loader: 4.0.1(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) postcss: 8.5.6 - postcss-loader: 7.3.4(postcss@8.5.6)(typescript@5.8.3)(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + postcss-loader: 7.3.4(postcss@8.5.6)(typescript@5.9.2)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) postcss-preset-env: 10.2.4(postcss@8.5.6) - terser-webpack-plugin: 5.3.14(@swc/core@1.13.2(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + terser-webpack-plugin: 5.3.14(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) tslib: 2.8.1 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))))(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) - webpackbar: 6.0.1(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) + webpackbar: 6.0.1(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) optionalDependencies: - '@docusaurus/faster': 3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17) + '@docusaurus/faster': 3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17) transitivePeerDependencies: - '@parcel/css' - '@rspack/core' @@ -17036,15 +17016,15 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/core@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)': + '@docusaurus/core@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/babel': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/bundler': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) + '@docusaurus/babel': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/bundler': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/logger': 3.8.1 - '@docusaurus/mdx-loader': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-common': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/mdx-loader': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mdx-js/react': 3.1.0(@types/react@19.1.2)(react@18.3.1) boxen: 6.2.1 chalk: 4.1.2 @@ -17060,7 +17040,7 @@ snapshots: execa: 5.1.1 fs-extra: 11.3.0 html-tags: 3.3.1 - html-webpack-plugin: 5.6.3(@rspack/core@1.4.10(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + html-webpack-plugin: 5.6.3(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) leven: 3.1.0 lodash: 4.17.21 open: 8.4.2 @@ -17070,7 +17050,7 @@ snapshots: react-dom: 18.3.1(react@18.3.1) react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)' react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' - react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) react-router: 5.3.4(react@18.3.1) react-router-config: 5.1.1(react-router@5.3.4(react@18.3.1))(react@18.3.1) react-router-dom: 5.3.4(react@18.3.1) @@ -17079,9 +17059,9 @@ snapshots: tinypool: 1.1.1 tslib: 2.8.1 update-notifier: 6.0.2 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) webpack-bundle-analyzer: 4.10.2 - webpack-dev-server: 4.15.2(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + webpack-dev-server: 4.15.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) webpack-merge: 6.0.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -17108,17 +17088,17 @@ snapshots: postcss-sort-media-queries: 5.2.0(postcss@8.5.6) tslib: 2.8.1 - '@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17)': + '@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17)': dependencies: - '@docusaurus/types': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rspack/core': 1.4.10(@swc/helpers@0.5.17) - '@swc/core': 1.13.2(@swc/helpers@0.5.17) - '@swc/html': 1.13.2 + '@docusaurus/types': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rspack/core': 1.4.11(@swc/helpers@0.5.17) + '@swc/core': 1.13.3(@swc/helpers@0.5.17) + '@swc/html': 1.13.3 browserslist: 4.25.1 lightningcss: 1.30.1 - swc-loader: 0.2.6(@swc/core@1.13.2(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + swc-loader: 0.2.6(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) tslib: 2.8.1 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) transitivePeerDependencies: - '@swc/helpers' - esbuild @@ -17130,16 +17110,16 @@ snapshots: chalk: 4.1.2 tslib: 2.8.1 - '@docusaurus/mdx-loader@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/mdx-loader@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@docusaurus/logger': 3.8.1 - '@docusaurus/utils': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mdx-js/mdx': 3.1.0(acorn@8.15.0) '@slorber/remark-comment': 1.0.0 escape-html: 1.0.3 estree-util-value-to-estree: 3.4.0 - file-loader: 6.2.0(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + file-loader: 6.2.0(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) fs-extra: 11.3.0 image-size: 2.0.2 mdast-util-mdx: 3.0.0 @@ -17155,9 +17135,9 @@ snapshots: tslib: 2.8.1 unified: 11.0.5 unist-util-visit: 5.0.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))))(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) vfile: 6.0.3 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) transitivePeerDependencies: - '@swc/core' - acorn @@ -17166,9 +17146,9 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/module-type-aliases@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/module-type-aliases@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@docusaurus/types': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/history': 4.7.11 '@types/react': 19.1.2 '@types/react-router-config': 5.0.11 @@ -17185,17 +17165,17 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/plugin-content-blog@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)': + '@docusaurus/plugin-content-blog@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) + '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/logger': 3.8.1 - '@docusaurus/mdx-loader': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/plugin-content-docs': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/types': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-common': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/mdx-loader': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-docs': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) cheerio: 1.0.0-rc.12 feed: 4.2.2 fs-extra: 11.3.0 @@ -17207,7 +17187,7 @@ snapshots: tslib: 2.8.1 unist-util-visit: 5.0.0 utility-types: 3.11.0 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' @@ -17227,17 +17207,17 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)': + '@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) + '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/logger': 3.8.1 - '@docusaurus/mdx-loader': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/module-type-aliases': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/types': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-common': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/mdx-loader': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/module-type-aliases': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/react-router-config': 5.0.11 combine-promises: 1.2.0 fs-extra: 11.3.0 @@ -17248,7 +17228,7 @@ snapshots: schema-dts: 1.1.5 tslib: 2.8.1 utility-types: 3.11.0 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' @@ -17268,18 +17248,18 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-pages@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)': + '@docusaurus/plugin-content-pages@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/mdx-loader': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/types': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/mdx-loader': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) fs-extra: 11.3.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) tslib: 2.8.1 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' @@ -17299,12 +17279,12 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-css-cascade-layers@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)': + '@docusaurus/plugin-css-cascade-layers@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/types': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/types': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -17327,11 +17307,11 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-debug@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)': + '@docusaurus/plugin-debug@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/types': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/types': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) fs-extra: 11.3.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -17356,11 +17336,11 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-analytics@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)': + '@docusaurus/plugin-google-analytics@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/types': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/types': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) tslib: 2.8.1 @@ -17383,11 +17363,11 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-gtag@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)': + '@docusaurus/plugin-google-gtag@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/types': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/types': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/gtag.js': 0.0.12 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -17411,11 +17391,11 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-tag-manager@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)': + '@docusaurus/plugin-google-tag-manager@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/types': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/types': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) tslib: 2.8.1 @@ -17438,14 +17418,14 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-sitemap@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)': + '@docusaurus/plugin-sitemap@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) + '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/logger': 3.8.1 - '@docusaurus/types': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-common': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) fs-extra: 11.3.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -17470,18 +17450,18 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-svgr@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)': + '@docusaurus/plugin-svgr@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/types': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@svgr/core': 8.1.0(typescript@5.8.3) - '@svgr/webpack': 8.1.0(typescript@5.8.3) + '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/types': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@svgr/core': 8.1.0(typescript@5.9.2) + '@svgr/webpack': 8.1.0(typescript@5.9.2) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) tslib: 2.8.1 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' @@ -17501,23 +17481,23 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/preset-classic@3.8.1(@algolia/client-search@5.34.1)(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.8.3)': + '@docusaurus/preset-classic@3.8.1(@algolia/client-search@5.35.0)(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/plugin-content-blog': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/plugin-content-docs': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/plugin-content-pages': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/plugin-css-cascade-layers': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/plugin-debug': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/plugin-google-analytics': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/plugin-google-gtag': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/plugin-google-tag-manager': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/plugin-sitemap': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/plugin-svgr': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/theme-classic': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/theme-search-algolia': 3.8.1(@algolia/client-search@5.34.1)(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.8.3) - '@docusaurus/types': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-content-blog': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-content-docs': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-content-pages': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-css-cascade-layers': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-debug': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-google-analytics': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-google-gtag': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-google-tag-manager': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-sitemap': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-svgr': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/theme-classic': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-search-algolia': 3.8.1(@algolia/client-search@5.35.0)(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2) + '@docusaurus/types': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) transitivePeerDependencies: @@ -17547,21 +17527,21 @@ snapshots: '@types/react': 19.1.2 react: 18.3.1 - '@docusaurus/theme-classic@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)': + '@docusaurus/theme-classic@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) + '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/logger': 3.8.1 - '@docusaurus/mdx-loader': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/module-type-aliases': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/plugin-content-blog': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/plugin-content-docs': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/plugin-content-pages': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/mdx-loader': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/module-type-aliases': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-blog': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-content-docs': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-content-pages': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/theme-translations': 3.8.1 - '@docusaurus/types': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-common': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mdx-js/react': 3.1.0(@types/react@19.1.2)(react@18.3.1) clsx: 2.1.1 copy-text-to-clipboard: 3.2.0 @@ -17596,13 +17576,13 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/theme-common@3.8.1(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/theme-common@3.8.1(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@docusaurus/mdx-loader': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/module-type-aliases': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/plugin-content-docs': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/utils': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-common': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/mdx-loader': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/module-type-aliases': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-docs': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/utils': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/history': 4.7.11 '@types/react': 19.1.2 '@types/react-router-config': 5.0.11 @@ -17621,13 +17601,13 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/theme-mermaid@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)': + '@docusaurus/theme-mermaid@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/module-type-aliases': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/types': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/module-type-aliases': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) mermaid: 11.9.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -17652,18 +17632,18 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/theme-search-algolia@3.8.1(@algolia/client-search@5.34.1)(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.8.3)': + '@docusaurus/theme-search-algolia@3.8.1(@algolia/client-search@5.35.0)(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2)': dependencies: - '@docsearch/react': 3.9.0(@algolia/client-search@5.34.1)(@types/react@19.1.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3) - '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) + '@docsearch/react': 3.9.0(@algolia/client-search@5.35.0)(@types/react@19.1.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3) + '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/logger': 3.8.1 - '@docusaurus/plugin-content-docs': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-docs': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/theme-translations': 3.8.1 - '@docusaurus/utils': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - algoliasearch: 5.34.1 - algoliasearch-helper: 3.26.0(algoliasearch@5.34.1) + '@docusaurus/utils': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + algoliasearch: 5.35.0 + algoliasearch-helper: 3.26.0(algoliasearch@5.35.0) clsx: 2.1.1 eta: 2.2.0 fs-extra: 11.3.0 @@ -17699,7 +17679,7 @@ snapshots: fs-extra: 11.3.0 tslib: 2.8.1 - '@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@mdx-js/mdx': 3.1.0(acorn@8.15.0) '@types/history': 4.7.11 @@ -17710,7 +17690,7 @@ snapshots: react-dom: 18.3.1(react@18.3.1) react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)' utility-types: 3.11.0 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) webpack-merge: 5.10.0 transitivePeerDependencies: - '@swc/core' @@ -17720,9 +17700,9 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils-common@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/utils-common@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@docusaurus/types': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) tslib: 2.8.1 transitivePeerDependencies: - '@swc/core' @@ -17734,11 +17714,11 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils-validation@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/utils-validation@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@docusaurus/logger': 3.8.1 - '@docusaurus/utils': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-common': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) fs-extra: 11.3.0 joi: 17.13.3 js-yaml: 4.1.0 @@ -17754,14 +17734,14 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/utils@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@docusaurus/logger': 3.8.1 - '@docusaurus/types': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-common': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) escape-string-regexp: 4.0.0 execa: 5.1.1 - file-loader: 6.2.0(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + file-loader: 6.2.0(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) fs-extra: 11.3.0 github-slugger: 1.5.0 globby: 11.1.0 @@ -17774,9 +17754,9 @@ snapshots: prompts: 2.4.2 resolve-pathname: 3.0.0 tslib: 2.8.1 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))))(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) utility-types: 3.11.0 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) transitivePeerDependencies: - '@swc/core' - acorn @@ -18045,30 +18025,30 @@ snapshots: '@faker-js/faker@9.9.0': {} - '@floating-ui/core@1.7.2': + '@floating-ui/core@1.7.3': dependencies: '@floating-ui/utils': 0.2.10 - '@floating-ui/dom@1.7.2': + '@floating-ui/dom@1.7.3': dependencies: - '@floating-ui/core': 1.7.2 + '@floating-ui/core': 1.7.3 '@floating-ui/utils': 0.2.10 - '@floating-ui/react-dom@2.1.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@floating-ui/react-dom@2.1.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@floating-ui/dom': 1.7.2 + '@floating-ui/dom': 1.7.3 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@floating-ui/react-dom@2.1.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@floating-ui/react-dom@2.1.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@floating-ui/dom': 1.7.2 + '@floating-ui/dom': 1.7.3 react: 19.1.0 react-dom: 19.1.0(react@19.1.0) '@floating-ui/react@0.26.28(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@floating-ui/react-dom': 2.1.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@floating-ui/react-dom': 2.1.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@floating-ui/utils': 0.2.10 react: 19.1.0 react-dom: 19.1.0(react@19.1.0) @@ -18149,7 +18129,7 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@headlessui/react@2.2.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@headlessui/react@2.2.7(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@floating-ui/react': 0.26.28(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@react-aria/focus': 3.21.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -18167,11 +18147,11 @@ snapshots: dependencies: react: 19.1.0 - '@hookform/error-message@2.0.1(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.61.1(react@18.3.1))(react@18.3.1)': + '@hookform/error-message@2.0.1(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.62.0(react@18.3.1))(react@18.3.1)': dependencies: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-hook-form: 7.61.1(react@18.3.1) + react-hook-form: 7.62.0(react@18.3.1) '@humanwhocodes/config-array@0.13.0': dependencies: @@ -18332,9 +18312,9 @@ snapshots: '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.2)(react@18.3.1) '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.2)(react@18.3.1) '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@18.3.1) - '@zag-js/focus-trap': 1.20.1 - '@zag-js/presence': 1.20.1 - '@zag-js/react': 1.20.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@zag-js/focus-trap': 1.21.1 + '@zag-js/presence': 1.21.1 + '@zag-js/react': 1.21.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) altcha-lib: 1.3.0 aria-hidden: 1.2.6 dequal: 2.0.3 @@ -18433,7 +18413,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 22.16.5 + '@types/node': 22.17.0 '@types/yargs': 17.0.33 chalk: 4.1.2 @@ -19059,7 +19039,7 @@ snapshots: hast-util-to-jsx-runtime: 2.3.6 markdown-extensions: 2.0.0 recma-build-jsx: 1.0.0 - recma-jsx: 1.0.0(acorn@8.15.0) + recma-jsx: 1.0.1(acorn@8.15.0) recma-stringify: 1.0.0 rehype-recma: 1.0.0 remark-mdx: 3.1.0 @@ -19085,30 +19065,30 @@ snapshots: dependencies: langium: 3.3.1 - '@module-federation/error-codes@0.17.0': {} + '@module-federation/error-codes@0.17.1': {} - '@module-federation/runtime-core@0.17.0': + '@module-federation/runtime-core@0.17.1': dependencies: - '@module-federation/error-codes': 0.17.0 - '@module-federation/sdk': 0.17.0 + '@module-federation/error-codes': 0.17.1 + '@module-federation/sdk': 0.17.1 - '@module-federation/runtime-tools@0.17.0': + '@module-federation/runtime-tools@0.17.1': dependencies: - '@module-federation/runtime': 0.17.0 - '@module-federation/webpack-bundler-runtime': 0.17.0 + '@module-federation/runtime': 0.17.1 + '@module-federation/webpack-bundler-runtime': 0.17.1 - '@module-federation/runtime@0.17.0': + '@module-federation/runtime@0.17.1': dependencies: - '@module-federation/error-codes': 0.17.0 - '@module-federation/runtime-core': 0.17.0 - '@module-federation/sdk': 0.17.0 + '@module-federation/error-codes': 0.17.1 + '@module-federation/runtime-core': 0.17.1 + '@module-federation/sdk': 0.17.1 - '@module-federation/sdk@0.17.0': {} + '@module-federation/sdk@0.17.1': {} - '@module-federation/webpack-bundler-runtime@0.17.0': + '@module-federation/webpack-bundler-runtime@0.17.1': dependencies: - '@module-federation/runtime': 0.17.0 - '@module-federation/sdk': 0.17.0 + '@module-federation/runtime': 0.17.1 + '@module-federation/sdk': 0.17.1 '@napi-rs/wasm-runtime@0.2.12': dependencies: @@ -19166,11 +19146,11 @@ snapshots: '@next/swc-win32-x64-msvc@15.4.0-canary.86': optional: true - '@ngtools/webpack@16.2.16(@angular/compiler-cli@16.2.12(@angular/compiler@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3)))(typescript@5.1.6))(typescript@5.1.6)(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17))': + '@ngtools/webpack@16.2.16(@angular/compiler-cli@16.2.12(@angular/compiler@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3)))(typescript@5.1.6))(typescript@5.1.6)(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17))': dependencies: '@angular/compiler-cli': 16.2.12(@angular/compiler@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3)))(typescript@5.1.6) typescript: 5.1.6 - webpack: 5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17) + webpack: 5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17) '@ngx-translate/core@15.0.0(@angular/common@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3))(rxjs@7.8.2))(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3))(rxjs@7.8.2)': dependencies: @@ -19245,26 +19225,26 @@ snapshots: - bluebird - supports-color - '@nrwl/devkit@16.5.1(nx@16.5.1(@swc/core@1.13.2(@swc/helpers@0.5.17)))': + '@nrwl/devkit@16.5.1(nx@16.5.1(@swc/core@1.13.3(@swc/helpers@0.5.17)))': dependencies: - '@nx/devkit': 16.5.1(nx@16.5.1(@swc/core@1.13.2(@swc/helpers@0.5.17))) + '@nx/devkit': 16.5.1(nx@16.5.1(@swc/core@1.13.3(@swc/helpers@0.5.17))) transitivePeerDependencies: - nx - '@nrwl/tao@16.5.1(@swc/core@1.13.2(@swc/helpers@0.5.17))': + '@nrwl/tao@16.5.1(@swc/core@1.13.3(@swc/helpers@0.5.17))': dependencies: - nx: 16.5.1(@swc/core@1.13.2(@swc/helpers@0.5.17)) + nx: 16.5.1(@swc/core@1.13.3(@swc/helpers@0.5.17)) transitivePeerDependencies: - '@swc-node/register' - '@swc/core' - debug - '@nx/devkit@16.5.1(nx@16.5.1(@swc/core@1.13.2(@swc/helpers@0.5.17)))': + '@nx/devkit@16.5.1(nx@16.5.1(@swc/core@1.13.3(@swc/helpers@0.5.17)))': dependencies: - '@nrwl/devkit': 16.5.1(nx@16.5.1(@swc/core@1.13.2(@swc/helpers@0.5.17))) + '@nrwl/devkit': 16.5.1(nx@16.5.1(@swc/core@1.13.3(@swc/helpers@0.5.17))) ejs: 3.1.10 ignore: 5.2.4 - nx: 16.5.1(@swc/core@1.13.2(@swc/helpers@0.5.17)) + nx: 16.5.1(@swc/core@1.13.3(@swc/helpers@0.5.17)) semver: 7.5.3 tmp: 0.2.1 tslib: 2.8.1 @@ -19438,9 +19418,9 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@playwright/test@1.54.1': + '@playwright/test@1.54.2': dependencies: - playwright: 1.54.1 + playwright: 1.54.2 '@pnpm/config.env-replace@1.1.0': {} @@ -19775,7 +19755,7 @@ snapshots: '@radix-ui/react-popper@1.2.1(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@floating-ui/react-dom': 2.1.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@floating-ui/react-dom': 2.1.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-arrow': 1.1.1(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.2)(react@18.3.1) '@radix-ui/react-context': 1.1.1(@types/react@19.1.2)(react@18.3.1) @@ -19793,7 +19773,7 @@ snapshots: '@radix-ui/react-popper@1.2.2(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@floating-ui/react-dom': 2.1.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@floating-ui/react-dom': 2.1.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-arrow': 1.1.2(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.2)(react@18.3.1) '@radix-ui/react-context': 1.1.1(@types/react@19.1.2)(react@18.3.1) @@ -19811,7 +19791,7 @@ snapshots: '@radix-ui/react-popper@1.2.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@floating-ui/react-dom': 2.1.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@floating-ui/react-dom': 2.1.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@18.3.1) '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@18.3.1) @@ -19829,7 +19809,7 @@ snapshots: '@radix-ui/react-popper@1.2.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@floating-ui/react-dom': 2.1.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@floating-ui/react-dom': 2.1.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) @@ -20282,7 +20262,7 @@ snapshots: dependencies: react: 19.1.0 - '@redocly/ajv@8.11.2': + '@redocly/ajv@8.11.3': dependencies: fast-deep-equal: 3.1.3 json-schema-traverse: 1.0.0 @@ -20291,9 +20271,9 @@ snapshots: '@redocly/config@0.22.2': {} - '@redocly/openapi-core@1.34.3': + '@redocly/openapi-core@1.34.5': dependencies: - '@redocly/ajv': 8.11.2 + '@redocly/ajv': 8.11.3 '@redocly/config': 0.22.2 colorette: 1.4.0 https-proxy-agent: 7.0.6 @@ -20317,115 +20297,115 @@ snapshots: '@rolldown/pluginutils@1.0.0-beta.27': {} - '@rollup/rollup-android-arm-eabi@4.45.1': + '@rollup/rollup-android-arm-eabi@4.46.2': optional: true - '@rollup/rollup-android-arm64@4.45.1': + '@rollup/rollup-android-arm64@4.46.2': optional: true - '@rollup/rollup-darwin-arm64@4.45.1': + '@rollup/rollup-darwin-arm64@4.46.2': optional: true - '@rollup/rollup-darwin-x64@4.45.1': + '@rollup/rollup-darwin-x64@4.46.2': optional: true - '@rollup/rollup-freebsd-arm64@4.45.1': + '@rollup/rollup-freebsd-arm64@4.46.2': optional: true - '@rollup/rollup-freebsd-x64@4.45.1': + '@rollup/rollup-freebsd-x64@4.46.2': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.45.1': + '@rollup/rollup-linux-arm-gnueabihf@4.46.2': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.45.1': + '@rollup/rollup-linux-arm-musleabihf@4.46.2': optional: true - '@rollup/rollup-linux-arm64-gnu@4.45.1': + '@rollup/rollup-linux-arm64-gnu@4.46.2': optional: true - '@rollup/rollup-linux-arm64-musl@4.45.1': + '@rollup/rollup-linux-arm64-musl@4.46.2': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.45.1': + '@rollup/rollup-linux-loongarch64-gnu@4.46.2': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.45.1': + '@rollup/rollup-linux-ppc64-gnu@4.46.2': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.45.1': + '@rollup/rollup-linux-riscv64-gnu@4.46.2': optional: true - '@rollup/rollup-linux-riscv64-musl@4.45.1': + '@rollup/rollup-linux-riscv64-musl@4.46.2': optional: true - '@rollup/rollup-linux-s390x-gnu@4.45.1': + '@rollup/rollup-linux-s390x-gnu@4.46.2': optional: true - '@rollup/rollup-linux-x64-gnu@4.45.1': + '@rollup/rollup-linux-x64-gnu@4.46.2': optional: true - '@rollup/rollup-linux-x64-musl@4.45.1': + '@rollup/rollup-linux-x64-musl@4.46.2': optional: true - '@rollup/rollup-win32-arm64-msvc@4.45.1': + '@rollup/rollup-win32-arm64-msvc@4.46.2': optional: true - '@rollup/rollup-win32-ia32-msvc@4.45.1': + '@rollup/rollup-win32-ia32-msvc@4.46.2': optional: true - '@rollup/rollup-win32-x64-msvc@4.45.1': + '@rollup/rollup-win32-x64-msvc@4.46.2': optional: true - '@rspack/binding-darwin-arm64@1.4.10': + '@rspack/binding-darwin-arm64@1.4.11': optional: true - '@rspack/binding-darwin-x64@1.4.10': + '@rspack/binding-darwin-x64@1.4.11': optional: true - '@rspack/binding-linux-arm64-gnu@1.4.10': + '@rspack/binding-linux-arm64-gnu@1.4.11': optional: true - '@rspack/binding-linux-arm64-musl@1.4.10': + '@rspack/binding-linux-arm64-musl@1.4.11': optional: true - '@rspack/binding-linux-x64-gnu@1.4.10': + '@rspack/binding-linux-x64-gnu@1.4.11': optional: true - '@rspack/binding-linux-x64-musl@1.4.10': + '@rspack/binding-linux-x64-musl@1.4.11': optional: true - '@rspack/binding-wasm32-wasi@1.4.10': + '@rspack/binding-wasm32-wasi@1.4.11': dependencies: '@napi-rs/wasm-runtime': 1.0.1 optional: true - '@rspack/binding-win32-arm64-msvc@1.4.10': + '@rspack/binding-win32-arm64-msvc@1.4.11': optional: true - '@rspack/binding-win32-ia32-msvc@1.4.10': + '@rspack/binding-win32-ia32-msvc@1.4.11': optional: true - '@rspack/binding-win32-x64-msvc@1.4.10': + '@rspack/binding-win32-x64-msvc@1.4.11': optional: true - '@rspack/binding@1.4.10': + '@rspack/binding@1.4.11': optionalDependencies: - '@rspack/binding-darwin-arm64': 1.4.10 - '@rspack/binding-darwin-x64': 1.4.10 - '@rspack/binding-linux-arm64-gnu': 1.4.10 - '@rspack/binding-linux-arm64-musl': 1.4.10 - '@rspack/binding-linux-x64-gnu': 1.4.10 - '@rspack/binding-linux-x64-musl': 1.4.10 - '@rspack/binding-wasm32-wasi': 1.4.10 - '@rspack/binding-win32-arm64-msvc': 1.4.10 - '@rspack/binding-win32-ia32-msvc': 1.4.10 - '@rspack/binding-win32-x64-msvc': 1.4.10 + '@rspack/binding-darwin-arm64': 1.4.11 + '@rspack/binding-darwin-x64': 1.4.11 + '@rspack/binding-linux-arm64-gnu': 1.4.11 + '@rspack/binding-linux-arm64-musl': 1.4.11 + '@rspack/binding-linux-x64-gnu': 1.4.11 + '@rspack/binding-linux-x64-musl': 1.4.11 + '@rspack/binding-wasm32-wasi': 1.4.11 + '@rspack/binding-win32-arm64-msvc': 1.4.11 + '@rspack/binding-win32-ia32-msvc': 1.4.11 + '@rspack/binding-win32-x64-msvc': 1.4.11 - '@rspack/core@1.4.10(@swc/helpers@0.5.17)': + '@rspack/core@1.4.11(@swc/helpers@0.5.17)': dependencies: - '@module-federation/runtime-tools': 0.17.0 - '@rspack/binding': 1.4.10 + '@module-federation/runtime-tools': 0.17.1 + '@rspack/binding': 1.4.11 '@rspack/lite-tapable': 1.0.1 optionalDependencies: '@swc/helpers': 0.5.17 @@ -20452,9 +20432,9 @@ snapshots: '@sideway/pinpoint@2.0.0': {} - '@signalwire/docusaurus-plugin-llms-txt@1.2.2(@docusaurus/core@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))': + '@signalwire/docusaurus-plugin-llms-txt@1.2.2(@docusaurus/core@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))': dependencies: - '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) + '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) fs-extra: 11.3.0 hast-util-select: 6.0.4 hast-util-to-html: 9.0.5 @@ -20559,12 +20539,12 @@ snapshots: '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.28.0) '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.28.0) - '@svgr/core@8.1.0(typescript@5.8.3)': + '@svgr/core@8.1.0(typescript@5.9.2)': dependencies: '@babel/core': 7.28.0 '@svgr/babel-preset': 8.1.0(@babel/core@7.28.0) camelcase: 6.3.0 - cosmiconfig: 8.3.6(typescript@5.8.3) + cosmiconfig: 8.3.6(typescript@5.9.2) snake-case: 3.0.4 transitivePeerDependencies: - supports-color @@ -20575,84 +20555,84 @@ snapshots: '@babel/types': 7.28.2 entities: 4.5.0 - '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.8.3))': + '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.9.2))': dependencies: '@babel/core': 7.28.0 '@svgr/babel-preset': 8.1.0(@babel/core@7.28.0) - '@svgr/core': 8.1.0(typescript@5.8.3) + '@svgr/core': 8.1.0(typescript@5.9.2) '@svgr/hast-util-to-babel-ast': 8.0.0 svg-parser: 2.0.4 transitivePeerDependencies: - supports-color - '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@5.8.3))(typescript@5.8.3)': + '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@5.9.2))(typescript@5.9.2)': dependencies: - '@svgr/core': 8.1.0(typescript@5.8.3) - cosmiconfig: 8.3.6(typescript@5.8.3) + '@svgr/core': 8.1.0(typescript@5.9.2) + cosmiconfig: 8.3.6(typescript@5.9.2) deepmerge: 4.3.1 svgo: 3.3.2 transitivePeerDependencies: - typescript - '@svgr/webpack@8.1.0(typescript@5.8.3)': + '@svgr/webpack@8.1.0(typescript@5.9.2)': dependencies: '@babel/core': 7.28.0 '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.28.0) '@babel/preset-env': 7.28.0(@babel/core@7.28.0) '@babel/preset-react': 7.27.1(@babel/core@7.28.0) '@babel/preset-typescript': 7.27.1(@babel/core@7.28.0) - '@svgr/core': 8.1.0(typescript@5.8.3) - '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.8.3)) - '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.8.3))(typescript@5.8.3) + '@svgr/core': 8.1.0(typescript@5.9.2) + '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.2)) + '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.9.2))(typescript@5.9.2) transitivePeerDependencies: - supports-color - typescript - '@swc/core-darwin-arm64@1.13.2': + '@swc/core-darwin-arm64@1.13.3': optional: true - '@swc/core-darwin-x64@1.13.2': + '@swc/core-darwin-x64@1.13.3': optional: true - '@swc/core-linux-arm-gnueabihf@1.13.2': + '@swc/core-linux-arm-gnueabihf@1.13.3': optional: true - '@swc/core-linux-arm64-gnu@1.13.2': + '@swc/core-linux-arm64-gnu@1.13.3': optional: true - '@swc/core-linux-arm64-musl@1.13.2': + '@swc/core-linux-arm64-musl@1.13.3': optional: true - '@swc/core-linux-x64-gnu@1.13.2': + '@swc/core-linux-x64-gnu@1.13.3': optional: true - '@swc/core-linux-x64-musl@1.13.2': + '@swc/core-linux-x64-musl@1.13.3': optional: true - '@swc/core-win32-arm64-msvc@1.13.2': + '@swc/core-win32-arm64-msvc@1.13.3': optional: true - '@swc/core-win32-ia32-msvc@1.13.2': + '@swc/core-win32-ia32-msvc@1.13.3': optional: true - '@swc/core-win32-x64-msvc@1.13.2': + '@swc/core-win32-x64-msvc@1.13.3': optional: true - '@swc/core@1.13.2(@swc/helpers@0.5.17)': + '@swc/core@1.13.3(@swc/helpers@0.5.17)': dependencies: '@swc/counter': 0.1.3 '@swc/types': 0.1.23 optionalDependencies: - '@swc/core-darwin-arm64': 1.13.2 - '@swc/core-darwin-x64': 1.13.2 - '@swc/core-linux-arm-gnueabihf': 1.13.2 - '@swc/core-linux-arm64-gnu': 1.13.2 - '@swc/core-linux-arm64-musl': 1.13.2 - '@swc/core-linux-x64-gnu': 1.13.2 - '@swc/core-linux-x64-musl': 1.13.2 - '@swc/core-win32-arm64-msvc': 1.13.2 - '@swc/core-win32-ia32-msvc': 1.13.2 - '@swc/core-win32-x64-msvc': 1.13.2 + '@swc/core-darwin-arm64': 1.13.3 + '@swc/core-darwin-x64': 1.13.3 + '@swc/core-linux-arm-gnueabihf': 1.13.3 + '@swc/core-linux-arm64-gnu': 1.13.3 + '@swc/core-linux-arm64-musl': 1.13.3 + '@swc/core-linux-x64-gnu': 1.13.3 + '@swc/core-linux-x64-musl': 1.13.3 + '@swc/core-win32-arm64-msvc': 1.13.3 + '@swc/core-win32-ia32-msvc': 1.13.3 + '@swc/core-win32-x64-msvc': 1.13.3 '@swc/helpers': 0.5.17 '@swc/counter@0.1.3': {} @@ -20665,50 +20645,50 @@ snapshots: dependencies: tslib: 2.8.1 - '@swc/html-darwin-arm64@1.13.2': + '@swc/html-darwin-arm64@1.13.3': optional: true - '@swc/html-darwin-x64@1.13.2': + '@swc/html-darwin-x64@1.13.3': optional: true - '@swc/html-linux-arm-gnueabihf@1.13.2': + '@swc/html-linux-arm-gnueabihf@1.13.3': optional: true - '@swc/html-linux-arm64-gnu@1.13.2': + '@swc/html-linux-arm64-gnu@1.13.3': optional: true - '@swc/html-linux-arm64-musl@1.13.2': + '@swc/html-linux-arm64-musl@1.13.3': optional: true - '@swc/html-linux-x64-gnu@1.13.2': + '@swc/html-linux-x64-gnu@1.13.3': optional: true - '@swc/html-linux-x64-musl@1.13.2': + '@swc/html-linux-x64-musl@1.13.3': optional: true - '@swc/html-win32-arm64-msvc@1.13.2': + '@swc/html-win32-arm64-msvc@1.13.3': optional: true - '@swc/html-win32-ia32-msvc@1.13.2': + '@swc/html-win32-ia32-msvc@1.13.3': optional: true - '@swc/html-win32-x64-msvc@1.13.2': + '@swc/html-win32-x64-msvc@1.13.3': optional: true - '@swc/html@1.13.2': + '@swc/html@1.13.3': dependencies: '@swc/counter': 0.1.3 optionalDependencies: - '@swc/html-darwin-arm64': 1.13.2 - '@swc/html-darwin-x64': 1.13.2 - '@swc/html-linux-arm-gnueabihf': 1.13.2 - '@swc/html-linux-arm64-gnu': 1.13.2 - '@swc/html-linux-arm64-musl': 1.13.2 - '@swc/html-linux-x64-gnu': 1.13.2 - '@swc/html-linux-x64-musl': 1.13.2 - '@swc/html-win32-arm64-msvc': 1.13.2 - '@swc/html-win32-ia32-msvc': 1.13.2 - '@swc/html-win32-x64-msvc': 1.13.2 + '@swc/html-darwin-arm64': 1.13.3 + '@swc/html-darwin-x64': 1.13.3 + '@swc/html-linux-arm-gnueabihf': 1.13.3 + '@swc/html-linux-arm64-gnu': 1.13.3 + '@swc/html-linux-arm64-musl': 1.13.3 + '@swc/html-linux-x64-gnu': 1.13.3 + '@swc/html-linux-x64-musl': 1.13.3 + '@swc/html-win32-arm64-msvc': 1.13.3 + '@swc/html-win32-ia32-msvc': 1.13.3 + '@swc/html-win32-x64-msvc': 1.13.3 '@swc/types@0.1.23': dependencies: @@ -20743,31 +20723,31 @@ snapshots: '@tanstack/virtual-core@3.13.12': {} - '@testing-library/dom@10.4.0': + '@testing-library/dom@10.4.1': dependencies: '@babel/code-frame': 7.27.1 '@babel/runtime': 7.28.2 '@types/aria-query': 5.0.4 aria-query: 5.3.0 - chalk: 4.1.2 dom-accessibility-api: 0.5.16 lz-string: 1.5.0 + picocolors: 1.1.1 pretty-format: 27.5.1 - '@testing-library/jest-dom@6.6.3': + '@testing-library/jest-dom@6.6.4': dependencies: '@adobe/css-tools': 4.4.3 aria-query: 5.3.2 - chalk: 3.0.0 css.escape: 1.5.1 dom-accessibility-api: 0.6.3 lodash: 4.17.21 + picocolors: 1.1.1 redent: 3.0.0 - '@testing-library/react@16.3.0(@testing-library/dom@10.4.0)(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@babel/runtime': 7.28.2 - '@testing-library/dom': 10.4.0 + '@testing-library/dom': 10.4.1 react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: @@ -20808,7 +20788,7 @@ snapshots: '@babel/types': 7.28.2 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.7 + '@types/babel__traverse': 7.28.0 '@types/babel__generator@7.27.0': dependencies: @@ -20819,18 +20799,18 @@ snapshots: '@babel/parser': 7.28.0 '@babel/types': 7.28.2 - '@types/babel__traverse@7.20.7': + '@types/babel__traverse@7.28.0': dependencies: '@babel/types': 7.28.2 '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.16.5 + '@types/node': 22.17.0 '@types/bonjour@3.5.13': dependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 '@types/codemirror@5.60.16': dependencies: @@ -20839,15 +20819,15 @@ snapshots: '@types/connect-history-api-fallback@1.5.4': dependencies: '@types/express-serve-static-core': 5.0.7 - '@types/node': 22.16.5 + '@types/node': 22.17.0 '@types/connect@3.4.38': dependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 '@types/cors@2.8.19': dependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 '@types/d3-array@3.2.1': {} @@ -20870,7 +20850,7 @@ snapshots: '@types/d3-delaunay@6.0.4': {} - '@types/d3-dispatch@3.0.6': {} + '@types/d3-dispatch@3.0.7': {} '@types/d3-drag@3.0.7': dependencies: @@ -20942,7 +20922,7 @@ snapshots: '@types/d3-color': 3.1.3 '@types/d3-contour': 3.0.6 '@types/d3-delaunay': 6.0.4 - '@types/d3-dispatch': 3.0.6 + '@types/d3-dispatch': 3.0.7 '@types/d3-drag': 3.0.7 '@types/d3-dsv': 3.0.7 '@types/d3-ease': 3.0.2 @@ -20988,14 +20968,14 @@ snapshots: '@types/express-serve-static-core@4.19.6': dependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 0.17.5 '@types/express-serve-static-core@5.0.7': dependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 0.17.5 @@ -21038,7 +21018,7 @@ snapshots: '@types/http-proxy@1.17.16': dependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 '@types/istanbul-lib-coverage@2.0.6': {} @@ -21063,7 +21043,7 @@ snapshots: '@types/jsonwebtoken@9.0.10': dependencies: '@types/ms': 2.1.0 - '@types/node': 22.16.5 + '@types/node': 22.17.0 '@types/mdast@3.0.15': dependencies: @@ -21079,24 +21059,24 @@ snapshots: '@types/ms@2.1.0': {} - '@types/node-fetch@2.6.12': + '@types/node-fetch@2.6.13': dependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 form-data: 4.0.4 '@types/node-forge@1.3.13': dependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 '@types/node@12.20.55': {} '@types/node@17.0.45': {} - '@types/node@18.19.120': + '@types/node@18.19.121': dependencies: undici-types: 5.26.5 - '@types/node@22.16.5': + '@types/node@22.17.0': dependencies: undici-types: 6.21.0 @@ -21110,9 +21090,9 @@ snapshots: '@types/parse5@6.0.3': {} - '@types/pg@8.15.4': + '@types/pg@8.15.5': dependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 pg-protocol: 1.10.3 pg-types: 2.2.0 @@ -21122,7 +21102,7 @@ snapshots: '@types/qrcode@1.5.5': dependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 '@types/qs@6.14.0': {} @@ -21164,14 +21144,14 @@ snapshots: '@types/sax@1.2.7': dependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 '@types/semver@7.7.0': {} '@types/send@0.17.5': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.16.5 + '@types/node': 22.17.0 '@types/serve-index@1.9.4': dependencies: @@ -21180,7 +21160,7 @@ snapshots: '@types/serve-static@1.15.8': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 22.16.5 + '@types/node': 22.17.0 '@types/send': 0.17.5 '@types/sinonjs__fake-timers@8.1.1': {} @@ -21189,7 +21169,7 @@ snapshots: '@types/sockjs@0.3.36': dependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 '@types/tern@0.23.9': dependencies: @@ -21208,7 +21188,7 @@ snapshots: '@types/ws@8.18.1': dependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 '@types/yargs-parser@21.0.3': {} @@ -21218,7 +21198,7 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 optional: true '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6)': @@ -21240,38 +21220,38 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.38.0(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/parser': 8.38.0(eslint@8.57.1)(typescript@5.9.2) '@typescript-eslint/scope-manager': 7.18.0 - '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.9.2) '@typescript-eslint/visitor-keys': 7.18.0 eslint: 8.57.1 graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 1.4.3(typescript@5.8.3) + ts-api-utils: 1.4.3(typescript@5.9.2) optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.38.0(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.38.0(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.38.0(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/parser': 8.38.0(eslint@8.57.1)(typescript@5.9.2) '@typescript-eslint/scope-manager': 8.38.0 - '@typescript-eslint/type-utils': 8.38.0(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/utils': 8.38.0(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/type-utils': 8.38.0(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/utils': 8.38.0(eslint@8.57.1)(typescript@5.9.2) '@typescript-eslint/visitor-keys': 8.38.0 eslint: 8.57.1 graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + ts-api-utils: 2.1.0(typescript@5.9.2) + typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -21287,15 +21267,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.8.3)': + '@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.9.2)': dependencies: '@typescript-eslint/scope-manager': 8.38.0 '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.9.2) '@typescript-eslint/visitor-keys': 8.38.0 debug: 4.4.1(supports-color@5.5.0) eslint: 8.57.1 - typescript: 5.8.3 + typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -21308,12 +21288,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.38.0(typescript@5.8.3)': + '@typescript-eslint/project-service@8.38.0(typescript@5.9.2)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.38.0(typescript@5.8.3) + '@typescript-eslint/tsconfig-utils': 8.38.0(typescript@5.9.2) '@typescript-eslint/types': 8.38.0 debug: 4.4.1(supports-color@5.5.0) - typescript: 5.8.3 + typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -21341,9 +21321,9 @@ snapshots: dependencies: typescript: 5.1.6 - '@typescript-eslint/tsconfig-utils@8.38.0(typescript@5.8.3)': + '@typescript-eslint/tsconfig-utils@8.38.0(typescript@5.9.2)': dependencies: - typescript: 5.8.3 + typescript: 5.9.2 '@typescript-eslint/type-utils@5.62.0(eslint@8.57.1)(typescript@5.1.6)': dependencies: @@ -21357,27 +21337,27 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@7.18.0(eslint@8.57.1)(typescript@5.8.3)': + '@typescript-eslint/type-utils@7.18.0(eslint@8.57.1)(typescript@5.9.2)': dependencies: - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.8.3) - '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.9.2) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.9.2) debug: 4.4.1(supports-color@5.5.0) eslint: 8.57.1 - ts-api-utils: 1.4.3(typescript@5.8.3) + ts-api-utils: 1.4.3(typescript@5.9.2) optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.38.0(eslint@8.57.1)(typescript@5.8.3)': + '@typescript-eslint/type-utils@8.38.0(eslint@8.57.1)(typescript@5.9.2)': dependencies: '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.38.0(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.9.2) + '@typescript-eslint/utils': 8.38.0(eslint@8.57.1)(typescript@5.9.2) debug: 4.4.1(supports-color@5.5.0) eslint: 8.57.1 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + ts-api-utils: 2.1.0(typescript@5.9.2) + typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -21403,7 +21383,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@7.18.0(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@7.18.0(typescript@5.9.2)': dependencies: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0 @@ -21412,9 +21392,9 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.7.2 - ts-api-utils: 1.4.3(typescript@5.8.3) + ts-api-utils: 1.4.3(typescript@5.9.2) optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -21449,10 +21429,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.38.0(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@8.38.0(typescript@5.9.2)': dependencies: - '@typescript-eslint/project-service': 8.38.0(typescript@5.8.3) - '@typescript-eslint/tsconfig-utils': 8.38.0(typescript@5.8.3) + '@typescript-eslint/project-service': 8.38.0(typescript@5.9.2) + '@typescript-eslint/tsconfig-utils': 8.38.0(typescript@5.9.2) '@typescript-eslint/types': 8.38.0 '@typescript-eslint/visitor-keys': 8.38.0 debug: 4.4.1(supports-color@5.5.0) @@ -21460,8 +21440,8 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.7.2 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + ts-api-utils: 2.1.0(typescript@5.9.2) + typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -21480,12 +21460,12 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@7.18.0(eslint@8.57.1)(typescript@5.8.3)': + '@typescript-eslint/utils@7.18.0(eslint@8.57.1)(typescript@5.9.2)': dependencies: '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1) '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.9.2) eslint: 8.57.1 transitivePeerDependencies: - supports-color @@ -21502,14 +21482,14 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@8.38.0(eslint@8.57.1)(typescript@5.8.3)': + '@typescript-eslint/utils@8.38.0(eslint@8.57.1)(typescript@5.9.2)': dependencies: '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1) '@typescript-eslint/scope-manager': 8.38.0 '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.9.2) eslint: 8.57.1 - typescript: 5.8.3 + typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -21594,18 +21574,18 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.11.1': optional: true - '@vercel/analytics@1.5.0(next@15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2))(react@19.1.0)': + '@vercel/analytics@1.5.0(next@15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2))(react@19.1.0)': optionalDependencies: - next: 15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2) + next: 15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2) react: 19.1.0 '@vercel/git-hooks@1.0.0': {} - '@vitejs/plugin-basic-ssl@1.0.1(vite@4.5.5(@types/node@22.16.5)(less@4.1.3)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.19.2))': + '@vitejs/plugin-basic-ssl@1.0.1(vite@4.5.5(@types/node@22.17.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.19.2))': dependencies: - vite: 4.5.5(@types/node@22.16.5)(less@4.1.3)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.19.2) + vite: 4.5.5(@types/node@22.17.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.19.2) - '@vitejs/plugin-react@4.7.0(vite@5.4.19(@types/node@22.16.5)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1))': + '@vitejs/plugin-react@4.7.0(vite@5.4.19(@types/node@22.17.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1))': dependencies: '@babel/core': 7.28.0 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.0) @@ -21613,7 +21593,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 5.4.19(@types/node@22.16.5)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1) + vite: 5.4.19(@types/node@22.17.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1) transitivePeerDependencies: - supports-color @@ -21624,13 +21604,13 @@ snapshots: chai: 5.2.1 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.9(vite@5.4.19(@types/node@22.16.5)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1))': + '@vitest/mocker@2.1.9(vite@5.4.19(@types/node@22.17.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1))': dependencies: '@vitest/spy': 2.1.9 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 5.4.19(@types/node@22.16.5)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1) + vite: 5.4.19(@types/node@22.17.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1) '@vitest/mocker@2.1.9(vite@5.4.19(@types/node@24.1.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1))': dependencies: @@ -21765,43 +21745,43 @@ snapshots: js-yaml: 3.14.1 tslib: 2.8.1 - '@zag-js/core@1.20.1': + '@zag-js/core@1.21.1': dependencies: - '@zag-js/dom-query': 1.20.1 - '@zag-js/utils': 1.20.1 + '@zag-js/dom-query': 1.21.1 + '@zag-js/utils': 1.21.1 - '@zag-js/dom-query@1.20.1': + '@zag-js/dom-query@1.21.1': dependencies: - '@zag-js/types': 1.20.1 + '@zag-js/types': 1.21.1 - '@zag-js/focus-trap@1.20.1': + '@zag-js/focus-trap@1.21.1': dependencies: - '@zag-js/dom-query': 1.20.1 + '@zag-js/dom-query': 1.21.1 - '@zag-js/presence@1.20.1': + '@zag-js/presence@1.21.1': dependencies: - '@zag-js/core': 1.20.1 - '@zag-js/dom-query': 1.20.1 - '@zag-js/types': 1.20.1 + '@zag-js/core': 1.21.1 + '@zag-js/dom-query': 1.21.1 + '@zag-js/types': 1.21.1 - '@zag-js/react@1.20.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@zag-js/react@1.21.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@zag-js/core': 1.20.1 - '@zag-js/store': 1.20.1 - '@zag-js/types': 1.20.1 - '@zag-js/utils': 1.20.1 + '@zag-js/core': 1.21.1 + '@zag-js/store': 1.21.1 + '@zag-js/types': 1.21.1 + '@zag-js/utils': 1.21.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@zag-js/store@1.20.1': + '@zag-js/store@1.21.1': dependencies: proxy-compare: 3.0.1 - '@zag-js/types@1.20.1': + '@zag-js/types@1.21.1': dependencies: csstype: 3.1.3 - '@zag-js/utils@1.20.1': {} + '@zag-js/utils@1.21.1': {} '@zkochan/js-yaml@0.0.6': dependencies: @@ -21926,26 +21906,27 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - algoliasearch-helper@3.26.0(algoliasearch@5.34.1): + algoliasearch-helper@3.26.0(algoliasearch@5.35.0): dependencies: '@algolia/events': 4.0.1 - algoliasearch: 5.34.1 + algoliasearch: 5.35.0 - algoliasearch@5.34.1: + algoliasearch@5.35.0: dependencies: - '@algolia/client-abtesting': 5.34.1 - '@algolia/client-analytics': 5.34.1 - '@algolia/client-common': 5.34.1 - '@algolia/client-insights': 5.34.1 - '@algolia/client-personalization': 5.34.1 - '@algolia/client-query-suggestions': 5.34.1 - '@algolia/client-search': 5.34.1 - '@algolia/ingestion': 1.34.1 - '@algolia/monitoring': 1.34.1 - '@algolia/recommend': 5.34.1 - '@algolia/requester-browser-xhr': 5.34.1 - '@algolia/requester-fetch': 5.34.1 - '@algolia/requester-node-http': 5.34.1 + '@algolia/abtesting': 1.1.0 + '@algolia/client-abtesting': 5.35.0 + '@algolia/client-analytics': 5.35.0 + '@algolia/client-common': 5.35.0 + '@algolia/client-insights': 5.35.0 + '@algolia/client-personalization': 5.35.0 + '@algolia/client-query-suggestions': 5.35.0 + '@algolia/client-search': 5.35.0 + '@algolia/ingestion': 1.35.0 + '@algolia/monitoring': 1.35.0 + '@algolia/recommend': 5.35.0 + '@algolia/requester-browser-xhr': 5.35.0 + '@algolia/requester-fetch': 5.35.0 + '@algolia/requester-node-http': 5.35.0 allof-merge@0.6.6: dependencies: @@ -22137,7 +22118,7 @@ snapshots: autoprefixer@10.4.14(postcss@8.4.31): dependencies: browserslist: 4.25.1 - caniuse-lite: 1.0.30001727 + caniuse-lite: 1.0.30001731 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 @@ -22147,7 +22128,7 @@ snapshots: autoprefixer@10.4.21(postcss@8.5.3): dependencies: browserslist: 4.25.1 - caniuse-lite: 1.0.30001727 + caniuse-lite: 1.0.30001731 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 @@ -22157,7 +22138,7 @@ snapshots: autoprefixer@10.4.21(postcss@8.5.6): dependencies: browserslist: 4.25.1 - caniuse-lite: 1.0.30001727 + caniuse-lite: 1.0.30001731 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 @@ -22176,7 +22157,7 @@ snapshots: axios@1.11.0(debug@4.4.1): dependencies: - follow-redirects: 1.15.9(debug@4.4.1) + follow-redirects: 1.15.11(debug@4.4.1) form-data: 4.0.4 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -22195,19 +22176,19 @@ snapshots: b4a@1.6.7: optional: true - babel-loader@9.1.3(@babel/core@7.22.9)(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)): + babel-loader@9.1.3(@babel/core@7.22.9)(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)): dependencies: '@babel/core': 7.22.9 find-cache-dir: 4.0.0 schema-utils: 4.3.2 - webpack: 5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17) + webpack: 5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17) - babel-loader@9.2.1(@babel/core@7.28.0)(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): + babel-loader@9.2.1(@babel/core@7.28.0)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: '@babel/core': 7.28.0 find-cache-dir: 4.0.0 schema-utils: 4.3.2 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) babel-plugin-dynamic-import-node@2.3.3: dependencies: @@ -22398,8 +22379,8 @@ snapshots: browserslist@4.25.1: dependencies: - caniuse-lite: 1.0.30001727 - electron-to-chromium: 1.5.190 + caniuse-lite: 1.0.30001731 + electron-to-chromium: 1.5.194 node-releases: 2.0.19 update-browserslist-db: 1.1.3(browserslist@4.25.1) @@ -22519,11 +22500,11 @@ snapshots: caniuse-api@3.0.0: dependencies: browserslist: 4.25.1 - caniuse-lite: 1.0.30001727 + caniuse-lite: 1.0.30001731 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 - caniuse-lite@1.0.30001727: {} + caniuse-lite@1.0.30001731: {} case-anything@2.1.13: {} @@ -22539,11 +22520,6 @@ snapshots: loupe: 3.2.0 pathval: 2.0.1 - chalk@3.0.0: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -22889,7 +22865,7 @@ snapshots: dependencies: toggle-selection: 1.0.6 - copy-webpack-plugin@11.0.0(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): + copy-webpack-plugin@11.0.0(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: fast-glob: 3.3.1 glob-parent: 6.0.2 @@ -22897,9 +22873,9 @@ snapshots: normalize-path: 3.0.0 schema-utils: 4.3.2 serialize-javascript: 6.0.2 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) - copy-webpack-plugin@11.0.0(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)): + copy-webpack-plugin@11.0.0(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)): dependencies: fast-glob: 3.3.1 glob-parent: 6.0.2 @@ -22907,7 +22883,7 @@ snapshots: normalize-path: 3.0.0 schema-utils: 4.3.2 serialize-javascript: 6.0.2 - webpack: 5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17) + webpack: 5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17) core-js-compat@3.44.0: dependencies: @@ -22943,23 +22919,23 @@ snapshots: optionalDependencies: typescript: 5.1.6 - cosmiconfig@8.3.6(typescript@5.8.3): + cosmiconfig@8.3.6(typescript@5.9.2): dependencies: import-fresh: 3.3.1 js-yaml: 4.1.0 parse-json: 5.2.0 path-type: 4.0.0 optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.2 - cosmiconfig@9.0.0(typescript@5.8.3): + cosmiconfig@9.0.0(typescript@5.9.2): dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 js-yaml: 4.1.0 parse-json: 5.2.0 optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.2 optional: true critters@0.0.20: @@ -23004,7 +22980,7 @@ snapshots: postcss-selector-parser: 7.1.0 postcss-value-parser: 4.2.0 - css-loader@6.11.0(@rspack/core@1.4.10(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): + css-loader@6.11.0(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: icss-utils: 5.1.0(postcss@8.5.3) postcss: 8.5.3 @@ -23015,10 +22991,10 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.7.2 optionalDependencies: - '@rspack/core': 1.4.10(@swc/helpers@0.5.17) - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + '@rspack/core': 1.4.11(@swc/helpers@0.5.17) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) - css-loader@6.8.1(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)): + css-loader@6.8.1(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)): dependencies: icss-utils: 5.1.0(postcss@8.5.3) postcss: 8.5.3 @@ -23028,9 +23004,9 @@ snapshots: postcss-modules-values: 4.0.0(postcss@8.5.3) postcss-value-parser: 4.2.0 semver: 7.5.4 - webpack: 5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17) + webpack: 5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17) - css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): + css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: '@jridgewell/trace-mapping': 0.3.29 cssnano: 6.1.2(postcss@8.5.3) @@ -23038,7 +23014,7 @@ snapshots: postcss: 8.5.3 schema-utils: 4.3.2 serialize-javascript: 6.0.2 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) optionalDependencies: clean-css: 5.3.3 @@ -23204,53 +23180,6 @@ snapshots: cypress-wait-until@3.0.2: {} - cypress@14.5.2: - dependencies: - '@cypress/request': 3.0.8 - '@cypress/xvfb': 1.2.4(supports-color@8.1.1) - '@types/sinonjs__fake-timers': 8.1.1 - '@types/sizzle': 2.3.9 - arch: 2.2.0 - blob-util: 2.0.2 - bluebird: 3.7.2 - buffer: 5.7.1 - cachedir: 2.4.0 - chalk: 4.1.2 - check-more-types: 2.24.0 - ci-info: 4.3.0 - cli-cursor: 3.1.0 - cli-table3: 0.6.1 - commander: 6.2.1 - common-tags: 1.8.2 - dayjs: 1.11.13 - debug: 4.4.1(supports-color@8.1.1) - enquirer: 2.4.1 - eventemitter2: 6.4.7 - execa: 4.1.0 - executable: 4.1.1 - extract-zip: 2.0.1(supports-color@8.1.1) - figures: 3.2.0 - fs-extra: 9.1.0 - getos: 3.2.1 - hasha: 5.2.2 - is-installed-globally: 0.4.0 - lazy-ass: 1.6.0 - listr2: 3.14.0(enquirer@2.4.1) - lodash: 4.17.21 - log-symbols: 4.1.0 - minimist: 1.2.8 - ospath: 1.2.2 - pretty-bytes: 5.6.0 - process: 0.11.10 - proxy-from-env: 1.0.0 - request-progress: 3.0.0 - semver: 7.7.2 - supports-color: 8.1.1 - tmp: 0.2.3 - tree-kill: 1.2.2 - untildify: 4.0.0 - yauzl: 2.10.0 - cypress@14.5.3: dependencies: '@cypress/request': 3.0.9 @@ -23298,17 +23227,17 @@ snapshots: untildify: 4.0.0 yauzl: 2.10.0 - cytoscape-cose-bilkent@4.1.0(cytoscape@3.32.1): + cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.0): dependencies: cose-base: 1.0.3 - cytoscape: 3.32.1 + cytoscape: 3.33.0 - cytoscape-fcose@2.2.0(cytoscape@3.32.1): + cytoscape-fcose@2.2.0(cytoscape@3.33.0): dependencies: cose-base: 2.2.0 - cytoscape: 3.32.1 + cytoscape: 3.33.0 - cytoscape@3.32.1: {} + cytoscape@3.33.0: {} d3-array@2.12.1: dependencies: @@ -23685,19 +23614,19 @@ snapshots: dependencies: esutils: 2.0.3 - docusaurus-plugin-image-zoom@3.0.1(@docusaurus/theme-classic@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)): + docusaurus-plugin-image-zoom@3.0.1(@docusaurus/theme-classic@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)): dependencies: - '@docusaurus/theme-classic': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) + '@docusaurus/theme-classic': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/react@19.1.2)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) medium-zoom: 1.1.0 validate-peer-dependencies: 2.2.0 - docusaurus-plugin-openapi-docs@4.4.0(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@docusaurus/utils-validation@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@docusaurus/utils@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(encoding@0.1.13)(react@18.3.1): + docusaurus-plugin-openapi-docs@4.4.0(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@docusaurus/utils-validation@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@docusaurus/utils@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(encoding@0.1.13)(react@18.3.1): dependencies: '@apidevtools/json-schema-ref-parser': 11.9.3 - '@docusaurus/plugin-content-docs': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@docusaurus/utils': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@redocly/openapi-core': 1.34.3 + '@docusaurus/plugin-content-docs': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/utils': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@redocly/openapi-core': 1.34.5 allof-merge: 0.6.6 chalk: 4.1.2 clsx: 1.2.1 @@ -23716,20 +23645,20 @@ snapshots: - encoding - supports-color - docusaurus-plugin-sass@0.2.6(@docusaurus/core@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(sass@1.89.2)(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): + docusaurus-plugin-sass@0.2.6(@docusaurus/core@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(sass@1.89.2)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: - '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) + '@docusaurus/core': 3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) sass: 1.89.2 - sass-loader: 16.0.5(@rspack/core@1.4.10(@swc/helpers@0.5.17))(sass@1.89.2)(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + sass-loader: 16.0.5(@rspack/core@1.4.11(@swc/helpers@0.5.17))(sass@1.89.2)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) transitivePeerDependencies: - '@rspack/core' - node-sass - sass-embedded - webpack - docusaurus-theme-github-codeblock@2.0.2(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + docusaurus-theme-github-codeblock@2.0.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@docusaurus/types': 3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) transitivePeerDependencies: - '@swc/core' - acorn @@ -23740,18 +23669,18 @@ snapshots: - uglify-js - webpack-cli - docusaurus-theme-openapi-docs@4.4.0(16229fb59c6dfb52093786e71d2a5baa): + docusaurus-theme-openapi-docs@4.4.0(29feb2096fefbad47784d0fa17fc3949): dependencies: - '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@hookform/error-message': 2.0.1(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.61.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@hookform/error-message': 2.0.1(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.62.0(react@18.3.1))(react@18.3.1) '@reduxjs/toolkit': 1.9.7(react-redux@7.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) allof-merge: 0.6.6 buffer: 6.0.3 clsx: 1.2.1 copy-text-to-clipboard: 3.2.0 crypto-js: 4.2.0 - docusaurus-plugin-openapi-docs: 4.4.0(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@docusaurus/utils-validation@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@docusaurus/utils@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(encoding@0.1.13)(react@18.3.1) - docusaurus-plugin-sass: 0.2.6(@docusaurus/core@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(@swc/core@1.13.2(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@rspack/core@1.4.10(@swc/helpers@0.5.17))(sass@1.89.2)(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + docusaurus-plugin-openapi-docs: 4.4.0(@docusaurus/plugin-content-docs@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@docusaurus/utils-validation@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@docusaurus/utils@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(encoding@0.1.13)(react@18.3.1) + docusaurus-plugin-sass: 0.2.6(@docusaurus/core@3.8.1(@docusaurus/faster@3.8.1(@docusaurus/types@3.8.1(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/helpers@0.5.17))(@mdx-js/react@3.1.0(@types/react@19.1.2)(react@18.3.1))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(sass@1.89.2)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) file-saver: 2.0.5 lodash: 4.17.21 pako: 2.1.0 @@ -23761,7 +23690,7 @@ snapshots: process: 0.11.10 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-hook-form: 7.61.1(react@18.3.1) + react-hook-form: 7.62.0(react@18.3.1) react-live: 4.1.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-magic-dropzone: 1.0.1 react-markdown: 8.0.7(@types/react@19.1.2)(react@18.3.1) @@ -23770,7 +23699,7 @@ snapshots: rehype-raw: 6.1.1 remark-gfm: 3.0.1 sass: 1.89.2 - sass-loader: 16.0.5(@rspack/core@1.4.10(@swc/helpers@0.5.17))(sass@1.89.2)(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + sass-loader: 16.0.5(@rspack/core@1.4.11(@swc/helpers@0.5.17))(sass@1.89.2)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) unist-util-visit: 5.0.0 url: 0.11.4 xml-formatter: 2.6.1 @@ -23891,7 +23820,7 @@ snapshots: dependencies: jake: 10.9.2 - electron-to-chromium@1.5.190: {} + electron-to-chromium@1.5.194: {} emoji-regex@10.4.0: {} @@ -23925,7 +23854,7 @@ snapshots: engine.io@6.6.4: dependencies: '@types/cors': 2.8.19 - '@types/node': 22.16.5 + '@types/node': 22.17.0 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.7.2 @@ -24102,7 +24031,7 @@ snapshots: '@types/estree-jsx': 1.0.5 acorn: 8.15.0 esast-util-from-estree: 2.0.0 - vfile-message: 4.0.2 + vfile-message: 4.0.3 esbuild-wasm@0.18.17: {} @@ -24206,21 +24135,21 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-config-next@15.4.0-canary.86(eslint@8.57.1)(typescript@5.8.3): + eslint-config-next@15.4.0-canary.86(eslint@8.57.1)(typescript@5.9.2): dependencies: '@next/eslint-plugin-next': 15.4.0-canary.86 '@rushstack/eslint-patch': 1.12.0 - '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/parser': 8.38.0(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/parser': 8.38.0(eslint@8.57.1)(typescript@5.9.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) eslint-plugin-react: 7.37.5(eslint@8.57.1) eslint-plugin-react-hooks: 5.2.0(eslint@8.57.1) optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.2 transitivePeerDependencies: - eslint-import-resolver-webpack - eslint-plugin-import-x @@ -24249,22 +24178,22 @@ snapshots: tinyglobby: 0.2.14 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): dependencies: debug: 3.2.7(supports-color@8.1.1) optionalDependencies: - '@typescript-eslint/parser': 8.38.0(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/parser': 8.38.0(eslint@8.57.1)(typescript@5.9.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -24275,7 +24204,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -24287,7 +24216,7 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.38.0(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/parser': 8.38.0(eslint@8.57.1)(typescript@5.9.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -24488,7 +24417,7 @@ snapshots: eval@0.1.8: dependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 require-like: 0.1.2 event-stream@3.3.4: @@ -24716,11 +24645,11 @@ snapshots: dependencies: flat-cache: 3.2.0 - file-loader@6.2.0(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): + file-loader@6.2.0(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) file-saver@2.0.5: {} @@ -24784,7 +24713,7 @@ snapshots: dependencies: magic-string: 0.30.17 mlly: 1.7.4 - rollup: 4.45.1 + rollup: 4.46.2 flag-icons@7.5.0: {} @@ -24798,7 +24727,7 @@ snapshots: flatted@3.3.3: {} - follow-redirects@1.15.9(debug@4.4.1): + follow-redirects@1.15.11(debug@4.4.1): optionalDependencies: debug: 4.4.1(supports-color@5.5.0) @@ -25226,7 +25155,7 @@ snapshots: hast-util-from-parse5: 8.0.3 parse5: 7.3.0 vfile: 6.0.3 - vfile-message: 4.0.2 + vfile-message: 4.0.3 hast-util-from-parse5@7.1.2: dependencies: @@ -25405,7 +25334,7 @@ snapshots: space-separated-tokens: 2.0.2 style-to-js: 1.1.17 unist-util-position: 5.0.0 - vfile-message: 4.0.2 + vfile-message: 4.0.3 transitivePeerDependencies: - supports-color @@ -25556,7 +25485,7 @@ snapshots: html-void-elements@3.0.0: {} - html-webpack-plugin@5.6.3(@rspack/core@1.4.10(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): + html-webpack-plugin@5.6.3(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -25564,10 +25493,10 @@ snapshots: pretty-error: 4.0.0 tapable: 2.2.2 optionalDependencies: - '@rspack/core': 1.4.10(@swc/helpers@0.5.17) - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + '@rspack/core': 1.4.11(@swc/helpers@0.5.17) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) - html-webpack-plugin@5.6.3(@rspack/core@1.4.10(@swc/helpers@0.5.17))(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)): + html-webpack-plugin@5.6.3(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -25575,8 +25504,8 @@ snapshots: pretty-error: 4.0.0 tapable: 2.2.2 optionalDependencies: - '@rspack/core': 1.4.10(@swc/helpers@0.5.17) - webpack: 5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17) + '@rspack/core': 1.4.11(@swc/helpers@0.5.17) + webpack: 5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17) optional: true htmlparser2@6.1.0: @@ -25652,7 +25581,7 @@ snapshots: http-proxy@1.18.1: dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.9(debug@4.4.1) + follow-redirects: 1.15.11(debug@4.4.1) requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -26123,7 +26052,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 22.16.5 + '@types/node': 22.17.0 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -26131,20 +26060,20 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 merge-stream: 2.0.0 supports-color: 8.1.1 jest-worker@29.7.0: dependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 jiti@1.21.7: {} - jiti@2.5.0: {} + jiti@2.5.1: {} joi@17.13.3: dependencies: @@ -26191,7 +26120,7 @@ snapshots: http-proxy-agent: 4.0.1 https-proxy-agent: 5.0.1 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.20 + nwsapi: 2.2.21 parse5: 6.0.1 saxes: 5.0.1 symbol-tree: 3.2.4 @@ -26218,7 +26147,7 @@ snapshots: http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.20 + nwsapi: 2.2.21 parse5: 7.3.0 rrweb-cssom: 0.8.0 saxes: 6.0.0 @@ -26422,13 +26351,13 @@ snapshots: klona@2.0.6: {} - knip@5.62.0(@types/node@24.1.0)(typescript@5.8.3): + knip@5.62.0(@types/node@24.1.0)(typescript@5.9.2): dependencies: '@nodelib/fs.walk': 1.2.8 '@types/node': 24.1.0 fast-glob: 3.3.3 formatly: 0.2.4 - jiti: 2.5.0 + jiti: 2.5.1 js-yaml: 4.1.0 minimist: 1.2.8 oxc-resolver: 11.6.0 @@ -26436,7 +26365,7 @@ snapshots: picomatch: 4.0.3 smol-toml: 1.4.1 strip-json-comments: 5.0.2 - typescript: 5.8.3 + typescript: 5.9.2 zod: 3.25.76 zod-validation-error: 3.5.3(zod@3.25.76) @@ -26460,7 +26389,7 @@ snapshots: dependencies: package-json: 8.1.1 - launch-editor@2.10.0: + launch-editor@2.11.0: dependencies: picocolors: 1.1.1 shell-quote: 1.8.3 @@ -26471,11 +26400,11 @@ snapshots: lazy-ass@1.6.0: {} - less-loader@11.1.0(less@4.1.3)(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)): + less-loader@11.1.0(less@4.1.3)(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)): dependencies: klona: 2.0.6 less: 4.1.3 - webpack: 5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17) + webpack: 5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17) less@4.1.3: dependencies: @@ -26500,11 +26429,11 @@ snapshots: libphonenumber-js@1.12.10: {} - license-webpack-plugin@4.0.2(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)): + license-webpack-plugin@4.0.2(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)): dependencies: webpack-sources: 3.3.3 optionalDependencies: - webpack: 5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17) + webpack: 5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17) lightningcss-darwin-arm64@1.30.1: optional: true @@ -27061,7 +26990,7 @@ snapshots: parse-entities: 4.0.2 stringify-entities: 4.0.4 unist-util-stringify-position: 4.0.0 - vfile-message: 4.0.2 + vfile-message: 4.0.3 transitivePeerDependencies: - supports-color @@ -27176,7 +27105,7 @@ snapshots: mdn-data@2.0.30: {} - mdx-mermaid@2.0.3(mermaid@11.9.0)(react@18.3.1)(typescript@5.8.3)(unist-util-visit@5.0.0): + mdx-mermaid@2.0.3(mermaid@11.9.0)(react@18.3.1)(typescript@5.9.2)(unist-util-visit@5.0.0): dependencies: mermaid: 11.9.0 react: 18.3.1 @@ -27189,7 +27118,7 @@ snapshots: mdast-util-from-markdown: 1.3.1 mdast-util-mdx: 2.0.1 micromark-extension-mdxjs: 1.0.1 - puppeteer: 22.15.0(typescript@5.8.3) + puppeteer: 22.15.0(typescript@5.9.2) transitivePeerDependencies: - bare-buffer - bufferutil @@ -27225,9 +27154,9 @@ snapshots: '@iconify/utils': 2.3.0 '@mermaid-js/parser': 0.6.2 '@types/d3': 7.4.3 - cytoscape: 3.32.1 - cytoscape-cose-bilkent: 4.1.0(cytoscape@3.32.1) - cytoscape-fcose: 2.2.0(cytoscape@3.32.1) + cytoscape: 3.33.0 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.33.0) + cytoscape-fcose: 2.2.0(cytoscape@3.33.0) d3: 7.9.0 d3-sankey: 0.12.3 dagre-d3-es: 7.0.11 @@ -27465,7 +27394,7 @@ snapshots: micromark-util-events-to-acorn: 2.0.3 micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 - vfile-message: 4.0.2 + vfile-message: 4.0.3 micromark-extension-mdx-md@1.0.1: dependencies: @@ -27499,7 +27428,7 @@ snapshots: micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 unist-util-position-from-estree: 2.0.0 - vfile-message: 4.0.2 + vfile-message: 4.0.3 micromark-extension-mdxjs@1.0.1: dependencies: @@ -27572,7 +27501,7 @@ snapshots: micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 unist-util-position-from-estree: 2.0.0 - vfile-message: 4.0.2 + vfile-message: 4.0.3 micromark-factory-space@1.1.0: dependencies: @@ -27698,7 +27627,7 @@ snapshots: estree-util-visit: 2.0.0 micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 - vfile-message: 4.0.2 + vfile-message: 4.0.3 micromark-util-html-tag-name@1.2.0: {} @@ -27837,16 +27766,16 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.7.6(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)): + mini-css-extract-plugin@2.7.6(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)): dependencies: schema-utils: 4.3.2 - webpack: 5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17) + webpack: 5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17) - mini-css-extract-plugin@2.9.2(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): + mini-css-extract-plugin@2.9.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: schema-utils: 4.3.2 tapable: 2.2.2 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) mini-svg-data-uri@1.4.4: {} @@ -28046,25 +27975,25 @@ snapshots: netmask@2.0.2: optional: true - next-intl@3.26.5(next@15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2))(react@19.1.0): + next-intl@3.26.5(next@15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2))(react@19.1.0): dependencies: '@formatjs/intl-localematcher': 0.5.10 negotiator: 1.0.0 - next: 15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2) + next: 15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2) react: 19.1.0 use-intl: 3.26.5(react@19.1.0) - next-themes@0.2.1(next@15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2))(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + next-themes@0.2.1(next@15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2))(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: - next: 15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2) + next: 15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) - next@15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2): + next@15.4.0-canary.86(@babel/core@7.28.0)(@playwright/test@1.54.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.2): dependencies: '@next/env': 15.4.0-canary.86 '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001727 + caniuse-lite: 1.0.30001731 postcss: 8.4.31 react: 19.1.0 react-dom: 19.1.0(react@19.1.0) @@ -28078,7 +28007,7 @@ snapshots: '@next/swc-linux-x64-musl': 15.4.0-canary.86 '@next/swc-win32-arm64-msvc': 15.4.0-canary.86 '@next/swc-win32-x64-msvc': 15.4.0-canary.86 - '@playwright/test': 1.54.1 + '@playwright/test': 1.54.2 sass: 1.89.2 sharp: 0.34.3 transitivePeerDependencies: @@ -28280,17 +28209,17 @@ snapshots: dependencies: boolbase: 1.0.0 - null-loader@4.0.1(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): + null-loader@4.0.1(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) - nwsapi@2.2.20: {} + nwsapi@2.2.21: {} - nx@16.5.1(@swc/core@1.13.2(@swc/helpers@0.5.17)): + nx@16.5.1(@swc/core@1.13.3(@swc/helpers@0.5.17)): dependencies: - '@nrwl/tao': 16.5.1(@swc/core@1.13.2(@swc/helpers@0.5.17)) + '@nrwl/tao': 16.5.1(@swc/core@1.13.3(@swc/helpers@0.5.17)) '@parcel/watcher': 2.0.4 '@yarnpkg/lockfile': 1.1.0 '@yarnpkg/parsers': 3.0.0-rc.46 @@ -28335,7 +28264,7 @@ snapshots: '@nx/nx-linux-x64-musl': 16.5.1 '@nx/nx-win32-arm64-msvc': 16.5.1 '@nx/nx-win32-x64-msvc': 16.5.1 - '@swc/core': 1.13.2(@swc/helpers@0.5.17) + '@swc/core': 1.13.3(@swc/helpers@0.5.17) transitivePeerDependencies: - debug @@ -28461,8 +28390,8 @@ snapshots: openai@4.78.1(encoding@0.1.13)(zod@3.25.76): dependencies: - '@types/node': 18.19.120 - '@types/node-fetch': 2.6.12 + '@types/node': 18.19.121 + '@types/node-fetch': 2.6.13 abort-controller: 3.0.0 agentkeepalive: 4.6.0 form-data-encoder: 1.7.2 @@ -28876,11 +28805,11 @@ snapshots: exsolve: 1.0.7 pathe: 2.0.3 - playwright-core@1.54.1: {} + playwright-core@1.54.2: {} - playwright@1.54.1: + playwright@1.54.2: dependencies: - playwright-core: 1.54.1 + playwright-core: 1.54.2 optionalDependencies: fsevents: 2.3.2 @@ -29094,31 +29023,31 @@ snapshots: optionalDependencies: postcss: 8.5.3 - postcss-load-config@6.0.1(jiti@2.5.0)(postcss@8.5.6)(yaml@2.8.0): + postcss-load-config@6.0.1(jiti@2.5.1)(postcss@8.5.6)(yaml@2.8.0): dependencies: lilconfig: 3.1.3 optionalDependencies: - jiti: 2.5.0 + jiti: 2.5.1 postcss: 8.5.6 yaml: 2.8.0 - postcss-loader@7.3.3(postcss@8.4.31)(typescript@5.1.6)(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)): + postcss-loader@7.3.3(postcss@8.4.31)(typescript@5.1.6)(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)): dependencies: cosmiconfig: 8.3.6(typescript@5.1.6) jiti: 1.21.7 postcss: 8.4.31 semver: 7.5.4 - webpack: 5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17) + webpack: 5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17) transitivePeerDependencies: - typescript - postcss-loader@7.3.4(postcss@8.5.6)(typescript@5.8.3)(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): + postcss-loader@7.3.4(postcss@8.5.6)(typescript@5.9.2)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: - cosmiconfig: 8.3.6(typescript@5.8.3) + cosmiconfig: 8.3.6(typescript@5.9.2) jiti: 1.21.7 postcss: 8.5.6 semver: 7.7.2 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) transitivePeerDependencies: - typescript @@ -29542,11 +29471,11 @@ snapshots: dependencies: xtend: 4.0.2 - posthog-js@1.257.2: + posthog-js@1.258.5: dependencies: core-js: 3.44.0 fflate: 0.4.8 - preact: 10.26.9 + preact: 10.27.0 web-vitals: 4.2.4 postman-code-generators@1.14.2: @@ -29576,25 +29505,25 @@ snapshots: dependencies: punycode: 2.3.1 - preact@10.26.9: {} + preact@10.27.0: {} prelude-ls@1.2.1: {} - prettier-plugin-organize-imports@3.2.4(prettier@3.6.2)(typescript@5.8.3): + prettier-plugin-organize-imports@3.2.4(prettier@3.6.2)(typescript@5.9.2): dependencies: prettier: 3.6.2 - typescript: 5.8.3 + typescript: 5.9.2 prettier-plugin-organize-imports@4.2.0(prettier@3.6.2)(typescript@5.1.6): dependencies: prettier: 3.6.2 typescript: 5.1.6 - prettier-plugin-tailwindcss@0.6.11(prettier-plugin-organize-imports@3.2.4(prettier@3.6.2)(typescript@5.8.3))(prettier@3.6.2): + prettier-plugin-tailwindcss@0.6.11(prettier-plugin-organize-imports@3.2.4(prettier@3.6.2)(typescript@5.9.2))(prettier@3.6.2): dependencies: prettier: 3.6.2 optionalDependencies: - prettier-plugin-organize-imports: 3.2.4(prettier@3.6.2)(typescript@5.8.3) + prettier-plugin-organize-imports: 3.2.4(prettier@3.6.2)(typescript@5.9.2) prettier@2.8.8: {} @@ -29668,7 +29597,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 22.16.5 + '@types/node': 22.17.0 long: 5.3.2 proxy-addr@2.0.7: @@ -29736,10 +29665,10 @@ snapshots: - utf-8-validate optional: true - puppeteer@22.15.0(typescript@5.8.3): + puppeteer@22.15.0(typescript@5.9.2): dependencies: '@puppeteer/browsers': 2.3.0 - cosmiconfig: 9.0.0(typescript@5.8.3) + cosmiconfig: 9.0.0(typescript@5.9.2) devtools-protocol: 0.0.1312386 puppeteer-core: 22.15.0 transitivePeerDependencies: @@ -29794,11 +29723,11 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 - raw-loader@4.0.2(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): + raw-loader@4.0.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) rc@1.2.8: dependencies: @@ -29844,7 +29773,7 @@ snapshots: dependencies: react: 18.3.1 - react-hook-form@7.61.1(react@18.3.1): + react-hook-form@7.62.0(react@18.3.1): dependencies: react: 18.3.1 @@ -29868,11 +29797,11 @@ snapshots: sucrase: 3.35.0 use-editable: 2.3.3(react@18.3.1) - react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): + react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: '@babel/runtime': 7.28.2 react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) react-magic-dropzone@1.0.1: {} @@ -30096,15 +30025,14 @@ snapshots: estree-util-build-jsx: 3.0.1 vfile: 6.0.3 - recma-jsx@1.0.0(acorn@8.15.0): + recma-jsx@1.0.1(acorn@8.15.0): dependencies: + acorn: 8.15.0 acorn-jsx: 5.3.2(acorn@8.15.0) estree-util-to-js: 2.0.0 recma-parse: 1.0.0 recma-stringify: 1.0.0 unified: 11.0.5 - transitivePeerDependencies: - - acorn recma-parse@1.0.0: dependencies: @@ -30424,30 +30352,30 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - rollup@4.45.1: + rollup@4.46.2: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.45.1 - '@rollup/rollup-android-arm64': 4.45.1 - '@rollup/rollup-darwin-arm64': 4.45.1 - '@rollup/rollup-darwin-x64': 4.45.1 - '@rollup/rollup-freebsd-arm64': 4.45.1 - '@rollup/rollup-freebsd-x64': 4.45.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.45.1 - '@rollup/rollup-linux-arm-musleabihf': 4.45.1 - '@rollup/rollup-linux-arm64-gnu': 4.45.1 - '@rollup/rollup-linux-arm64-musl': 4.45.1 - '@rollup/rollup-linux-loongarch64-gnu': 4.45.1 - '@rollup/rollup-linux-powerpc64le-gnu': 4.45.1 - '@rollup/rollup-linux-riscv64-gnu': 4.45.1 - '@rollup/rollup-linux-riscv64-musl': 4.45.1 - '@rollup/rollup-linux-s390x-gnu': 4.45.1 - '@rollup/rollup-linux-x64-gnu': 4.45.1 - '@rollup/rollup-linux-x64-musl': 4.45.1 - '@rollup/rollup-win32-arm64-msvc': 4.45.1 - '@rollup/rollup-win32-ia32-msvc': 4.45.1 - '@rollup/rollup-win32-x64-msvc': 4.45.1 + '@rollup/rollup-android-arm-eabi': 4.46.2 + '@rollup/rollup-android-arm64': 4.46.2 + '@rollup/rollup-darwin-arm64': 4.46.2 + '@rollup/rollup-darwin-x64': 4.46.2 + '@rollup/rollup-freebsd-arm64': 4.46.2 + '@rollup/rollup-freebsd-x64': 4.46.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.46.2 + '@rollup/rollup-linux-arm-musleabihf': 4.46.2 + '@rollup/rollup-linux-arm64-gnu': 4.46.2 + '@rollup/rollup-linux-arm64-musl': 4.46.2 + '@rollup/rollup-linux-loongarch64-gnu': 4.46.2 + '@rollup/rollup-linux-ppc64-gnu': 4.46.2 + '@rollup/rollup-linux-riscv64-gnu': 4.46.2 + '@rollup/rollup-linux-riscv64-musl': 4.46.2 + '@rollup/rollup-linux-s390x-gnu': 4.46.2 + '@rollup/rollup-linux-x64-gnu': 4.46.2 + '@rollup/rollup-linux-x64-musl': 4.46.2 + '@rollup/rollup-win32-arm64-msvc': 4.46.2 + '@rollup/rollup-win32-ia32-msvc': 4.46.2 + '@rollup/rollup-win32-x64-msvc': 4.46.2 fsevents: 2.3.3 roughjs@4.6.6: @@ -30513,20 +30441,20 @@ snapshots: safevalues@0.3.4: {} - sass-loader@13.3.2(sass@1.64.1)(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)): + sass-loader@13.3.2(sass@1.64.1)(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)): dependencies: neo-async: 2.6.2 - webpack: 5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17) + webpack: 5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17) optionalDependencies: sass: 1.64.1 - sass-loader@16.0.5(@rspack/core@1.4.10(@swc/helpers@0.5.17))(sass@1.89.2)(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): + sass-loader@16.0.5(@rspack/core@1.4.11(@swc/helpers@0.5.17))(sass@1.89.2)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: neo-async: 2.6.2 optionalDependencies: - '@rspack/core': 1.4.10(@swc/helpers@0.5.17) + '@rspack/core': 1.4.11(@swc/helpers@0.5.17) sass: 1.89.2 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) sass@1.64.1: dependencies: @@ -30935,12 +30863,12 @@ snapshots: source-map-js@1.2.1: {} - source-map-loader@4.0.1(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)): + source-map-loader@4.0.1(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)): dependencies: abab: 2.0.6 iconv-lite: 0.6.3 source-map-js: 1.2.1 - webpack: 5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17) + webpack: 5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17) source-map-support@0.5.21: dependencies: @@ -31287,11 +31215,11 @@ snapshots: transitivePeerDependencies: - encoding - swc-loader@0.2.6(@swc/core@1.13.2(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): + swc-loader@0.2.6(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: - '@swc/core': 1.13.2(@swc/helpers@0.5.17) + '@swc/core': 1.13.3(@swc/helpers@0.5.17) '@swc/counter': 0.1.3 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) symbol-observable@4.0.0: {} @@ -31373,28 +31301,28 @@ snapshots: term-size@2.2.1: {} - terser-webpack-plugin@5.3.14(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)): + terser-webpack-plugin@5.3.14(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)): dependencies: '@jridgewell/trace-mapping': 0.3.29 jest-worker: 27.5.1 schema-utils: 4.3.2 serialize-javascript: 6.0.2 terser: 5.43.1 - webpack: 5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17) + webpack: 5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17) optionalDependencies: - '@swc/core': 1.13.2(@swc/helpers@0.5.17) + '@swc/core': 1.13.3(@swc/helpers@0.5.17) esbuild: 0.18.17 - terser-webpack-plugin@5.3.14(@swc/core@1.13.2(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): + terser-webpack-plugin@5.3.14(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: '@jridgewell/trace-mapping': 0.3.29 jest-worker: 27.5.1 schema-utils: 4.3.2 serialize-javascript: 6.0.2 terser: 5.43.1 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) optionalDependencies: - '@swc/core': 1.13.2(@swc/helpers@0.5.17) + '@swc/core': 1.13.3(@swc/helpers@0.5.17) terser@5.19.2: dependencies: @@ -31531,17 +31459,17 @@ snapshots: dependencies: typescript: 5.1.6 - ts-api-utils@1.4.3(typescript@5.8.3): + ts-api-utils@1.4.3(typescript@5.9.2): dependencies: - typescript: 5.8.3 + typescript: 5.9.2 ts-api-utils@2.1.0(typescript@5.1.6): dependencies: typescript: 5.1.6 - ts-api-utils@2.1.0(typescript@5.8.3): + ts-api-utils@2.1.0(typescript@5.9.2): dependencies: - typescript: 5.8.3 + typescript: 5.9.2 ts-dedent@2.2.0: {} @@ -31564,9 +31492,9 @@ snapshots: ts-poet: 6.12.0 ts-proto-descriptors: 2.0.0 - tsconfck@3.1.6(typescript@5.8.3): + tsconfck@3.1.6(typescript@5.9.2): optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.2 tsconfig-paths@3.15.0: dependencies: @@ -31587,7 +31515,7 @@ snapshots: tslib@2.8.1: {} - tsup@8.5.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(jiti@2.5.0)(postcss@8.5.6)(typescript@5.8.3)(yaml@2.8.0): + tsup@8.5.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(jiti@2.5.1)(postcss@8.5.6)(typescript@5.9.2)(yaml@2.8.0): dependencies: bundle-require: 5.1.0(esbuild@0.25.8) cac: 6.7.14 @@ -31598,18 +31526,18 @@ snapshots: fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(jiti@2.5.0)(postcss@8.5.6)(yaml@2.8.0) + postcss-load-config: 6.0.1(jiti@2.5.1)(postcss@8.5.6)(yaml@2.8.0) resolve-from: 5.0.0 - rollup: 4.45.1 + rollup: 4.46.2 source-map: 0.8.0-beta.0 sucrase: 3.35.0 tinyexec: 0.3.2 tinyglobby: 0.2.14 tree-kill: 1.2.2 optionalDependencies: - '@swc/core': 1.13.2(@swc/helpers@0.5.17) + '@swc/core': 1.13.3(@swc/helpers@0.5.17) postcss: 8.5.6 - typescript: 5.8.3 + typescript: 5.9.2 transitivePeerDependencies: - jiti - supports-color @@ -31722,7 +31650,7 @@ snapshots: typescript@5.1.6: {} - typescript@5.8.3: {} + typescript@5.9.2: {} ua-parser-js@0.7.40: {} @@ -31933,14 +31861,14 @@ snapshots: dependencies: punycode: 2.3.1 - url-loader@4.1.1(file-loader@6.2.0(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))))(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): + url-loader@4.1.1(file-loader@6.2.0(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: loader-utils: 2.0.4 mime-types: 2.1.35 schema-utils: 3.3.0 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) optionalDependencies: - file-loader: 6.2.0(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + file-loader: 6.2.0(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) url-parse@1.5.10: dependencies: @@ -32088,7 +32016,7 @@ snapshots: '@types/unist': 2.0.11 unist-util-stringify-position: 3.0.3 - vfile-message@4.0.2: + vfile-message@4.0.3: dependencies: '@types/unist': 3.0.3 unist-util-stringify-position: 4.0.0 @@ -32103,15 +32031,15 @@ snapshots: vfile@6.0.3: dependencies: '@types/unist': 3.0.3 - vfile-message: 4.0.2 + vfile-message: 4.0.3 - vite-node@2.1.9(@types/node@22.16.5)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1): + vite-node@2.1.9(@types/node@22.17.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1): dependencies: cac: 6.7.14 debug: 4.4.1(supports-color@5.5.0) es-module-lexer: 1.7.0 pathe: 1.1.2 - vite: 5.4.19(@types/node@22.16.5)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1) + vite: 5.4.19(@types/node@22.17.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1) transitivePeerDependencies: - '@types/node' - less @@ -32141,37 +32069,37 @@ snapshots: - supports-color - terser - vite-tsconfig-paths@5.1.4(typescript@5.8.3)(vite@5.4.19(@types/node@22.16.5)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)): + vite-tsconfig-paths@5.1.4(typescript@5.9.2)(vite@5.4.19(@types/node@22.17.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)): dependencies: debug: 4.4.1(supports-color@5.5.0) globrex: 0.1.2 - tsconfck: 3.1.6(typescript@5.8.3) + tsconfck: 3.1.6(typescript@5.9.2) optionalDependencies: - vite: 5.4.19(@types/node@22.16.5)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1) + vite: 5.4.19(@types/node@22.17.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1) transitivePeerDependencies: - supports-color - typescript - vite@4.5.5(@types/node@22.16.5)(less@4.1.3)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.19.2): + vite@4.5.5(@types/node@22.17.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.19.2): dependencies: esbuild: 0.18.17 postcss: 8.5.3 rollup: 3.29.5 optionalDependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 fsevents: 2.3.3 less: 4.1.3 lightningcss: 1.30.1 sass: 1.64.1 terser: 5.19.2 - vite@5.4.19(@types/node@22.16.5)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1): + vite@5.4.19(@types/node@22.17.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1): dependencies: esbuild: 0.21.5 postcss: 8.5.3 - rollup: 4.45.1 + rollup: 4.46.2 optionalDependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 fsevents: 2.3.3 less: 4.1.3 lightningcss: 1.30.1 @@ -32182,7 +32110,7 @@ snapshots: dependencies: esbuild: 0.21.5 postcss: 8.5.3 - rollup: 4.45.1 + rollup: 4.46.2 optionalDependencies: '@types/node': 24.1.0 fsevents: 2.3.3 @@ -32191,10 +32119,10 @@ snapshots: sass: 1.89.2 terser: 5.43.1 - vitest@2.1.9(@types/node@22.16.5)(jsdom@26.1.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1): + vitest@2.1.9(@types/node@22.17.0)(jsdom@26.1.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1): dependencies: '@vitest/expect': 2.1.9 - '@vitest/mocker': 2.1.9(vite@5.4.19(@types/node@22.16.5)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)) + '@vitest/mocker': 2.1.9(vite@5.4.19(@types/node@22.17.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)) '@vitest/pretty-format': 2.1.9 '@vitest/runner': 2.1.9 '@vitest/snapshot': 2.1.9 @@ -32210,11 +32138,11 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.1.1 tinyrainbow: 1.2.0 - vite: 5.4.19(@types/node@22.16.5)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1) - vite-node: 2.1.9(@types/node@22.16.5)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1) + vite: 5.4.19(@types/node@22.17.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1) + vite-node: 2.1.9(@types/node@22.17.0)(less@4.1.3)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.16.5 + '@types/node': 22.17.0 jsdom: 26.1.0 transitivePeerDependencies: - less @@ -32369,25 +32297,25 @@ snapshots: - bufferutil - utf-8-validate - webpack-dev-middleware@5.3.4(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): + webpack-dev-middleware@5.3.4(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: colorette: 2.0.20 memfs: 3.5.3 mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.3.2 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) - webpack-dev-middleware@5.3.4(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)): + webpack-dev-middleware@5.3.4(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)): dependencies: colorette: 2.0.20 memfs: 3.5.3 mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.3.2 - webpack: 5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17) + webpack: 5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17) - webpack-dev-middleware@6.1.2(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)): + webpack-dev-middleware@6.1.2(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)): dependencies: colorette: 2.0.20 memfs: 3.5.3 @@ -32395,9 +32323,9 @@ snapshots: range-parser: 1.2.1 schema-utils: 4.3.2 optionalDependencies: - webpack: 5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17) + webpack: 5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17) - webpack-dev-server@4.15.1(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)): + webpack-dev-server@4.15.1(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -32418,7 +32346,7 @@ snapshots: html-entities: 2.6.0 http-proxy-middleware: 2.0.9(@types/express@4.17.23) ipaddr.js: 2.2.0 - launch-editor: 2.10.0 + launch-editor: 2.11.0 open: 8.4.2 p-retry: 4.6.2 rimraf: 3.0.2 @@ -32427,17 +32355,17 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 5.3.4(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)) + webpack-dev-middleware: 5.3.4(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)) ws: 8.18.3 optionalDependencies: - webpack: 5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17) + webpack: 5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17) transitivePeerDependencies: - bufferutil - debug - supports-color - utf-8-validate - webpack-dev-server@4.15.2(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): + webpack-dev-server@4.15.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -32458,7 +32386,7 @@ snapshots: html-entities: 2.6.0 http-proxy-middleware: 2.0.9(@types/express@4.17.23) ipaddr.js: 2.2.0 - launch-editor: 2.10.0 + launch-editor: 2.11.0 open: 8.4.2 p-retry: 4.6.2 rimraf: 3.0.2 @@ -32467,10 +32395,10 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 5.3.4(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + webpack-dev-middleware: 5.3.4(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) ws: 8.18.3 optionalDependencies: - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) transitivePeerDependencies: - bufferutil - debug @@ -32496,14 +32424,14 @@ snapshots: webpack-sources@3.3.3: {} - webpack-subresource-integrity@5.1.0(html-webpack-plugin@5.6.3(@rspack/core@1.4.10(@swc/helpers@0.5.17))(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)))(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)): + webpack-subresource-integrity@5.1.0(html-webpack-plugin@5.6.3(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)))(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)): dependencies: typed-assert: 1.0.9 - webpack: 5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17) + webpack: 5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17) optionalDependencies: - html-webpack-plugin: 5.6.3(@rspack/core@1.4.10(@swc/helpers@0.5.17))(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)) + html-webpack-plugin: 5.6.3(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)) - webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)): + webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -32527,7 +32455,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.2 tapable: 2.2.2 - terser-webpack-plugin: 5.3.14(@swc/core@1.13.2(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))) + terser-webpack-plugin: 5.3.14(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))) watchpack: 2.4.4 webpack-sources: 3.3.3 transitivePeerDependencies: @@ -32535,7 +32463,7 @@ snapshots: - esbuild - uglify-js - webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17): + webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17): dependencies: '@types/estree': 1.0.8 '@webassemblyjs/ast': 1.14.1 @@ -32557,7 +32485,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.2 - terser-webpack-plugin: 5.3.14(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)(webpack@5.94.0(@swc/core@1.13.2(@swc/helpers@0.5.17))(esbuild@0.18.17)) + terser-webpack-plugin: 5.3.14(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)(webpack@5.94.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.18.17)) watchpack: 2.4.4 webpack-sources: 3.3.3 transitivePeerDependencies: @@ -32565,7 +32493,7 @@ snapshots: - esbuild - uglify-js - webpackbar@6.0.1(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): + webpackbar@6.0.1(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: ansi-escapes: 4.3.2 chalk: 4.1.2 @@ -32574,7 +32502,7 @@ snapshots: markdown-table: 2.0.0 pretty-time: 1.1.0 std-env: 3.9.0 - webpack: 5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17)) + webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)) wrap-ansi: 7.0.0 websocket-driver@0.7.4: diff --git a/proto/zitadel/action/v2/action_service.proto b/proto/zitadel/action/v2/action_service.proto new file mode 100644 index 0000000000..d9e57a83a5 --- /dev/null +++ b/proto/zitadel/action/v2/action_service.proto @@ -0,0 +1,728 @@ +syntax = "proto3"; + +package zitadel.action.v2; + +import "google/api/annotations.proto"; +import "google/api/field_behavior.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/struct.proto"; +import "protoc-gen-openapiv2/options/annotations.proto"; +import "validate/validate.proto"; + +import "zitadel/protoc_gen_zitadel/v2/options.proto"; + +import "zitadel/action/v2/target.proto"; +import "zitadel/action/v2/execution.proto"; +import "zitadel/action/v2/query.proto"; +import "google/protobuf/timestamp.proto"; +import "zitadel/filter/v2/filter.proto"; + +option go_package = "github.com/zitadel/zitadel/pkg/grpc/action/v2;action"; + +option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { + info: { + title: "Action Service"; + version: "2.0"; + description: "This API is intended to manage custom executions (previously known as actions) in a ZITADEL instance."; + contact:{ + name: "ZITADEL" + url: "https://zitadel.com" + email: "hi@zitadel.com" + } + license: { + name: "Apache 2.0", + url: "https://github.com/zitadel/zitadel/blob/main/LICENSING.md"; + }; + }; + schemes: HTTPS; + schemes: HTTP; + + consumes: "application/json"; + consumes: "application/grpc"; + + produces: "application/json"; + produces: "application/grpc"; + + consumes: "application/grpc-web+proto"; + produces: "application/grpc-web+proto"; + + host: "$CUSTOM-DOMAIN"; + base_path: "/"; + + external_docs: { + description: "Detailed information about ZITADEL", + url: "https://zitadel.com/docs" + } + security_definitions: { + security: { + key: "OAuth2"; + value: { + type: TYPE_OAUTH2; + flow: FLOW_ACCESS_CODE; + authorization_url: "$CUSTOM-DOMAIN/oauth/v2/authorize"; + token_url: "$CUSTOM-DOMAIN/oauth/v2/token"; + scopes: { + scope: { + key: "openid"; + value: "openid"; + } + scope: { + key: "urn:zitadel:iam:org:project:id:zitadel:aud"; + value: "urn:zitadel:iam:org:project:id:zitadel:aud"; + } + } + } + } + } + security: { + security_requirement: { + key: "OAuth2"; + value: { + scope: "openid"; + scope: "urn:zitadel:iam:org:project:id:zitadel:aud"; + } + } + } + responses: { + key: "403"; + value: { + description: "Returned when the user does not have permission to access the resource."; + schema: { + json_schema: { + ref: "#/definitions/rpcStatus"; + } + } + } + } + responses: { + key: "404"; + value: { + description: "Returned when the resource does not exist."; + schema: { + json_schema: { + ref: "#/definitions/rpcStatus"; + } + } + } + } +}; + +// Service to manage custom executions. +// The service provides methods to create, update, delete and list targets and executions. +service ActionService { + + // Create Target + // + // Create a new target to your endpoint, which can be used in executions. + // + // Required permission: + // - `action.target.write` + // + // Required feature flag: + // - `actions` + rpc CreateTarget (CreateTargetRequest) returns (CreateTargetResponse) { + option (google.api.http) = { + post: "/v2/actions/targets" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "action.target.write" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "Target created successfully"; + }; + }; + responses: { + key: "409" + value: { + description: "The target to create already exists."; + } + }; + responses: { + key: "400" + value: { + description: "The feature flag `actions` is not enabled."; + } + }; + }; + } + + // Update Target + // + // Update an existing target. + // To generate a new signing key set the optional expirationSigningKey. + // + // Required permission: + // - `action.target.write` + // + // Required feature flag: + // - `actions` + rpc UpdateTarget (UpdateTargetRequest) returns (UpdateTargetResponse) { + option (google.api.http) = { + post: "/v2/actions/targets/{id}" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "action.target.write" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "Target successfully updated or left unchanged"; + }; + }; + responses: { + key: "404" + value: { + description: "The target to update does not exist."; + } + }; + responses: { + key: "400" + value: { + description: "The feature flag `actions` is not enabled."; + } + }; + }; + } + + // Delete Target + // + // Delete an existing target. This will remove it from any configured execution as well. + // In case the target is not found, the request will return a successful response as + // the desired state is already achieved. + // + // Required permission: + // - `action.target.delete` + // + // Required feature flag: + // - `actions` + rpc DeleteTarget (DeleteTargetRequest) returns (DeleteTargetResponse) { + option (google.api.http) = { + delete: "/v2/actions/targets/{id}" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "action.target.delete" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "Target deleted successfully"; + }; + }; + responses: { + key: "400" + value: { + description: "The feature flag `actions` is not enabled."; + } + }; + }; + } + + // Get Target + // + // Returns the target identified by the requested ID. + // + // Required permission: + // - `action.target.read` + // + // Required feature flag: + // - `actions` + rpc GetTarget (GetTargetRequest) returns (GetTargetResponse) { + option (google.api.http) = { + get: "/v2/actions/targets/{id}" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "action.target.read" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "Target retrieved successfully"; + } + }; + responses: { + key: "404" + value: { + description: "The target to update does not exist."; + } + }; + responses: { + key: "400" + value: { + description: "The feature flag `actions` is not enabled."; + } + }; + }; + } + + // List targets + // + // List all matching targets. By default all targets of the instance are returned. + // Make sure to include a limit and sorting for pagination. + // + // Required permission: + // - `action.target.read` + // + // Required feature flag: + // - `actions` + rpc ListTargets (ListTargetsRequest) returns (ListTargetsResponse) { + option (google.api.http) = { + post: "/v2/actions/targets/search", + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "action.target.read" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "A list of all targets matching the query"; + }; + }; + responses: { + key: "400"; + value: { + description: "invalid list query"; + }; + }; + responses: { + key: "400" + value: { + description: "The feature flag `actions` is not enabled."; + } + }; + }; + } + + // Set Execution + // + // Sets an execution to call a target or include the targets of another execution. + // Setting an empty list of targets will remove all targets from the execution, making it a noop. + // + // Required permission: + // - `action.execution.write` + // + // Required feature flag: + // - `actions` + rpc SetExecution (SetExecutionRequest) returns (SetExecutionResponse) { + option (google.api.http) = { + put: "/v2/actions/executions" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "action.execution.write" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "Execution successfully updated or left unchanged"; + }; + }; + responses: { + key: "400" + value: { + description: "Condition to set execution does not exist or the feature flag `actions` is not enabled."; + } + }; + }; + } + + // List Executions + // + // List all matching executions. By default all executions of the instance are returned that have at least one execution target. + // Make sure to include a limit and sorting for pagination. + // + // Required permission: + // - `action.execution.read` + // + // Required feature flag: + // - `actions` + rpc ListExecutions (ListExecutionsRequest) returns (ListExecutionsResponse) { + option (google.api.http) = { + post: "/v2/actions/executions/search" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "action.execution.read" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "A list of all non noop executions matching the query"; + }; + }; + responses: { + key: "400"; + value: { + description: "Invalid list query or the feature flag `actions` is not enabled."; + }; + }; + }; + } + + // List Execution Functions + // + // List all available functions which can be used as condition for executions. + rpc ListExecutionFunctions (ListExecutionFunctionsRequest) returns (ListExecutionFunctionsResponse) { + option (google.api.http) = { + get: "/v2/actions/executions/functions" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "List all functions successfully"; + }; + }; + }; + } + + // List Execution Methods + // + // List all available methods which can be used as condition for executions. + rpc ListExecutionMethods (ListExecutionMethodsRequest) returns (ListExecutionMethodsResponse) { + option (google.api.http) = { + get: "/v2/actions/executions/methods" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "List all methods successfully"; + }; + }; + }; + } + + // List Execution Services + // + // List all available services which can be used as condition for executions. + rpc ListExecutionServices (ListExecutionServicesRequest) returns (ListExecutionServicesResponse) { + option (google.api.http) = { + get: "/v2/actions/executions/services" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "List all services successfully"; + }; + }; + }; + } +} + +message CreateTargetRequest { + string name = 1 [ + (validate.rules).string = {min_len: 1, max_len: 1000}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"ip_allow_list\""; + min_length: 1 + max_length: 1000 + } + ]; + // Defines the target type and how the response of the target is treated. + oneof target_type { + option (validate.required) = true; + // Wait for response but response body is ignored, status is checked, call is sent as post. + RESTWebhook rest_webhook = 2; + // Wait for response and response body is used, status is checked, call is sent as post. + RESTCall rest_call = 3; + // Call is executed in parallel to others, ZITADEL does not wait until the call is finished. The state is ignored, call is sent as post. + RESTAsync rest_async = 4; + } + // Timeout defines the duration until ZITADEL cancels the execution. + // If the target doesn't respond before this timeout expires, then the connection is closed and the action fails. Depending on the target type and possible setting on `interrupt_on_error` following targets will not be called. In case of a `rest_async` target only this specific target will fail, without any influence on other targets of the same execution. + google.protobuf.Duration timeout = 5 [ + (validate.rules).duration = {gte: {}, lte: {seconds: 270}}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"10s\""; + } + ]; + string endpoint = 6 [ + (validate.rules).string = {min_len: 1, max_len: 1000}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"https://example.com/hooks/ip_check\"" + min_length: 1 + max_length: 1000 + } + ]; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { + example: "{\"name\": \"ip_allow_list\",\"restWebhook\":{\"interruptOnError\":true},\"timeout\":\"10s\",\"endpoint\":\"https://example.com/hooks/ip_check\"}"; + }; +} + +message CreateTargetResponse { + // The unique identifier of the newly created target. + string id = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"69629012906488334\""; + } + ]; + // The timestamp of the target creation. + google.protobuf.Timestamp creation_date = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"2024-12-18T07:50:47.492Z\""; + } + ]; + // Key used to sign and check payload sent to the target. + string signing_key = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"98KmsU67\"" + } + ]; +} + +message UpdateTargetRequest { + string id = 1 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1, + max_length: 200, + example: "\"69629026806489455\""; + } + ]; + optional string name = 2 [ + (validate.rules).string = {min_len: 1, max_len: 1000}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"ip_allow_list\"" + min_length: 1 + max_length: 1000 + } + ]; + // Defines the target type and how the response of the target is treated. + oneof target_type { + // Wait for response but response body is ignored, status is checked, call is sent as post. + RESTWebhook rest_webhook = 3; + // Wait for response and response body is used, status is checked, call is sent as post. + RESTCall rest_call = 4; + // Call is executed in parallel to others, ZITADEL does not wait until the call is finished. The state is ignored, call is sent as post. + RESTAsync rest_async = 5; + } + // Timeout defines the duration until ZITADEL cancels the execution. + // If the target doesn't respond before this timeout expires, then the connection is closed and the action fails. Depending on the target type and possible setting on `interrupt_on_error` following targets will not be called. In case of a `rest_async` target only this specific target will fail, without any influence on other targets of the same execution. + optional google.protobuf.Duration timeout = 6 [ + (validate.rules).duration = {gte: {}, lte: {seconds: 270}}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"10s\""; + } + ]; + optional string endpoint = 7 [ + (validate.rules).string = {min_len: 1, max_len: 1000}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"https://example.com/hooks/ip_check\"" + min_length: 1 + max_length: 1000 + } + ]; + // Regenerate the key used for signing and checking the payload sent to the target. + // Set the graceful period for the existing key. During that time, the previous + // signing key and the new one will be used to sign the request to allow you a smooth + // transition onf your API. + // + // Note that we currently only allow an immediate rotation ("0s") and will support + // longer expirations in the future. + optional google.protobuf.Duration expiration_signing_key = 8 [ + (validate.rules).duration = {const: {seconds: 0, nanos: 0}}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"0s\"" + minimum: 0 + maximum: 0 + } + ]; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { + example: "{\"name\": \"ip_allow_list\",\"restCall\":{\"interruptOnError\":true},\"timeout\":\"10s\",\"endpoint\":\"https://example.com/hooks/ip_check\",\"expirationSigningKey\":\"0s\"}"; + }; +} + +message UpdateTargetResponse { + // The timestamp of the change of the target. + google.protobuf.Timestamp change_date = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"2025-01-23T10:34:18.051Z\""; + } + ]; + // Key used to sign and check payload sent to the target. + optional string signing_key = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"98KmsU67\"" + } + ]; +} + +message DeleteTargetRequest { + string id = 1 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1, + max_length: 200, + example: "\"69629026806489455\""; + } + ]; +} + +message DeleteTargetResponse { + // The timestamp of the deletion of the target. + // Note that the deletion date is only guaranteed to be set if the deletion was successful during the request. + // In case the deletion occurred in a previous request, the deletion date might be empty. + google.protobuf.Timestamp deletion_date = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"2025-01-23T10:34:18.051Z\""; + } + ]; +} + +message GetTargetRequest { + string id = 1 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1, + max_length: 200, + example: "\"69629026806489455\""; + } + ]; +} + +message GetTargetResponse { + Target target = 1; +} + +message ListTargetsRequest { + // List limitations and ordering. + optional zitadel.filter.v2.PaginationRequest pagination = 1; + // The field the result is sorted by. The default is the creation date. Beware that if you change this, your result pagination might be inconsistent. + optional TargetFieldName sorting_column = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + default: "\"TARGET_FIELD_NAME_CREATION_DATE\"" + } + ]; + // Define the criteria to query for. + repeated TargetSearchFilter filters = 3; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { + example: "{\"pagination\":{\"offset\":0,\"limit\":0,\"asc\":true},\"sortingColumn\":\"TARGET_FIELD_NAME_CREATION_DATE\",\"filters\":[{\"targetNameFilter\":{\"targetName\":\"ip_allow_list\",\"method\":\"TEXT_FILTER_METHOD_EQUALS\"}},{\"inTargetIdsFilter\":{\"targetIds\":[\"69629023906488334\",\"69622366012355662\"]}}]}"; + }; +} + +message ListTargetsResponse { + reserved 'result'; + zitadel.filter.v2.PaginationResponse pagination = 1; + repeated Target targets = 2; +} + +message SetExecutionRequest { + // Condition defining when the execution should be used. + Condition condition = 1; + // Ordered list of targets called during the execution. + repeated string targets = 2; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { + example: "{\"condition\":{\"request\":{\"method\":\"zitadel.session.v2.SessionService/ListSessions\"}},\"targets\":[{\"target\":\"69629026806489455\"}]}"; + }; +} + +message SetExecutionResponse { + // The timestamp of the execution set. + google.protobuf.Timestamp set_date = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"2024-12-18T07:50:47.492Z\""; + } + ]; +} + +message ListExecutionsRequest { + // List limitations and ordering. + optional zitadel.filter.v2.PaginationRequest pagination = 1; + // The field the result is sorted by. The default is the creation date. Beware that if you change this, your result pagination might be inconsistent. + optional ExecutionFieldName sorting_column = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + default: "\"EXECUTION_FIELD_NAME_CREATION_DATE\"" + } + ]; + // Define the criteria to query for. + repeated ExecutionSearchFilter filters = 3; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { + example: "{\"pagination\":{\"offset\":0,\"limit\":0,\"asc\":true},\"sortingColumn\":\"EXECUTION_FIELD_NAME_ID\",\"filters\":[{\"targetFilter\":{\"targetId\":\"69629023906488334\"}}]}"; + }; +} + +message ListExecutionsResponse { + reserved 'result'; + zitadel.filter.v2.PaginationResponse pagination = 1; + repeated Execution executions = 2; +} + +message ListExecutionFunctionsRequest{} +message ListExecutionFunctionsResponse{ + // All available methods + repeated string functions = 1; +} +message ListExecutionMethodsRequest{} +message ListExecutionMethodsResponse{ + // All available methods + repeated string methods = 1; +} + +message ListExecutionServicesRequest{} +message ListExecutionServicesResponse{ + // All available methods + repeated string services = 1; +} diff --git a/proto/zitadel/action/v2/execution.proto b/proto/zitadel/action/v2/execution.proto new file mode 100644 index 0000000000..9f166a4c2c --- /dev/null +++ b/proto/zitadel/action/v2/execution.proto @@ -0,0 +1,135 @@ +syntax = "proto3"; + +package zitadel.action.v2; + +import "google/api/annotations.proto"; +import "google/api/field_behavior.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/struct.proto"; +import "protoc-gen-openapiv2/options/annotations.proto"; +import "validate/validate.proto"; +import "zitadel/protoc_gen_zitadel/v2/options.proto"; + +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/zitadel/zitadel/pkg/grpc/action/v2;action"; + +message Execution { + Condition condition = 1; + // The timestamp of the execution creation. + google.protobuf.Timestamp creation_date = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"2024-12-18T07:50:47.492Z\""; + } + ]; + // The timestamp of the last change to the execution. + google.protobuf.Timestamp change_date = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"2025-01-23T10:34:18.051Z\""; + } + ]; + // Ordered list of targets called during the execution. + repeated string targets = 4; +} + +message Condition { + // Condition-types under which conditions the execution should happen, only one possible. + oneof condition_type { + option (validate.required) = true; + + // Condition-type to execute if a request on the defined API point happens. + RequestExecution request = 1; + // Condition-type to execute on response if a request on the defined API point happens. + ResponseExecution response = 2; + // Condition-type to execute if function is used, replaces actions v1. + FunctionExecution function = 3; + // Condition-type to execute if an event is created in the system. + EventExecution event = 4; + } +} + +message RequestExecution { + // Condition for the request execution. Only one is possible. + oneof condition{ + option (validate.required) = true; + // GRPC-method as condition. + string method = 1 [ + (validate.rules).string = {min_len: 1, max_len: 1000}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1, + max_length: 1000, + example: "\"/zitadel.session.v2.SessionService/ListSessions\""; + } + ]; + // GRPC-service as condition. + string service = 2 [ + (validate.rules).string = {min_len: 1, max_len: 1000}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1, + max_length: 1000, + example: "\"zitadel.session.v2.SessionService\""; + } + ]; + // All calls to any available services and methods as condition. + bool all = 3 [(validate.rules).bool = {const: true}]; + } +} + +message ResponseExecution { + // Condition for the response execution. Only one is possible. + oneof condition{ + option (validate.required) = true; + // GRPC-method as condition. + string method = 1 [ + (validate.rules).string = {min_len: 1, max_len: 1000}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1, + max_length: 1000, + example: "\"/zitadel.session.v2.SessionService/ListSessions\""; + } + ]; + // GRPC-service as condition. + string service = 2 [ + (validate.rules).string = {min_len: 1, max_len: 1000}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1, + max_length: 1000, + example: "\"zitadel.session.v2.SessionService\""; + } + ]; + // All calls to any available services and methods as condition. + bool all = 3 [(validate.rules).bool = {const: true}]; + } +} + +// Executed on the specified function +message FunctionExecution { + string name = 1 [(validate.rules).string = {min_len: 1, max_len: 1000}]; +} + +message EventExecution { + // Condition for the event execution. Only one is possible. + oneof condition{ + option (validate.required) = true; + // Event name as condition. + string event = 1 [ + (validate.rules).string = {min_len: 1, max_len: 1000}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1, + max_length: 1000, + example: "\"user.human.added\""; + } + ]; + // Event group as condition, all events under this group. + string group = 2 [ + (validate.rules).string = {min_len: 1, max_len: 1000}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1, + max_length: 1000, + example: "\"user.human\""; + } + ]; + // all events as condition. + bool all = 3 [(validate.rules).bool = {const: true}]; + } +} diff --git a/proto/zitadel/action/v2/query.proto b/proto/zitadel/action/v2/query.proto new file mode 100644 index 0000000000..39e94bd826 --- /dev/null +++ b/proto/zitadel/action/v2/query.proto @@ -0,0 +1,108 @@ +syntax = "proto3"; + +package zitadel.action.v2; + +option go_package = "github.com/zitadel/zitadel/pkg/grpc/action/v2;action"; + +import "google/api/field_behavior.proto"; +import "protoc-gen-openapiv2/options/annotations.proto"; +import "validate/validate.proto"; +import "google/protobuf/timestamp.proto"; + +import "zitadel/action/v2/execution.proto"; +import "zitadel/filter/v2/filter.proto"; + +message ExecutionSearchFilter { + oneof filter { + option (validate.required) = true; + + InConditionsFilter in_conditions_filter = 1; + ExecutionTypeFilter execution_type_filter = 2; + TargetFilter target_filter = 3; + } +} + +message InConditionsFilter { + // Defines the conditions to query for. + repeated Condition conditions = 1; +} + +message ExecutionTypeFilter { + // Defines the type to query for. + ExecutionType execution_type = 1; +} + +message TargetFilter { + // Defines the id to query for. + string target_id = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "the id of the targets to include" + example: "\"69629023906488334\""; + } + ]; +} + +enum TargetFieldName { + TARGET_FIELD_NAME_UNSPECIFIED = 0; + TARGET_FIELD_NAME_ID = 1; + TARGET_FIELD_NAME_CREATED_DATE = 2; + TARGET_FIELD_NAME_CHANGED_DATE = 3; + TARGET_FIELD_NAME_NAME = 4; + TARGET_FIELD_NAME_TARGET_TYPE = 5; + TARGET_FIELD_NAME_URL = 6; + TARGET_FIELD_NAME_TIMEOUT = 7; + TARGET_FIELD_NAME_INTERRUPT_ON_ERROR = 8; +} + +message TargetSearchFilter { + oneof filter { + option (validate.required) = true; + + TargetNameFilter target_name_filter = 1; + InTargetIDsFilter in_target_ids_filter = 2; + } +} + +message TargetNameFilter { + // Defines the name of the target to query for. + string target_name = 1 [ + (validate.rules).string = {max_len: 200}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + max_length: 200; + example: "\"ip_allow_list\""; + } + ]; + // Defines which text comparison method used for the name query. + zitadel.filter.v2.TextFilterMethod method = 2 [ + (validate.rules).enum.defined_only = true, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "defines which text equality method is used"; + } + ]; +} + +message InTargetIDsFilter { + // Defines the ids to query for. + repeated string target_ids = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "the ids of the targets to include" + example: "[\"69629023906488334\",\"69622366012355662\"]"; + } + ]; +} + +enum ExecutionType { + EXECUTION_TYPE_UNSPECIFIED = 0; + EXECUTION_TYPE_REQUEST = 1; + EXECUTION_TYPE_RESPONSE = 2; + EXECUTION_TYPE_EVENT = 3; + EXECUTION_TYPE_FUNCTION = 4; +} + + +enum ExecutionFieldName { + EXECUTION_FIELD_NAME_UNSPECIFIED = 0; + EXECUTION_FIELD_NAME_ID = 1; + EXECUTION_FIELD_NAME_CREATED_DATE = 2; + EXECUTION_FIELD_NAME_CHANGED_DATE = 3; +} \ No newline at end of file diff --git a/proto/zitadel/action/v2/target.proto b/proto/zitadel/action/v2/target.proto new file mode 100644 index 0000000000..ee98b35149 --- /dev/null +++ b/proto/zitadel/action/v2/target.proto @@ -0,0 +1,75 @@ +syntax = "proto3"; + +package zitadel.action.v2; + +import "google/api/annotations.proto"; +import "google/api/field_behavior.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/struct.proto"; +import "protoc-gen-openapiv2/options/annotations.proto"; +import "validate/validate.proto"; +import "zitadel/protoc_gen_zitadel/v2/options.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/zitadel/zitadel/pkg/grpc/action/v2;action"; + +message Target { + // The unique identifier of the target. + string id = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"69629012906488334\""; + } + ]; + // The timestamp of the target creation. + google.protobuf.Timestamp creation_date = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"2024-12-18T07:50:47.492Z\""; + } + ]; + // The timestamp of the last change to the target (e.g. creation, activation, deactivation). + google.protobuf.Timestamp change_date = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"2025-01-23T10:34:18.051Z\""; + } + ]; + string name = 4 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"ip_allow_list\""; + } + ]; + // Defines the target type and how the response of the target is treated. + oneof target_type { + RESTWebhook rest_webhook = 5; + RESTCall rest_call = 6; + RESTAsync rest_async = 7; + } + // Timeout defines the duration until ZITADEL cancels the execution. + // If the target doesn't respond before this timeout expires, the the connection is closed and the action fails. Depending on the target type and possible setting on `interrupt_on_error` following targets will not be called. In case of a `rest_async` target only this specific target will fail, without any influence on other targets of the same execution. + google.protobuf.Duration timeout = 8 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"10s\""; + } + ]; + string endpoint = 9 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"https://example.com/hooks/ip_check\"" + } + ]; + string signing_key = 10 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"98KmsU67\"" + } + ]; +} + +message RESTWebhook { + // Define if any error stops the whole execution. By default the process continues as normal. + bool interrupt_on_error = 1; +} + +message RESTCall { + // Define if any error stops the whole execution. By default the process continues as normal. + bool interrupt_on_error = 1; +} + +message RESTAsync {} diff --git a/proto/zitadel/action/v2beta/action_service.proto b/proto/zitadel/action/v2beta/action_service.proto index c040eb9a1d..1cf5c210ee 100644 --- a/proto/zitadel/action/v2beta/action_service.proto +++ b/proto/zitadel/action/v2beta/action_service.proto @@ -675,7 +675,7 @@ message SetExecutionRequest { // Ordered list of targets called during the execution. repeated string targets = 2; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { - example: "{\"condition\":{\"request\":{\"method\":\"zitadel.session.v2.SessionService/ListSessions\"}},\"targets\":[{\"target\":\"69629026806489455\"}]}"; + example: "{\"condition\":{\"request\":{\"method\":\"zitadel.session.v2.SessionService/ListSessions\"}},\"targets\":[\"69629026806489455\"]}"; }; }