diff --git a/.changeset/big-parrots-sleep.md b/.changeset/big-parrots-sleep.md new file mode 100644 index 000000000..2bfed380f --- /dev/null +++ b/.changeset/big-parrots-sleep.md @@ -0,0 +1,9 @@ +--- +'@asgardeo/javascript': patch +'@asgardeo/browser': patch +'@asgardeo/nextjs': patch +'@asgardeo/node': patch +'@asgardeo/react': minor +--- + +Initial release with basic redirection capabilities and components. diff --git a/.changeset/config.json b/.changeset/config.json index 098a375c2..b65ea2b7d 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -1,15 +1,24 @@ { - "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", - "changelog": ["@changesets/changelog-github", { "repo": "asgardeo/web-ui-sdks" }], + "$schema": "https://unpkg.com/@changesets/config@2.2.0/schema.json", + "access": "restricted", + "baseBranch": "main", + "changelog": [ + "@changesets/changelog-github", + { + "repo": "asgardeo/javascript" + } + ], "commit": false, "fixed": [], + "ignore": [], "linked": [], - "access": "restricted", - "baseBranch": "main", "privatePackages": { - "version": true, - "tag": true + "version": false, + "tag": false + }, + "root": { + "packageDir": "." }, - "updateInternalDependencies": "patch", - "ignore": [] -} + "tagFormat": "@/@${version}", + "updateInternalDependencies": "patch" +} \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.cjs similarity index 92% rename from .eslintrc.js rename to .eslintrc.cjs index ca7c9259e..c5cc5f0bd 100644 --- a/.eslintrc.js +++ b/.eslintrc.cjs @@ -1,5 +1,5 @@ /** - * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/.github/workflows/pr-builder.yml b/.github/workflows/pr-builder.yml index 69eac7ef2..4eeccda03 100644 --- a/.github/workflows/pr-builder.yml +++ b/.github/workflows/pr-builder.yml @@ -118,6 +118,10 @@ jobs: - name: 🧩 Install Dependencies id: install-dependencies run: pnpm install + + - name: 🏗️ Build + id: build + run: pnpm build - name: ☄️ Check Type Errors run: pnpm nx affected --target=typecheck --parallel=3 --base=${{ env.NX_BASE }} --head=${{ env.NX_HEAD }} @@ -166,6 +170,10 @@ jobs: - name: 🧩 Install Dependencies id: install-dependencies run: pnpm install + + - name: 🏗️ Build + id: build + run: pnpm build - name: 🃏 Run Jest & Collect Coverage id: run-jest-test-and-coverage diff --git a/.gitignore b/.gitignore index c6240fcc2..cf3dd4a4b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,9 @@ -# See http://help.github.com/ignore-files/ for more about ignoring files. +# See https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files for more about ignoring files. # compiled output dist tmp -/out-tsc +out-tsc # dependencies node_modules @@ -38,5 +38,9 @@ testem.log .DS_Store Thumbs.db -# Nx .nx/cache +.nx/workspace-data + +# Environment files +*.env +.env* \ No newline at end of file diff --git a/.prettierignore b/.prettierignore index 5781d0a8c..e7c97543c 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,3 +4,5 @@ /build /node_modules /coverage +/.nx/cache +/.nx/workspace-data diff --git a/.vscode/settings.json b/.vscode/settings.json index b2efe7834..1ed1b3fab 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -17,5 +17,6 @@ "css", "scss" ], - "typescript.tsdk": "node_modules/typescript/lib" + "typescript.tsdk": "node_modules/typescript/lib", + "editor.formatOnSave": true } diff --git a/README.md b/README.md index 3d2afdab6..ed4c90e16 100644 --- a/README.md +++ b/README.md @@ -3,16 +3,15 @@ src="https://github.com/asgardeo/web-ui-sdks/assets/25959096/ae77b70c-6570-40b1-a723-719abd0f7d02" alt="Asgardeo Logo" height="40" width="auto" >

- Web SDKs + Asgardeo JavaScript SDKs

- Web SDKs for building customizable UIs for Asgardeo & WSO2 Identity Server + JavaScript SDKs for building applications with Asgardeo

License - 🚀 Release
@@ -21,7 +20,7 @@
-This repository contains the source code of the different Web SDKs that can be used to build customizable UIs for Asgardeo and WSO2 Identity Server. If you have any questions, please reach out to us through one of the following channels: +This repository contains the source code of JavaScript SDKs that can be used to build applications integrated with Asgardeo. If you have any questions, please reach out to us through one of the following channels: [![Stackoverflow](https://img.shields.io/badge/Ask%20for%20help%20on-Stackoverflow-orange)](https://stackoverflow.com/questions/tagged/wso2is) [![Join the chat at https://discord.gg/wso2](https://img.shields.io/badge/Join%20us%20on-Discord-%23e01563.svg)](https://discord.gg/wso2) @@ -31,16 +30,21 @@ This repository contains the source code of the different Web SDKs that can be u | Package | Description | | --- | --- | -| [![@asgardeo/js](https://img.shields.io/npm/v/@asgardeo/js?color=%234B32C3&label=%40asgardeo%2Fjs&logo=javascript)](./packages/core/) | Framework-agnostic JavaScript Core SDK | -| [![@asgardeo/react](https://img.shields.io/npm/v/@asgardeo/react?color=%23F7B93E&label=%40asgardeo%2Freact&logo=react)](./packages/react/) | React SDK for building customizable UIs for React applications | +| [![@asgardeo/javascript](https://img.shields.io/npm/v/@asgardeo/javascript?color=%234B32C3&label=%40asgardeo%2Fjavascript&logo=javascript)](./packages/javascript/) | Framework-agnostic JavaScript Core SDK | +| [![@asgardeo/browser](https://img.shields.io/npm/v/@asgardeo/browser?color=%234B32C3&label=%40asgardeo%2Fbrowser&logo=firefox)](./packages/browser/) | Browser-based JavaScript SDK | +| [![@asgardeo/nextjs](https://img.shields.io/npm/v/@asgardeo/nextjs?color=%23000000&label=%40asgardeo%2Fnext&logo=next.js)](./packages/next/) | Next.js SDK for building applications with Asgardeo | +| [![@asgardeo/node](https://img.shields.io/npm/v/@asgardeo/node?color=%23339933&label=%40asgardeo%2Fnode&logo=node.js)](./packages/node/) | Node.js SDK for server-side integration | +| [![@asgardeo/nuxt](https://img.shields.io/npm/v/@asgardeo/nuxt?color=%2300DC82&label=%40asgardeo%2Fnuxt&logo=nuxt)](./packages/nuxt/) | Nuxt.js SDK for building applications with Asgardeo | +| [![@asgardeo/react](https://img.shields.io/npm/v/@asgardeo/react?color=%2361DAFB&label=%40asgardeo%2Freact&logo=react)](./packages/react/) | React SDK for building applications with Asgardeo | +| [![@asgardeo/vue](https://img.shields.io/npm/v/@asgardeo/vue?color=%234FC08D&label=%40asgardeo%2Fvue&logo=vue.js)](./packages/vue/) | Vue.js SDK for building applications with Asgardeo | ## Contribute -Please read [Contributing Guide](CONTRIBUTING.md) for details on how to contribute to Asgardeo web UI SDKs. Refer to [General Contribution Guidelines](http://wso2.github.io/) for details on our code of conduct, and the process for submitting pull requests to us. +Please read [Contributing Guide](CONTRIBUTING.md) for details on how to contribute to Asgardeo JavaScript SDKs. Refer to [General Contribution Guidelines](http://wso2.github.io/) for details on our code of conduct, and the process for submitting pull requests to us. ### Reporting issues We encourage you to report issues, improvements, and feature requests creating [Github Issues](https://github.com/asgardeo/web-ui-sdks/issues). -**Important**: Please be advised that security issues MUST be reported to security@wso2com, not as GitHub issues, in order to reach the proper audience. We strongly advise following the WSO2 Security Vulnerability Reporting Guidelines when reporting the security issues. +**Important**: Please be advised that security issues MUST be reported to security@wso2.com, not as GitHub issues, in order to reach the proper audience. We strongly advise following the WSO2 Security Vulnerability Reporting Guidelines when reporting the security issues. ## License This project is licensed under the Apache License 2.0. See the [LICENSE](LICENSE) file for details. diff --git a/nx.json b/nx.json index 027b7d137..f5c24760f 100644 --- a/nx.json +++ b/nx.json @@ -1,4 +1,26 @@ { - "extends": "nx/presets/npm.json", - "$schema": "./node_modules/nx/schemas/nx-schema.json" -} + "$schema": "./node_modules/nx/schemas/nx-schema.json", + "namedInputs": { + "default": [ + "{projectRoot}/**/*", + "sharedGlobals" + ], + "production": [ + "default" + ], + "sharedGlobals": [] + }, + "targetDefaults": { + "build": { + "dependsOn": [ + "^build" + ] + }, + "typecheck": { + "dependsOn": [ + "^build" + ] + } + }, + "plugins": [] +} \ No newline at end of file diff --git a/package.json b/package.json index e7bcb44be..2d08546be 100644 --- a/package.json +++ b/package.json @@ -1,52 +1,42 @@ { "private": true, - "name": "@asgardeo/web-ui-sdks", - "version": "0.1.0", - "description": "Web SDKs for building customizable login UIs for Asgardeo & WSO2 Identity Server.", + "name": "@asgardeo/javascript-workspace", + "version": "0.0.0", + "description": "Workspace to hold the Asgardeo JavaScript SDKs.", "author": "WSO2", "license": "Apache-2.0", - "homepage": "https://github.com/asgardeo/web-ui-sdks#readme", + "homepage": "https://github.com/asgardeo/javascript#readme", "bugs": { - "url": "https://github.com/asgardeo/web-ui-sdks/issues" + "url": "https://github.com/asgardeo/javascript/issues" }, "repository": { "type": "git", - "url": "https://github.com/asgardeo/web-ui-sdks" + "url": "https://github.com/asgardeo/javascript" }, "keywords": [ "asgardeo", - "web-sdks", - "api-based-auth" + "javascript", + "workspace" ], "scripts": { - "build": "nx run-many --target=build --parallel --projects=@asgardeo/js,@asgardeo/react", - "changeset": "changeset", - "lint": "nx run-many --target=lint --parallel", + "build": "nx run-many --target=build --all", + "fix:lint": "nx run-many --target=fix:lint --all --parallel", + "lint": "nx run-many --target=lint --all --parallel", "publish:packages": "changeset publish", - "test": "nx run-many --target=test --parallel", - "typecheck": "nx run-many --target=typecheck --parallel", + "test": "nx run-many --target=test --all --parallel", "version:packages": "changeset version && pnpm install --lockfile-only" }, "devDependencies": { - "@changesets/changelog-github": "^0.5.0", - "@changesets/cli": "^2.27.3", + "@changesets/changelog-github": "^0.5.1", + "@changesets/cli": "^2.29.4", "@wso2/eslint-plugin": "catalog:", "@wso2/prettier-config": "catalog:", - "eslint": "catalog:", - "nx": "18.2.4", - "prettier": "^3.2.5", - "typescript": "5.1.6" - }, - "workspaces": [ - "packages/*", - "recipes/*" - ], - "engines": { - "node": ">=18", - "pnpm": ">=9" + "eslint": "8.57.0", + "nx": "20.8.1", + "prettier": "^2.6.2", + "typescript": "~5.7.2" }, "publishConfig": { "access": "restricted" - }, - "packageManager": "pnpm@10.8.0+sha512.0e82714d1b5b43c74610193cb20734897c1d00de89d0e18420aebc5977fa13d780a9cb05734624e81ebd81cc876cd464794850641c48b9544326b5622ca29971" -} + } +} \ No newline at end of file diff --git a/packages/core/.editorconfig b/packages/__legacy__/core/.editorconfig similarity index 100% rename from packages/core/.editorconfig rename to packages/__legacy__/core/.editorconfig diff --git a/packages/core/.eslintignore b/packages/__legacy__/core/.eslintignore similarity index 100% rename from packages/core/.eslintignore rename to packages/__legacy__/core/.eslintignore diff --git a/packages/core/.eslintrc.cjs b/packages/__legacy__/core/.eslintrc.cjs similarity index 100% rename from packages/core/.eslintrc.cjs rename to packages/__legacy__/core/.eslintrc.cjs diff --git a/packages/core/.gitignore b/packages/__legacy__/core/.gitignore similarity index 100% rename from packages/core/.gitignore rename to packages/__legacy__/core/.gitignore diff --git a/packages/core/.prettierignore b/packages/__legacy__/core/.prettierignore similarity index 100% rename from packages/core/.prettierignore rename to packages/__legacy__/core/.prettierignore diff --git a/packages/core/CHANGELOG.md b/packages/__legacy__/core/CHANGELOG.md similarity index 100% rename from packages/core/CHANGELOG.md rename to packages/__legacy__/core/CHANGELOG.md diff --git a/packages/core/LICENSE b/packages/__legacy__/core/LICENSE similarity index 100% rename from packages/core/LICENSE rename to packages/__legacy__/core/LICENSE diff --git a/packages/core/README.md b/packages/__legacy__/core/README.md similarity index 100% rename from packages/core/README.md rename to packages/__legacy__/core/README.md diff --git a/packages/core/package.json b/packages/__legacy__/core/package.json similarity index 93% rename from packages/core/package.json rename to packages/__legacy__/core/package.json index 49dc63133..6a42b3908 100644 --- a/packages/core/package.json +++ b/packages/__legacy__/core/package.json @@ -1,5 +1,6 @@ { - "name": "@asgardeo/js", + "private": true, + "name": "@asgardeo/js-legacy", "version": "0.1.3", "description": "Framework agnostic JS for Asgardeo or Identity Server", "main": "dist/esm/index.js", @@ -43,7 +44,7 @@ "@types/node": "^20.12.7", "@wso2/eslint-plugin": "catalog:", "@wso2/prettier-config": "catalog:", - "eslint": "catalog:", + "eslint": "8.57.0", "prettier": "^3.2.5", "rollup": "^4.17.2", "rollup-plugin-dts": "^6.1.0", @@ -51,7 +52,7 @@ "typescript": "5.1.6" }, "publishConfig": { - "access": "public" + "access": "restricted" }, "dependencies": { "@asgardeo/auth-js": "^5.0.1", diff --git a/packages/core/prettier.config.cjs b/packages/__legacy__/core/prettier.config.cjs similarity index 100% rename from packages/core/prettier.config.cjs rename to packages/__legacy__/core/prettier.config.cjs diff --git a/packages/core/rollup.config.cjs b/packages/__legacy__/core/rollup.config.cjs similarity index 100% rename from packages/core/rollup.config.cjs rename to packages/__legacy__/core/rollup.config.cjs diff --git a/packages/core/src/api/authenticate.ts b/packages/__legacy__/core/src/api/authenticate.ts similarity index 100% rename from packages/core/src/api/authenticate.ts rename to packages/__legacy__/core/src/api/authenticate.ts diff --git a/packages/core/src/api/authorize.ts b/packages/__legacy__/core/src/api/authorize.ts similarity index 100% rename from packages/core/src/api/authorize.ts rename to packages/__legacy__/core/src/api/authorize.ts diff --git a/packages/core/src/api/get-branding-preference-text.ts b/packages/__legacy__/core/src/api/get-branding-preference-text.ts similarity index 100% rename from packages/core/src/api/get-branding-preference-text.ts rename to packages/__legacy__/core/src/api/get-branding-preference-text.ts diff --git a/packages/core/src/api/get-branding-preference.ts b/packages/__legacy__/core/src/api/get-branding-preference.ts similarity index 100% rename from packages/core/src/api/get-branding-preference.ts rename to packages/__legacy__/core/src/api/get-branding-preference.ts diff --git a/packages/core/src/api/get-profile-information.ts b/packages/__legacy__/core/src/api/get-profile-information.ts similarity index 100% rename from packages/core/src/api/get-profile-information.ts rename to packages/__legacy__/core/src/api/get-profile-information.ts diff --git a/packages/core/src/api/public-api.ts b/packages/__legacy__/core/src/api/public-api.ts similarity index 100% rename from packages/core/src/api/public-api.ts rename to packages/__legacy__/core/src/api/public-api.ts diff --git a/packages/core/src/api/sign-out.ts b/packages/__legacy__/core/src/api/sign-out.ts similarity index 97% rename from packages/core/src/api/sign-out.ts rename to packages/__legacy__/core/src/api/sign-out.ts index 542353864..ad6416a00 100644 --- a/packages/core/src/api/sign-out.ts +++ b/packages/__legacy__/core/src/api/sign-out.ts @@ -51,7 +51,7 @@ const signOut = async (): Promise => { try { formBody.append('id_token_hint', await authClient.getIDToken()); formBody.append('client_id', (await authClient.getDataLayer().getConfigData()).clientID); - formBody.append('response_mode', ResponseMode.direct); + formBody.append('response_mode', ResponseMode.Direct); } catch (error) { throw new AsgardeoUIException('JS_UI_CORE-SIGNOUT-SO-IV', 'Failed to build the body of the signout request.'); } diff --git a/packages/core/src/auth-client.ts b/packages/__legacy__/core/src/auth-client.ts similarity index 85% rename from packages/core/src/auth-client.ts rename to packages/__legacy__/core/src/auth-client.ts index 06ef83743..51e67bcad 100644 --- a/packages/core/src/auth-client.ts +++ b/packages/__legacy__/core/src/auth-client.ts @@ -16,7 +16,7 @@ * under the License. */ -import {AsgardeoAuthClient, Store, CryptoUtils, ResponseMode} from '@asgardeo/auth-js'; +import {AsgardeoAuthClient, Store, Crypto, ResponseMode} from '@asgardeo/auth-js'; import {UIAuthClient, UIAuthConfig} from './models/auth-config'; import {BrandingPreferenceTypes} from './models/branding-api-response'; @@ -38,10 +38,10 @@ export class AuthClient { * * @param {UIAuthConfig} authClientConfig - The configuration for the `UIAuthClient`. * @param {Store} store - The store for the `UIAuthClient`. - * @param {CryptoUtils} cryptoUtils - The crypto utilities for the `UIAuthClient`. + * @param {Crypto} cryptoUtils - The crypto utilities for the `UIAuthClient`. * @returns {UIAuthClient} The singleton instance of `UIAuthClient`. */ - static getInstance(authClientConfig?: UIAuthConfig, store?: Store, cryptoUtils?: CryptoUtils): UIAuthClient { + static getInstance(authClientConfig?: UIAuthConfig, store?: Store, cryptoUtils?: Crypto): UIAuthClient { if (!AuthClient.instance) { const DEFAULT_NAME: string = 'carbon.super'; @@ -50,7 +50,7 @@ export class AuthClient { enableConsoleBranding: authClientConfig?.enableConsoleBranding ?? true, enableConsoleTextBranding: authClientConfig?.enableConsoleTextBranding ?? true, name: authClientConfig?.name ?? DEFAULT_NAME, - responseMode: ResponseMode.direct, + responseMode: ResponseMode.Direct, type: authClientConfig?.type ?? BrandingPreferenceTypes.Org, }; @@ -63,4 +63,4 @@ export class AuthClient { } /* Interfaces, classes and enums required from the auth-js package */ -export {CryptoUtils, JWKInterface, Store, AsgardeoAuthClient, TokenResponse, ResponseMode} from '@asgardeo/auth-js'; +export {Crypto, JWKInterface, Store, AsgardeoAuthClient, TokenResponse, ResponseMode} from '@asgardeo/auth-js'; diff --git a/packages/core/src/branding/default-branding/dark-theme.ts b/packages/__legacy__/core/src/branding/default-branding/dark-theme.ts similarity index 100% rename from packages/core/src/branding/default-branding/dark-theme.ts rename to packages/__legacy__/core/src/branding/default-branding/dark-theme.ts diff --git a/packages/core/src/branding/default-branding/default-branding.ts b/packages/__legacy__/core/src/branding/default-branding/default-branding.ts similarity index 100% rename from packages/core/src/branding/default-branding/default-branding.ts rename to packages/__legacy__/core/src/branding/default-branding/default-branding.ts diff --git a/packages/core/src/branding/default-branding/light-theme.ts b/packages/__legacy__/core/src/branding/default-branding/light-theme.ts similarity index 100% rename from packages/core/src/branding/default-branding/light-theme.ts rename to packages/__legacy__/core/src/branding/default-branding/light-theme.ts diff --git a/packages/core/src/branding/get-branding-css.ts b/packages/__legacy__/core/src/branding/get-branding-css.ts similarity index 100% rename from packages/core/src/branding/get-branding-css.ts rename to packages/__legacy__/core/src/branding/get-branding-css.ts diff --git a/packages/core/src/branding/get-branding.ts b/packages/__legacy__/core/src/branding/get-branding.ts similarity index 100% rename from packages/core/src/branding/get-branding.ts rename to packages/__legacy__/core/src/branding/get-branding.ts diff --git a/packages/core/src/branding/public.ts b/packages/__legacy__/core/src/branding/public.ts similarity index 100% rename from packages/core/src/branding/public.ts rename to packages/__legacy__/core/src/branding/public.ts diff --git a/packages/core/src/exception.ts b/packages/__legacy__/core/src/exception.ts similarity index 100% rename from packages/core/src/exception.ts rename to packages/__legacy__/core/src/exception.ts diff --git a/packages/core/src/i18n/get-localization.ts b/packages/__legacy__/core/src/i18n/get-localization.ts similarity index 100% rename from packages/core/src/i18n/get-localization.ts rename to packages/__legacy__/core/src/i18n/get-localization.ts diff --git a/packages/core/src/i18n/public.ts b/packages/__legacy__/core/src/i18n/public.ts similarity index 100% rename from packages/core/src/i18n/public.ts rename to packages/__legacy__/core/src/i18n/public.ts diff --git a/packages/core/src/i18n/screens/common/en-US.ts b/packages/__legacy__/core/src/i18n/screens/common/en-US.ts similarity index 100% rename from packages/core/src/i18n/screens/common/en-US.ts rename to packages/__legacy__/core/src/i18n/screens/common/en-US.ts diff --git a/packages/core/src/i18n/screens/common/fr-FR.ts b/packages/__legacy__/core/src/i18n/screens/common/fr-FR.ts similarity index 100% rename from packages/core/src/i18n/screens/common/fr-FR.ts rename to packages/__legacy__/core/src/i18n/screens/common/fr-FR.ts diff --git a/packages/core/src/i18n/screens/common/model.ts b/packages/__legacy__/core/src/i18n/screens/common/model.ts similarity index 100% rename from packages/core/src/i18n/screens/common/model.ts rename to packages/__legacy__/core/src/i18n/screens/common/model.ts diff --git a/packages/core/src/i18n/screens/emailOtp/en-US.ts b/packages/__legacy__/core/src/i18n/screens/emailOtp/en-US.ts similarity index 100% rename from packages/core/src/i18n/screens/emailOtp/en-US.ts rename to packages/__legacy__/core/src/i18n/screens/emailOtp/en-US.ts diff --git a/packages/core/src/i18n/screens/emailOtp/model.ts b/packages/__legacy__/core/src/i18n/screens/emailOtp/model.ts similarity index 100% rename from packages/core/src/i18n/screens/emailOtp/model.ts rename to packages/__legacy__/core/src/i18n/screens/emailOtp/model.ts diff --git a/packages/core/src/i18n/screens/identifierFirst/en-US.ts b/packages/__legacy__/core/src/i18n/screens/identifierFirst/en-US.ts similarity index 100% rename from packages/core/src/i18n/screens/identifierFirst/en-US.ts rename to packages/__legacy__/core/src/i18n/screens/identifierFirst/en-US.ts diff --git a/packages/core/src/i18n/screens/identifierFirst/fr-FR.ts b/packages/__legacy__/core/src/i18n/screens/identifierFirst/fr-FR.ts similarity index 100% rename from packages/core/src/i18n/screens/identifierFirst/fr-FR.ts rename to packages/__legacy__/core/src/i18n/screens/identifierFirst/fr-FR.ts diff --git a/packages/core/src/i18n/screens/identifierFirst/model.ts b/packages/__legacy__/core/src/i18n/screens/identifierFirst/model.ts similarity index 100% rename from packages/core/src/i18n/screens/identifierFirst/model.ts rename to packages/__legacy__/core/src/i18n/screens/identifierFirst/model.ts diff --git a/packages/core/src/i18n/screens/keys.ts b/packages/__legacy__/core/src/i18n/screens/keys.ts similarity index 100% rename from packages/core/src/i18n/screens/keys.ts rename to packages/__legacy__/core/src/i18n/screens/keys.ts diff --git a/packages/core/src/i18n/screens/login/en-US.ts b/packages/__legacy__/core/src/i18n/screens/login/en-US.ts similarity index 100% rename from packages/core/src/i18n/screens/login/en-US.ts rename to packages/__legacy__/core/src/i18n/screens/login/en-US.ts diff --git a/packages/core/src/i18n/screens/login/fr-FR.ts b/packages/__legacy__/core/src/i18n/screens/login/fr-FR.ts similarity index 100% rename from packages/core/src/i18n/screens/login/fr-FR.ts rename to packages/__legacy__/core/src/i18n/screens/login/fr-FR.ts diff --git a/packages/core/src/i18n/screens/login/model.ts b/packages/__legacy__/core/src/i18n/screens/login/model.ts similarity index 100% rename from packages/core/src/i18n/screens/login/model.ts rename to packages/__legacy__/core/src/i18n/screens/login/model.ts diff --git a/packages/core/src/i18n/screens/model.ts b/packages/__legacy__/core/src/i18n/screens/model.ts similarity index 100% rename from packages/core/src/i18n/screens/model.ts rename to packages/__legacy__/core/src/i18n/screens/model.ts diff --git a/packages/core/src/i18n/screens/smsOtp/en-US.ts b/packages/__legacy__/core/src/i18n/screens/smsOtp/en-US.ts similarity index 100% rename from packages/core/src/i18n/screens/smsOtp/en-US.ts rename to packages/__legacy__/core/src/i18n/screens/smsOtp/en-US.ts diff --git a/packages/core/src/i18n/screens/smsOtp/model.ts b/packages/__legacy__/core/src/i18n/screens/smsOtp/model.ts similarity index 100% rename from packages/core/src/i18n/screens/smsOtp/model.ts rename to packages/__legacy__/core/src/i18n/screens/smsOtp/model.ts diff --git a/packages/core/src/i18n/screens/totp/en-US.ts b/packages/__legacy__/core/src/i18n/screens/totp/en-US.ts similarity index 100% rename from packages/core/src/i18n/screens/totp/en-US.ts rename to packages/__legacy__/core/src/i18n/screens/totp/en-US.ts diff --git a/packages/core/src/i18n/screens/totp/fr-FR.ts b/packages/__legacy__/core/src/i18n/screens/totp/fr-FR.ts similarity index 100% rename from packages/core/src/i18n/screens/totp/fr-FR.ts rename to packages/__legacy__/core/src/i18n/screens/totp/fr-FR.ts diff --git a/packages/core/src/i18n/screens/totp/model.ts b/packages/__legacy__/core/src/i18n/screens/totp/model.ts similarity index 100% rename from packages/core/src/i18n/screens/totp/model.ts rename to packages/__legacy__/core/src/i18n/screens/totp/model.ts diff --git a/packages/core/src/index.ts b/packages/__legacy__/core/src/index.ts similarity index 100% rename from packages/core/src/index.ts rename to packages/__legacy__/core/src/index.ts diff --git a/packages/core/src/models/auth-api-request.ts b/packages/__legacy__/core/src/models/auth-api-request.ts similarity index 100% rename from packages/core/src/models/auth-api-request.ts rename to packages/__legacy__/core/src/models/auth-api-request.ts diff --git a/packages/core/src/models/auth-api-response.ts b/packages/__legacy__/core/src/models/auth-api-response.ts similarity index 100% rename from packages/core/src/models/auth-api-response.ts rename to packages/__legacy__/core/src/models/auth-api-response.ts diff --git a/packages/core/src/models/auth-config.ts b/packages/__legacy__/core/src/models/auth-config.ts similarity index 100% rename from packages/core/src/models/auth-config.ts rename to packages/__legacy__/core/src/models/auth-config.ts diff --git a/packages/core/src/models/branding-api-response.ts b/packages/__legacy__/core/src/models/branding-api-response.ts similarity index 100% rename from packages/core/src/models/branding-api-response.ts rename to packages/__legacy__/core/src/models/branding-api-response.ts diff --git a/packages/core/src/models/branding-text-api-response.ts b/packages/__legacy__/core/src/models/branding-text-api-response.ts similarity index 100% rename from packages/core/src/models/branding-text-api-response.ts rename to packages/__legacy__/core/src/models/branding-text-api-response.ts diff --git a/packages/core/src/models/branding.ts b/packages/__legacy__/core/src/models/branding.ts similarity index 100% rename from packages/core/src/models/branding.ts rename to packages/__legacy__/core/src/models/branding.ts diff --git a/packages/core/src/models/common.ts b/packages/__legacy__/core/src/models/common.ts similarity index 100% rename from packages/core/src/models/common.ts rename to packages/__legacy__/core/src/models/common.ts diff --git a/packages/core/src/models/element-styles.ts b/packages/__legacy__/core/src/models/element-styles.ts similarity index 100% rename from packages/core/src/models/element-styles.ts rename to packages/__legacy__/core/src/models/element-styles.ts diff --git a/packages/core/src/models/get-branding-props.ts b/packages/__legacy__/core/src/models/get-branding-props.ts similarity index 100% rename from packages/core/src/models/get-branding-props.ts rename to packages/__legacy__/core/src/models/get-branding-props.ts diff --git a/packages/core/src/models/get-localization-props.ts b/packages/__legacy__/core/src/models/get-localization-props.ts similarity index 100% rename from packages/core/src/models/get-localization-props.ts rename to packages/__legacy__/core/src/models/get-localization-props.ts diff --git a/packages/core/src/models/me-api-response.ts b/packages/__legacy__/core/src/models/me-api-response.ts similarity index 100% rename from packages/core/src/models/me-api-response.ts rename to packages/__legacy__/core/src/models/me-api-response.ts diff --git a/packages/core/src/models/public-models.ts b/packages/__legacy__/core/src/models/public-models.ts similarity index 100% rename from packages/core/src/models/public-models.ts rename to packages/__legacy__/core/src/models/public-models.ts diff --git a/packages/core/src/models/screen-type.ts b/packages/__legacy__/core/src/models/screen-type.ts similarity index 100% rename from packages/core/src/models/screen-type.ts rename to packages/__legacy__/core/src/models/screen-type.ts diff --git a/packages/core/tsconfig.eslint.json b/packages/__legacy__/core/tsconfig.eslint.json similarity index 100% rename from packages/core/tsconfig.eslint.json rename to packages/__legacy__/core/tsconfig.eslint.json diff --git a/packages/core/tsconfig.json b/packages/__legacy__/core/tsconfig.json similarity index 100% rename from packages/core/tsconfig.json rename to packages/__legacy__/core/tsconfig.json diff --git a/packages/core/tsconfig.lib.json b/packages/__legacy__/core/tsconfig.lib.json similarity index 100% rename from packages/core/tsconfig.lib.json rename to packages/__legacy__/core/tsconfig.lib.json diff --git a/packages/__legacy__/react/.editorconfig b/packages/__legacy__/react/.editorconfig new file mode 100644 index 000000000..54a161112 --- /dev/null +++ b/packages/__legacy__/react/.editorconfig @@ -0,0 +1 @@ +../../.editorconfig diff --git a/packages/__legacy__/react/.eslintignore b/packages/__legacy__/react/.eslintignore new file mode 100644 index 000000000..c925c21d5 --- /dev/null +++ b/packages/__legacy__/react/.eslintignore @@ -0,0 +1,2 @@ +/dist +/node_modules diff --git a/packages/__legacy__/react/.eslintrc.cjs b/packages/__legacy__/react/.eslintrc.cjs new file mode 100644 index 000000000..d8644f33e --- /dev/null +++ b/packages/__legacy__/react/.eslintrc.cjs @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const path = require('path'); + +module.exports = { + extends: [ + 'plugin:@wso2/typescript', + 'plugin:@wso2/react', + 'plugin:@wso2/strict', + 'plugin:@wso2/internal', + 'plugin:@wso2/prettier', + 'plugin:@wso2/jest', + 'plugin:react/jsx-runtime', + ], + parserOptions: { + project: [path.resolve(__dirname, 'tsconfig.lib.json'), path.resolve(__dirname, 'tsconfig.eslint.json')], + }, + plugins: ['@wso2'], + rules: { + // In `SignIn.tsx` we are using non dot notation to access the object properties. + // TODO: Refactor the code to use dot notation. + '@typescript-eslint/dot-notation': 'off', + // We are throwing custom exceptions in the codebase. + // Hence, turning this off to avoid linting errors. (https://eslint.org/docs/latest/rules/no-throw-literal#known-limitations) + '@typescript-eslint/no-throw-literal': 'off', + // TODO: Fix this and enable. + // Occurred while linting /packages/react/src/utils/crypto-utils.ts:33 + // Rule: "@typescript-eslint/no-useless-constructor" + '@typescript-eslint/no-useless-constructor': 'off', + 'class-methods-use-this': 'off', + }, +}; diff --git a/packages/__legacy__/react/.gitignore b/packages/__legacy__/react/.gitignore new file mode 100644 index 000000000..f20a8a8c1 --- /dev/null +++ b/packages/__legacy__/react/.gitignore @@ -0,0 +1,134 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# misc +.DS_Store +*.pem diff --git a/packages/__legacy__/react/.prettierignore b/packages/__legacy__/react/.prettierignore new file mode 100644 index 000000000..c925c21d5 --- /dev/null +++ b/packages/__legacy__/react/.prettierignore @@ -0,0 +1,2 @@ +/dist +/node_modules diff --git a/packages/react/CHANGELOG.md b/packages/__legacy__/react/CHANGELOG.md similarity index 100% rename from packages/react/CHANGELOG.md rename to packages/__legacy__/react/CHANGELOG.md diff --git a/packages/__legacy__/react/LICENSE b/packages/__legacy__/react/LICENSE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/packages/__legacy__/react/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/__legacy__/react/README.md b/packages/__legacy__/react/README.md new file mode 100644 index 000000000..30b225361 --- /dev/null +++ b/packages/__legacy__/react/README.md @@ -0,0 +1,27 @@ +

+

@asgardeo/react

+

+

React Wrapper to build customizable login UIs for Asgardeo or Identity Server

+
+ npm (scoped) + npm + License +
+ +## Installation + +```bash +# With npm +npm install @asgardeo/react + +# With pnpm +pnpm add @asgardeo/react + +# With yarn +yarn add @asgardeo/react +``` + +## License + +Licenses this source under the Apache License, Version 2.0 [LICENSE](./LICENSE), You may not use this file except in +compliance with the License. diff --git a/packages/react/declarations.d.ts b/packages/__legacy__/react/declarations.d.ts similarity index 100% rename from packages/react/declarations.d.ts rename to packages/__legacy__/react/declarations.d.ts diff --git a/packages/__legacy__/react/package.json b/packages/__legacy__/react/package.json new file mode 100644 index 000000000..a0cffd761 --- /dev/null +++ b/packages/__legacy__/react/package.json @@ -0,0 +1,81 @@ +{ + "private": true, + "name": "@asgardeo/react-legacy", + "version": "0.2.4", + "description": "React Wrapper to build customizable login UIs for Asgardeo or Identity Server", + "main": "dist/esm/index.js", + "module": "dist/esm/index.js", + "types": "dist/index.d.ts", + "type": "module", + "author": "WSO2", + "license": "Apache-2.0", + "files": [ + "dist", + "LICENSE", + "README.md" + ], + "homepage": "https://github.com/asgardeo/web-ui-sdks/tree/main/packages/react#readme", + "bugs": { + "url": "https://github.com/asgardeo/web-ui-sdks/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/asgardeo/web-ui-sdks", + "directory": "packages/react" + }, + "keywords": [ + "asgardeo", + "identity", + "ui", + "react", + "login", + "customize" + ], + "scripts": { + "build": "rollup -c", + "lint": "eslint .", + "lint:fix": "eslint . --fix" + }, + "publishConfig": { + "access": "restricted" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^25.0.7", + "@rollup/plugin-image": "^3.0.3", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-typescript": "^11.1.6", + "@types/node": "^20.12.7", + "@types/randombytes": "^2.0.3", + "@types/react": "^18.2.79", + "@types/react-dom": "^18.2.25", + "@wso2/eslint-plugin": "catalog:", + "@wso2/prettier-config": "catalog:", + "@wso2/stylelint-config": "catalog:", + "eslint": "8.57.0", + "prettier": "^3.2.5", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "rollup": "^4.17.2", + "rollup-plugin-dts": "^6.1.0", + "rollup-plugin-polyfill-node": "^0.13.0", + "rollup-plugin-styles": "^4.0.0", + "sass": "^1.75.0", + "stylelint": "15.1.0", + "tslib": "^2.6.2", + "typescript": "5.1.6" + }, + "dependencies": { + "@asgardeo/js": "*", + "@oxygen-ui/react": "^1.11.0", + "base64url": "^3.0.1", + "buffer": "^6.0.3", + "clsx": "^2.1.1", + "fast-sha256": "^1.3.0", + "jose": "^5.3.0", + "randombytes": "^2.1.0" + }, + "peerDependencies": { + "react": ">=18.0.0", + "react-dom": ">=18.0.0" + } +} diff --git a/packages/__legacy__/react/prettier.config.cjs b/packages/__legacy__/react/prettier.config.cjs new file mode 100644 index 000000000..c07f730d2 --- /dev/null +++ b/packages/__legacy__/react/prettier.config.cjs @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +module.exports = require('@wso2/prettier-config'); diff --git a/packages/react/rollup.config.cjs b/packages/__legacy__/react/rollup.config.cjs similarity index 100% rename from packages/react/rollup.config.cjs rename to packages/__legacy__/react/rollup.config.cjs diff --git a/packages/react/src/assets/building-icon.svg b/packages/__legacy__/react/src/assets/building-icon.svg similarity index 100% rename from packages/react/src/assets/building-icon.svg rename to packages/__legacy__/react/src/assets/building-icon.svg diff --git a/packages/react/src/assets/email-solid.svg b/packages/__legacy__/react/src/assets/email-solid.svg similarity index 100% rename from packages/react/src/assets/email-solid.svg rename to packages/__legacy__/react/src/assets/email-solid.svg diff --git a/packages/react/src/assets/sms-icon.svg b/packages/__legacy__/react/src/assets/sms-icon.svg similarity index 100% rename from packages/react/src/assets/sms-icon.svg rename to packages/__legacy__/react/src/assets/sms-icon.svg diff --git a/packages/react/src/assets/social-logins/facebook.svg b/packages/__legacy__/react/src/assets/social-logins/facebook.svg similarity index 100% rename from packages/react/src/assets/social-logins/facebook.svg rename to packages/__legacy__/react/src/assets/social-logins/facebook.svg diff --git a/packages/react/src/assets/social-logins/github.svg b/packages/__legacy__/react/src/assets/social-logins/github.svg similarity index 100% rename from packages/react/src/assets/social-logins/github.svg rename to packages/__legacy__/react/src/assets/social-logins/github.svg diff --git a/packages/react/src/assets/social-logins/google.svg b/packages/__legacy__/react/src/assets/social-logins/google.svg similarity index 100% rename from packages/react/src/assets/social-logins/google.svg rename to packages/__legacy__/react/src/assets/social-logins/google.svg diff --git a/packages/react/src/assets/social-logins/microsoft.svg b/packages/__legacy__/react/src/assets/social-logins/microsoft.svg similarity index 100% rename from packages/react/src/assets/social-logins/microsoft.svg rename to packages/__legacy__/react/src/assets/social-logins/microsoft.svg diff --git a/packages/react/src/assets/totp.svg b/packages/__legacy__/react/src/assets/totp.svg similarity index 100% rename from packages/react/src/assets/totp.svg rename to packages/__legacy__/react/src/assets/totp.svg diff --git a/packages/react/src/components/SignIn/SignIn.tsx b/packages/__legacy__/react/src/components/SignIn/SignIn.tsx similarity index 100% rename from packages/react/src/components/SignIn/SignIn.tsx rename to packages/__legacy__/react/src/components/SignIn/SignIn.tsx diff --git a/packages/react/src/components/SignIn/fragments/BasicAuth.tsx b/packages/__legacy__/react/src/components/SignIn/fragments/BasicAuth.tsx similarity index 100% rename from packages/react/src/components/SignIn/fragments/BasicAuth.tsx rename to packages/__legacy__/react/src/components/SignIn/fragments/BasicAuth.tsx diff --git a/packages/react/src/components/SignIn/fragments/EmailOtp.tsx b/packages/__legacy__/react/src/components/SignIn/fragments/EmailOtp.tsx similarity index 100% rename from packages/react/src/components/SignIn/fragments/EmailOtp.tsx rename to packages/__legacy__/react/src/components/SignIn/fragments/EmailOtp.tsx diff --git a/packages/react/src/components/SignIn/fragments/IdentifierFirst.tsx b/packages/__legacy__/react/src/components/SignIn/fragments/IdentifierFirst.tsx similarity index 100% rename from packages/react/src/components/SignIn/fragments/IdentifierFirst.tsx rename to packages/__legacy__/react/src/components/SignIn/fragments/IdentifierFirst.tsx diff --git a/packages/react/src/components/SignIn/fragments/LoginOptionsBox.tsx b/packages/__legacy__/react/src/components/SignIn/fragments/LoginOptionsBox.tsx similarity index 100% rename from packages/react/src/components/SignIn/fragments/LoginOptionsBox.tsx rename to packages/__legacy__/react/src/components/SignIn/fragments/LoginOptionsBox.tsx diff --git a/packages/react/src/components/SignIn/fragments/SmsOtp.tsx b/packages/__legacy__/react/src/components/SignIn/fragments/SmsOtp.tsx similarity index 100% rename from packages/react/src/components/SignIn/fragments/SmsOtp.tsx rename to packages/__legacy__/react/src/components/SignIn/fragments/SmsOtp.tsx diff --git a/packages/react/src/components/SignIn/fragments/Totp.tsx b/packages/__legacy__/react/src/components/SignIn/fragments/Totp.tsx similarity index 100% rename from packages/react/src/components/SignIn/fragments/Totp.tsx rename to packages/__legacy__/react/src/components/SignIn/fragments/Totp.tsx diff --git a/packages/react/src/components/SignIn/fragments/basic-auth.scss b/packages/__legacy__/react/src/components/SignIn/fragments/basic-auth.scss similarity index 100% rename from packages/react/src/components/SignIn/fragments/basic-auth.scss rename to packages/__legacy__/react/src/components/SignIn/fragments/basic-auth.scss diff --git a/packages/react/src/components/SignIn/fragments/email-otp.scss b/packages/__legacy__/react/src/components/SignIn/fragments/email-otp.scss similarity index 100% rename from packages/react/src/components/SignIn/fragments/email-otp.scss rename to packages/__legacy__/react/src/components/SignIn/fragments/email-otp.scss diff --git a/packages/react/src/components/SignIn/fragments/totp.scss b/packages/__legacy__/react/src/components/SignIn/fragments/totp.scss similarity index 100% rename from packages/react/src/components/SignIn/fragments/totp.scss rename to packages/__legacy__/react/src/components/SignIn/fragments/totp.scss diff --git a/packages/react/src/components/SignIn/sign-in.scss b/packages/__legacy__/react/src/components/SignIn/sign-in.scss similarity index 100% rename from packages/react/src/components/SignIn/sign-in.scss rename to packages/__legacy__/react/src/components/SignIn/sign-in.scss diff --git a/packages/react/src/components/SignInButton/SignInButton.tsx b/packages/__legacy__/react/src/components/SignInButton/SignInButton.tsx similarity index 100% rename from packages/react/src/components/SignInButton/SignInButton.tsx rename to packages/__legacy__/react/src/components/SignInButton/SignInButton.tsx diff --git a/packages/react/src/components/SignInButton/sign-in-button.scss b/packages/__legacy__/react/src/components/SignInButton/sign-in-button.scss similarity index 100% rename from packages/react/src/components/SignInButton/sign-in-button.scss rename to packages/__legacy__/react/src/components/SignInButton/sign-in-button.scss diff --git a/packages/react/src/components/SignOutButton/SignOutButton.tsx b/packages/__legacy__/react/src/components/SignOutButton/SignOutButton.tsx similarity index 100% rename from packages/react/src/components/SignOutButton/SignOutButton.tsx rename to packages/__legacy__/react/src/components/SignOutButton/SignOutButton.tsx diff --git a/packages/react/src/components/SignedIn/SignedIn.tsx b/packages/__legacy__/react/src/components/SignedIn/SignedIn.tsx similarity index 100% rename from packages/react/src/components/SignedIn/SignedIn.tsx rename to packages/__legacy__/react/src/components/SignedIn/SignedIn.tsx diff --git a/packages/react/src/components/SignedOut/SignedOut.tsx b/packages/__legacy__/react/src/components/SignedOut/SignedOut.tsx similarity index 100% rename from packages/react/src/components/SignedOut/SignedOut.tsx rename to packages/__legacy__/react/src/components/SignedOut/SignedOut.tsx diff --git a/packages/react/src/components/public-components.ts b/packages/__legacy__/react/src/components/public-components.ts similarity index 100% rename from packages/react/src/components/public-components.ts rename to packages/__legacy__/react/src/components/public-components.ts diff --git a/packages/react/src/contexts/asgardeo-context.ts b/packages/__legacy__/react/src/contexts/asgardeo-context.ts similarity index 100% rename from packages/react/src/contexts/asgardeo-context.ts rename to packages/__legacy__/react/src/contexts/asgardeo-context.ts diff --git a/packages/react/src/contexts/branding-preference-context.ts b/packages/__legacy__/react/src/contexts/branding-preference-context.ts similarity index 100% rename from packages/react/src/contexts/branding-preference-context.ts rename to packages/__legacy__/react/src/contexts/branding-preference-context.ts diff --git a/packages/react/src/contexts/i18n-context.ts b/packages/__legacy__/react/src/contexts/i18n-context.ts similarity index 100% rename from packages/react/src/contexts/i18n-context.ts rename to packages/__legacy__/react/src/contexts/i18n-context.ts diff --git a/packages/react/src/hooks/use-authentication.ts b/packages/__legacy__/react/src/hooks/use-authentication.ts similarity index 100% rename from packages/react/src/hooks/use-authentication.ts rename to packages/__legacy__/react/src/hooks/use-authentication.ts diff --git a/packages/react/src/hooks/use-config.ts b/packages/__legacy__/react/src/hooks/use-config.ts similarity index 100% rename from packages/react/src/hooks/use-config.ts rename to packages/__legacy__/react/src/hooks/use-config.ts diff --git a/packages/react/src/hooks/use-on.ts b/packages/__legacy__/react/src/hooks/use-on.ts similarity index 100% rename from packages/react/src/hooks/use-on.ts rename to packages/__legacy__/react/src/hooks/use-on.ts diff --git a/packages/react/src/hooks/use-translations.ts b/packages/__legacy__/react/src/hooks/use-translations.ts similarity index 100% rename from packages/react/src/hooks/use-translations.ts rename to packages/__legacy__/react/src/hooks/use-translations.ts diff --git a/packages/__legacy__/react/src/index.ts b/packages/__legacy__/react/src/index.ts new file mode 100644 index 000000000..98f497c95 --- /dev/null +++ b/packages/__legacy__/react/src/index.ts @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from './components/public-components'; +export * from './models/public-models'; +export {default as AsgardeoProvider} from './providers/AsgardeoProvider'; +export {default as useAuthentication} from './hooks/use-authentication'; +export {default as useOn} from './hooks/use-on'; diff --git a/packages/react/src/models/asgardeo-provider-props.ts b/packages/__legacy__/react/src/models/asgardeo-provider-props.ts similarity index 100% rename from packages/react/src/models/asgardeo-provider-props.ts rename to packages/__legacy__/react/src/models/asgardeo-provider-props.ts diff --git a/packages/react/src/models/auth-context.ts b/packages/__legacy__/react/src/models/auth-context.ts similarity index 100% rename from packages/react/src/models/auth-context.ts rename to packages/__legacy__/react/src/models/auth-context.ts diff --git a/packages/react/src/models/basic-auth-props.ts b/packages/__legacy__/react/src/models/basic-auth-props.ts similarity index 100% rename from packages/react/src/models/basic-auth-props.ts rename to packages/__legacy__/react/src/models/basic-auth-props.ts diff --git a/packages/react/src/models/branding-preference-provider-props.ts b/packages/__legacy__/react/src/models/branding-preference-provider-props.ts similarity index 100% rename from packages/react/src/models/branding-preference-provider-props.ts rename to packages/__legacy__/react/src/models/branding-preference-provider-props.ts diff --git a/packages/react/src/models/email-otp-props.ts b/packages/__legacy__/react/src/models/email-otp-props.ts similarity index 100% rename from packages/react/src/models/email-otp-props.ts rename to packages/__legacy__/react/src/models/email-otp-props.ts diff --git a/packages/react/src/models/i18n.ts b/packages/__legacy__/react/src/models/i18n.ts similarity index 100% rename from packages/react/src/models/i18n.ts rename to packages/__legacy__/react/src/models/i18n.ts diff --git a/packages/react/src/models/jwt-verify-options.ts b/packages/__legacy__/react/src/models/jwt-verify-options.ts similarity index 100% rename from packages/react/src/models/jwt-verify-options.ts rename to packages/__legacy__/react/src/models/jwt-verify-options.ts diff --git a/packages/react/src/models/login-options-box-props.ts b/packages/__legacy__/react/src/models/login-options-box-props.ts similarity index 100% rename from packages/react/src/models/login-options-box-props.ts rename to packages/__legacy__/react/src/models/login-options-box-props.ts diff --git a/packages/react/src/models/public-models.ts b/packages/__legacy__/react/src/models/public-models.ts similarity index 100% rename from packages/react/src/models/public-models.ts rename to packages/__legacy__/react/src/models/public-models.ts diff --git a/packages/react/src/models/sign-in.ts b/packages/__legacy__/react/src/models/sign-in.ts similarity index 100% rename from packages/react/src/models/sign-in.ts rename to packages/__legacy__/react/src/models/sign-in.ts diff --git a/packages/react/src/models/signed-props.ts b/packages/__legacy__/react/src/models/signed-props.ts similarity index 100% rename from packages/react/src/models/signed-props.ts rename to packages/__legacy__/react/src/models/signed-props.ts diff --git a/packages/react/src/models/totp-props.ts b/packages/__legacy__/react/src/models/totp-props.ts similarity index 100% rename from packages/react/src/models/totp-props.ts rename to packages/__legacy__/react/src/models/totp-props.ts diff --git a/packages/react/src/models/use-authentication.ts b/packages/__legacy__/react/src/models/use-authentication.ts similarity index 100% rename from packages/react/src/models/use-authentication.ts rename to packages/__legacy__/react/src/models/use-authentication.ts diff --git a/packages/react/src/models/use-config.ts b/packages/__legacy__/react/src/models/use-config.ts similarity index 100% rename from packages/react/src/models/use-config.ts rename to packages/__legacy__/react/src/models/use-config.ts diff --git a/packages/react/src/models/use-on.ts b/packages/__legacy__/react/src/models/use-on.ts similarity index 100% rename from packages/react/src/models/use-on.ts rename to packages/__legacy__/react/src/models/use-on.ts diff --git a/packages/react/src/models/use-translations.ts b/packages/__legacy__/react/src/models/use-translations.ts similarity index 100% rename from packages/react/src/models/use-translations.ts rename to packages/__legacy__/react/src/models/use-translations.ts diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignIn/SignIn.tsx b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignIn/SignIn.tsx similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignIn/SignIn.tsx rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignIn/SignIn.tsx diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignIn/sign-in.scss b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignIn/sign-in.scss similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignIn/sign-in.scss rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignIn/sign-in.scss diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInAlert/SignInAlert.tsx b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInAlert/SignInAlert.tsx similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignInAlert/SignInAlert.tsx rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInAlert/SignInAlert.tsx diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInAlert/sign-in-alert.scss b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInAlert/sign-in-alert.scss similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignInAlert/sign-in-alert.scss rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInAlert/sign-in-alert.scss diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInButton/SignInButton.tsx b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInButton/SignInButton.tsx similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignInButton/SignInButton.tsx rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInButton/SignInButton.tsx diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInButton/sign-in-button.scss b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInButton/sign-in-button.scss similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignInButton/sign-in-button.scss rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInButton/sign-in-button.scss diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInDivider/SignInDivider.tsx b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInDivider/SignInDivider.tsx similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignInDivider/SignInDivider.tsx rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInDivider/SignInDivider.tsx diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInDivider/sign-in-divider.scss b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInDivider/sign-in-divider.scss similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignInDivider/sign-in-divider.scss rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInDivider/sign-in-divider.scss diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInFooter/SignInFooter.tsx b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInFooter/SignInFooter.tsx similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignInFooter/SignInFooter.tsx rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInFooter/SignInFooter.tsx diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInFooter/sign-in-footer.scss b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInFooter/sign-in-footer.scss similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignInFooter/sign-in-footer.scss rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInFooter/sign-in-footer.scss diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInImage/SignInImage.tsx b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInImage/SignInImage.tsx similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignInImage/SignInImage.tsx rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInImage/SignInImage.tsx diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInImage/sign-in-image.scss b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInImage/sign-in-image.scss similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignInImage/sign-in-image.scss rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInImage/sign-in-image.scss diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInLink/SignInLink.tsx b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInLink/SignInLink.tsx similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignInLink/SignInLink.tsx rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInLink/SignInLink.tsx diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInPaper/SignInPaper.tsx b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInPaper/SignInPaper.tsx similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignInPaper/SignInPaper.tsx rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInPaper/SignInPaper.tsx diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInPaper/sign-in-paper.scss b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInPaper/sign-in-paper.scss similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignInPaper/sign-in-paper.scss rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInPaper/sign-in-paper.scss diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInPinInput/SignInPinInput.tsx b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInPinInput/SignInPinInput.tsx similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignInPinInput/SignInPinInput.tsx rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInPinInput/SignInPinInput.tsx diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInPinInput/sign-in-pin-input.scss b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInPinInput/sign-in-pin-input.scss similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignInPinInput/sign-in-pin-input.scss rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInPinInput/sign-in-pin-input.scss diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInTextField/SignInTextField.tsx b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInTextField/SignInTextField.tsx similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignInTextField/SignInTextField.tsx rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInTextField/SignInTextField.tsx diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInTextField/sign-in-text-field.scss b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInTextField/sign-in-text-field.scss similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignInTextField/sign-in-text-field.scss rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInTextField/sign-in-text-field.scss diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInTypography/SignInTypography.tsx b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInTypography/SignInTypography.tsx similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignInTypography/SignInTypography.tsx rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInTypography/SignInTypography.tsx diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInTypography/sign-in-typography.scss b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInTypography/sign-in-typography.scss similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/SignInTypography/sign-in-typography.scss rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/SignInTypography/sign-in-typography.scss diff --git a/packages/react/src/oxygen-ui-react-auth-components/index.ts b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/index.ts similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/index.ts rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/index.ts diff --git a/packages/react/src/oxygen-ui-react-auth-components/models/component.ts b/packages/__legacy__/react/src/oxygen-ui-react-auth-components/models/component.ts similarity index 100% rename from packages/react/src/oxygen-ui-react-auth-components/models/component.ts rename to packages/__legacy__/react/src/oxygen-ui-react-auth-components/models/component.ts diff --git a/packages/__legacy__/react/src/providers/AsgardeoProvider.tsx b/packages/__legacy__/react/src/providers/AsgardeoProvider.tsx new file mode 100644 index 000000000..0400cee9a --- /dev/null +++ b/packages/__legacy__/react/src/providers/AsgardeoProvider.tsx @@ -0,0 +1,187 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + AuthApiResponse, + AuthClient, + Crypto, + MeAPIResponse, + Store, + UIAuthClient, + getProfileInformation, +} from '@asgardeo/js'; +import {FC, PropsWithChildren, useCallback, useEffect, useMemo, useRef, useState} from 'react'; +import BrandingPreferenceProvider from './BrandingPreferenceProvider'; +import I18nProvider from './I18nProvider'; +import AsgardeoContext from '../contexts/asgardeo-context'; +import AsgardeoProviderProps from '../models/asgardeo-provider-props'; +import AuthContext from '../models/auth-context'; +import SPACryptoUtils from '../utils/crypto-utils'; +import SessionStore from '../utils/session-store'; + +/** + * `AsgardeoProvider` is a component that provides an Asgardeo context to all its children. + * It takes an object of type `AsgardeProviderProps` as props, which includes the children to render, + * a configuration object, a store instance, and a branding object. + * + * @param {PropsWithChildren} props - The properties passed to the component. + * @param {ReactNode} props.children - The children to render inside the provider. + * @param {Config} props.config - The configuration object for the Asgardeo context. + * @param {Store} [props.store] - An optional store instance. If not provided, a new SessionStore will be created. + * @param {Branding} props.branding - The branding object for the Asgardeo context. + * + * @returns {ReactElement} A React element that provides the Asgardeo context to all its children. + */ +const AsgardeoProvider: FC> = ( + props: PropsWithChildren, +) => { + const {children, config, store, branding} = props; + + const [accessToken, setAccessToken] = useState(''); + const [isAuthenticated, setIsAuthenticated] = useState(); + const [user, setUser] = useState(); + const [isBrandingLoading, setIsBrandingLoading] = useState(true); + const [isTextLoading, setIsTextLoading] = useState(true); + const [isAuthLoading, setIsAuthLoading] = useState(false); + const [isComponentLoading, setIsComponentLoading] = useState(true); + const [authResponse, setAuthResponse] = useState(); + const [username, setUsername] = useState(''); + + const onSignInRef: React.MutableRefObject = useRef(); + const onSignOutRef: React.MutableRefObject = useRef(); + + const setOnSignIn: (newOnSignIn: Function) => void = useCallback( + (newOnSignIn: Function): void => { + onSignInRef.current = newOnSignIn; + }, + [], // Add any dependencies here... + ); + + const setOnSignOut: (newOnSignOut: Function) => void = useCallback( + (newOnSignOut: Function): void => { + onSignOutRef.current = newOnSignOut; + }, + [], // Add any dependencies here... + ); + + const storeInstance: Store = store || new SessionStore(); + + const spaUtils: Crypto = new SPACryptoUtils(); + + const authClient: UIAuthClient = AuthClient.getInstance(config, storeInstance, spaUtils); + + /** + * Sets the authentication status and access token. + */ + const setAuthentication: () => void = useCallback((): void => { + authClient.isAuthenticated().then((isAuth: boolean) => { + setIsAuthenticated(isAuth); + + if (isAuth) { + authClient.getAccessToken().then((accessTokenFromClient: string) => { + if (accessTokenFromClient) { + setAccessToken(accessTokenFromClient); + + getProfileInformation().then((response: MeAPIResponse) => { + setUser(response); + }); + + if (onSignInRef.current) { + onSignInRef.current(); + } + } + }); + } + }); + }, [authClient]); + + useEffect(() => { + setAuthentication(); + + /** + * This script is added so that the popup window can send the code and state to the parent window + */ + const url: URL = new URL(window.location.href); + if (url.searchParams.has('code') && url.searchParams.has('state')) { + const code: string = url.searchParams.get('code'); + const state: string = url.searchParams.get('state'); + + /** + * Send the 'code' and 'state' to the parent window and close the current window (popup) + */ + window.opener.postMessage({code, state}, config.signInRedirectURL); + window.close(); + } + }, [config.signInRedirectURL, setAuthentication]); + + const value: AuthContext = useMemo( + () => ({ + accessToken, + authResponse, + config, + isAuthLoading, + isAuthenticated, + isBrandingLoading, + isComponentLoading, + isGlobalLoading: isAuthLoading || isBrandingLoading || isComponentLoading || isTextLoading, + isTextLoading, + onSignOutRef, + setAuthResponse, + setAuthentication, + setIsAuthLoading, + setIsBrandingLoading, + setIsComponentLoading, + setIsTextLoading, + setOnSignIn, + setOnSignOut, + setUsername, + user, + username, + }), + [ + accessToken, + authResponse, + config, + isAuthLoading, + isAuthenticated, + isBrandingLoading, + isComponentLoading, + isTextLoading, + setAuthResponse, + setAuthentication, + setIsComponentLoading, + setOnSignIn, + setOnSignOut, + setUsername, + user, + username, + ], + ); + + return ( + + + + {children} + + + + ); +}; + +export default AsgardeoProvider; diff --git a/packages/react/src/providers/BrandingPreferenceProvider.tsx b/packages/__legacy__/react/src/providers/BrandingPreferenceProvider.tsx similarity index 100% rename from packages/react/src/providers/BrandingPreferenceProvider.tsx rename to packages/__legacy__/react/src/providers/BrandingPreferenceProvider.tsx diff --git a/packages/react/src/providers/I18nProvider.tsx b/packages/__legacy__/react/src/providers/I18nProvider.tsx similarity index 100% rename from packages/react/src/providers/I18nProvider.tsx rename to packages/__legacy__/react/src/providers/I18nProvider.tsx diff --git a/packages/react/src/theme/generate-theme-sign-in.ts b/packages/__legacy__/react/src/theme/generate-theme-sign-in.ts similarity index 100% rename from packages/react/src/theme/generate-theme-sign-in.ts rename to packages/__legacy__/react/src/theme/generate-theme-sign-in.ts diff --git a/packages/react/src/theme/generate-theme.ts b/packages/__legacy__/react/src/theme/generate-theme.ts similarity index 100% rename from packages/react/src/theme/generate-theme.ts rename to packages/__legacy__/react/src/theme/generate-theme.ts diff --git a/packages/react/src/utils/crypto-utils.ts b/packages/__legacy__/react/src/utils/crypto-utils.ts similarity index 94% rename from packages/react/src/utils/crypto-utils.ts rename to packages/__legacy__/react/src/utils/crypto-utils.ts index 9612bdd5d..566756560 100644 --- a/packages/react/src/utils/crypto-utils.ts +++ b/packages/__legacy__/react/src/utils/crypto-utils.ts @@ -17,14 +17,14 @@ */ import {Buffer} from 'buffer'; -import {CryptoUtils, JWKInterface, AsgardeoUIException} from '@asgardeo/js'; +import {Crypto, JWKInterface, AsgardeoUIException} from '@asgardeo/js'; import base64url from 'base64url'; import sha256 from 'fast-sha256'; import {createLocalJWKSet, jwtVerify} from 'jose'; import randombytes from 'randombytes'; import JwtVerifyOptions from '../models/jwt-verify-options'; -export default class SPACryptoUtils implements CryptoUtils { +export default class SPACryptoUtils implements Crypto { /** * Get URL encoded string. * diff --git a/packages/react/src/utils/session-store.ts b/packages/__legacy__/react/src/utils/session-store.ts similarity index 100% rename from packages/react/src/utils/session-store.ts rename to packages/__legacy__/react/src/utils/session-store.ts diff --git a/packages/react/stylelint.config.cjs b/packages/__legacy__/react/stylelint.config.cjs similarity index 100% rename from packages/react/stylelint.config.cjs rename to packages/__legacy__/react/stylelint.config.cjs diff --git a/packages/__legacy__/react/tsconfig.eslint.json b/packages/__legacy__/react/tsconfig.eslint.json new file mode 100644 index 000000000..bdaa69d4b --- /dev/null +++ b/packages/__legacy__/react/tsconfig.eslint.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "ESNext", + "types": ["jest", "node"] + }, + "include": [ + "**/*.cjs", + "**/*.js", + "**/*.jsx", + "**/*.ts", + "**/*.tsx", + ] + } diff --git a/packages/__legacy__/react/tsconfig.json b/packages/__legacy__/react/tsconfig.json new file mode 100644 index 000000000..cb627bf60 --- /dev/null +++ b/packages/__legacy__/react/tsconfig.json @@ -0,0 +1,35 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "jsx": "react-jsx", + "target": "es2016", + "module": "ESNext", + "emitDecoratorMetadata": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "forceConsistentCasingInFileNames": true, + "strict": false, + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "allowJs": true, + "allowSyntheticDefaultImports": true, + "declaration": true, + "declarationDir": "dist/types", + "outDir": "dist", + "moduleResolution": "node", + "importHelpers": true, + "resolveJsonModule": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + }, + "include": [], + "files": [], + "exclude": ["node_modules", "tmp"], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ] +} diff --git a/packages/__legacy__/react/tsconfig.lib.json b/packages/__legacy__/react/tsconfig.lib.json new file mode 100644 index 000000000..7f9476b9b --- /dev/null +++ b/packages/__legacy__/react/tsconfig.lib.json @@ -0,0 +1,26 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "declaration": true, + "outDir": "dist", + "declarationDir": "types", + "types": ["node"], + "emitDeclarationOnly": true + }, + "files": [], + "exclude": [ + "test-configs", + "jest.config.ts", + "**/*.spec.ts", + "**/*.test.ts", + "**/*.spec.tsx", + "**/*.test.tsx", + "**/*.spec.js", + "**/*.test.js", + "**/*.spec.jsx", + "**/*.test.jsx", + "scripts", + "dist" + ], + "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx", "rollup.config.cjs", "declarations.d.ts"] + } diff --git a/packages/browser/.editorconfig b/packages/browser/.editorconfig new file mode 100644 index 000000000..1b3ce07de --- /dev/null +++ b/packages/browser/.editorconfig @@ -0,0 +1 @@ +../../.editorconfig \ No newline at end of file diff --git a/packages/browser/.eslintignore b/packages/browser/.eslintignore new file mode 100644 index 000000000..177586b6b --- /dev/null +++ b/packages/browser/.eslintignore @@ -0,0 +1,4 @@ +/dist +/build +/node_modules +/coverage \ No newline at end of file diff --git a/packages/browser/.eslintrc.cjs b/packages/browser/.eslintrc.cjs new file mode 100644 index 000000000..2676ca816 --- /dev/null +++ b/packages/browser/.eslintrc.cjs @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const path = require('path'); + +module.exports = { + env: { + es6: true, + node: true, + }, + extends: [ + 'plugin:@wso2/typescript', + 'plugin:@wso2/strict', + 'plugin:@wso2/internal', + 'plugin:@wso2/jest', + 'plugin:@wso2/prettier', + ], + parserOptions: { + ecmaVersion: 2018, + project: [path.resolve(__dirname, 'tsconfig.eslint.json')], + }, + plugins: ['@wso2'], +}; diff --git a/packages/browser/.gitignore b/packages/browser/.gitignore new file mode 100644 index 000000000..c6bba5913 --- /dev/null +++ b/packages/browser/.gitignore @@ -0,0 +1,130 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* diff --git a/packages/browser/.prettierignore b/packages/browser/.prettierignore new file mode 100644 index 000000000..99b0b518a --- /dev/null +++ b/packages/browser/.prettierignore @@ -0,0 +1,4 @@ +/dist +/build +/node_modules +/coverage diff --git a/packages/browser/README.md b/packages/browser/README.md new file mode 100644 index 000000000..5f334aeb0 --- /dev/null +++ b/packages/browser/README.md @@ -0,0 +1,48 @@ +

+

@asgardeo/browser

+

+

Browser-based SDK for Asgardeo

+
+ npm (scoped) + npm + License +
+ +## Installation + +```bash +# Using npm +npm install @asgardeo/browser + +# or using pnpm +pnpm add @asgardeo/browser + +# or using yarn +yarn add @asgardeo/browser +``` + +## Quick Start + +```javascript +import { AsgardeoAuthClient } from "@asgardeo/browser"; + +// Initialize the auth client +const authClient = new AsgardeoAuthClient({ + signInRedirectURL: "https://localhost:3000", + clientID: "", + baseUrl: "https://api.asgardeo.io/t/" +}); + +// Sign in +authClient.signIn(); + +// Get user info after authentication +const userInfo = await authClient.getBasicUserInfo(); + +// Sign out +authClient.signOut(); +``` + +## License + +Apache-2.0 diff --git a/packages/browser/esbuild.config.mjs b/packages/browser/esbuild.config.mjs new file mode 100644 index 000000000..244371280 --- /dev/null +++ b/packages/browser/esbuild.config.mjs @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { readFileSync } from 'fs'; +import * as esbuild from 'esbuild'; +import { createRequire } from 'module'; +import { fileURLToPath } from 'url'; + +const require = createRequire(import.meta.url); +const pkg = JSON.parse(readFileSync('./package.json', 'utf8')); + +// Get dependencies excluding crypto-related ones that need to be bundled +const externalDeps = [...Object.keys(pkg.dependencies || {}), ...Object.keys(pkg.peerDependencies || {})] + .filter(dep => !['crypto-browserify', 'randombytes', 'buffer'].includes(dep)); + +// Plugin to alias crypto and buffer modules +const polyfillPlugin = { + name: 'polyfill-plugin', + setup(build) { + // Crypto polyfill + build.onResolve({ filter: /^crypto$/ }, () => ({ + path: require.resolve('crypto-browserify') + })); + + // Buffer polyfill + build.onResolve({ filter: /^buffer$/ }, () => ({ + path: require.resolve('buffer/') + })); + } +}; + +const commonOptions = { + bundle: true, + entryPoints: ['src/index.ts'], + external: externalDeps, + platform: 'browser', + target: ['es2020'], + define: { + global: 'globalThis', // Required by crypto-browserify + 'process.env.NODE_DEBUG': 'false', + 'process.version': '"16.0.0"', + 'process.browser': 'true' + }, + banner: { + js: ` + import { Buffer } from 'buffer/'; + if (typeof window !== 'undefined' && !window.Buffer) { + window.Buffer = Buffer; + } + ` + }, + footer: { + js: ` + if (typeof window !== 'undefined' && !window.Buffer) { + window.Buffer = require('buffer/').Buffer; + } + ` + }, + plugins: [polyfillPlugin] +}; + +await esbuild.build({ + ...commonOptions, + format: 'esm', + outfile: 'dist/index.js', + sourcemap: true +}); + +await esbuild.build({ + ...commonOptions, + format: 'cjs', + outfile: 'dist/cjs/index.js', + sourcemap: true +}); diff --git a/packages/browser/package.json b/packages/browser/package.json new file mode 100644 index 000000000..edb5091fe --- /dev/null +++ b/packages/browser/package.json @@ -0,0 +1,76 @@ +{ + "name": "@asgardeo/browser", + "version": "0.0.0", + "description": "Browser-specific implementation of Asgardeo JavaScript SDK.", + "keywords": [ + "asgardeo", + "browser", + "spa" + ], + "homepage": "https://github.com/asgardeo/javascript/tree/main/packages/browser#readme", + "bugs": { + "url": "https://github.com/asgardeo/javascript/issues" + }, + "author": "WSO2", + "license": "Apache-2.0", + "type": "module", + "main": "dist/cjs/index.js", + "module": "dist/index.js", + "exports": { + "import": "./dist/index.js", + "require": "./dist/cjs/index.js" + }, + "files": [ + "dist", + "README.md", + "LICENSE" + ], + "types": "dist/index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/asgardeo/javascript", + "directory": "packages/browser" + }, + "scripts": { + "build": "pnpm clean && node esbuild.config.mjs && tsc -p tsconfig.lib.json --emitDeclarationOnly --outDir dist", + "clean": "rimraf dist", + "fix:lint": "eslint . --ext .js,.jsx,.ts,.tsx,.cjs,.mjs", + "lint": "eslint . --ext .js,.jsx,.ts,.tsx,.cjs,.mjs", + "test": "vitest", + "test:browser": "vitest --workspace=vitest.workspace.ts", + "typecheck": "tsc -p tsconfig.lib.json" + }, + "devDependencies": { + "@testing-library/dom": "^10.4.0", + "@types/node": "^22.15.3", + "@vitest/browser": "^3.1.3", + "@wso2/eslint-plugin": "catalog:", + "@wso2/prettier-config": "catalog:", + "esbuild": "^0.25.4", + "esbuild-plugins-node-modules-polyfill": "^1.7.0", + "eslint": "8.57.0", + "playwright": "^1.52.0", + "prettier": "^2.6.2", + "rimraf": "^6.0.1", + "typescript": "~5.7.2", + "vitest": "^3.1.3" + }, + "dependencies": { + "@asgardeo/javascript": "workspace:^", + "axios": "^0.26.0", + "base64url": "^3.0.1", + "buffer": "^6.0.3", + "core-js": "^3.42.0", + "crypto-browserify": "^3.12.1", + "esbuild-plugin-polyfill-node": "^0.3.0", + "fast-sha256": "^1.3.0", + "jose": "^6.0.11", + "process": "^0.11.10", + "randombytes": "^2.1.0", + "stream-browserify": "^3.0.0", + "tslib": "^2.8.1" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/packages/browser/prettier.config.cjs b/packages/browser/prettier.config.cjs new file mode 100644 index 000000000..929b9b15f --- /dev/null +++ b/packages/browser/prettier.config.cjs @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +module.exports = require('@wso2/prettier-config'); diff --git a/packages/browser/src/AsgardeoBrowserClient.ts b/packages/browser/src/AsgardeoBrowserClient.ts new file mode 100644 index 000000000..ad3b13b28 --- /dev/null +++ b/packages/browser/src/AsgardeoBrowserClient.ts @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {AsgardeoJavaScriptClient} from '@asgardeo/javascript'; +import {AsgardeoBrowserConfig} from './models/config'; + +/** + * Base class for implementing Asgardeo in browser-based applications. + * This class provides the core functionality for managing user authentication and sessions. + * + * @typeParam T - Configuration type that extends AsgardeoBrowserConfig. + */ +abstract class AsgardeoBrowserClient extends AsgardeoJavaScriptClient {} + +export default AsgardeoBrowserClient; diff --git a/packages/browser/src/__legacy__/client.ts b/packages/browser/src/__legacy__/client.ts new file mode 100755 index 000000000..17a878d90 --- /dev/null +++ b/packages/browser/src/__legacy__/client.ts @@ -0,0 +1,1171 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + AsgardeoAuthClient, + AsgardeoAuthException, + AuthClientConfig, + BasicUserInfo, + IsomorphicCrypto, + CustomGrantConfig, + DataLayer, + IdTokenPayload, + FetchResponse, + OIDCEndpoints, +} from '@asgardeo/javascript'; +import WorkerFile from '../worker'; +import {MainThreadClient, WebWorkerClient} from './clients'; +import {Hooks, REFRESH_ACCESS_TOKEN_ERR0R} from './constants'; +import {AuthenticationHelper, SPAHelper} from './helpers'; +import {HttpClientInstance} from './http-client'; +import { + AuthSPAClientConfig, + LegacyConfig as Config, + HttpRequestConfig, + HttpResponse, + MainThreadClientConfig, + MainThreadClientInterface, + SignInConfig, + SignOutError, + WebWorkerClientConfig, + WebWorkerClientInterface, +} from './models'; +import {Storage} from './models/storage'; +import {SPAUtils} from './utils'; + +/** + * Default configurations. + */ +const DefaultConfig: Partial> = { + autoLogoutOnTokenRefreshError: true, + checkSessionInterval: 3, + clientHost: origin, + enableOIDCSessionManagement: false, + periodicTokenRefresh: false, + sessionRefreshInterval: 300, + storage: Storage.SessionStorage, +}; + +/** + * This class provides the necessary methods to implement authentication in a Single Page Application. + * + * @export + * @class AsgardeoSPAClient + */ +export class AsgardeoSPAClient { + protected static _instances: Map = new Map(); + protected _client: WebWorkerClientInterface | MainThreadClientInterface | undefined; + protected _storage: Storage | undefined; + protected _authHelper: typeof AuthenticationHelper = AuthenticationHelper; + protected _worker: new () => Worker = WorkerFile; + protected _initialized: boolean = false; + protected _startedInitialize: boolean = false; + protected _onSignInCallback: (response: BasicUserInfo) => void = () => null; + protected _onSignOutCallback: () => void = () => null; + protected _onSignOutFailedCallback: (error: SignOutError) => void = () => null; + protected _onEndUserSession: (response: any) => void = () => null; + protected _onInitialize: (response: boolean) => void = () => null; + protected _onCustomGrant: Map void> = new Map(); + protected _instanceID: number; + + protected constructor(id: number) { + this._instanceID = id; + } + + public instantiateAuthHelper(authHelper?: typeof AuthenticationHelper) { + if (authHelper) { + this._authHelper = authHelper; + } else { + this._authHelper = AuthenticationHelper; + } + } + + public instantiateWorker(worker: new () => Worker) { + if (worker) { + this._worker = worker; + } else { + this._worker = WorkerFile; + } + } + + /** + * This method specifies if the `AsgardeoSPAClient` has been initialized or not. + * + * @return {Promise} - Resolves to `true` if the client has been initialized. + * + * @memberof AsgardeoSPAClient + * + * @private + */ + private async _isInitialized(): Promise { + if (!this._startedInitialize) { + return false; + } + + let iterationToWait = 0; + + const sleep = (): Promise => { + return new Promise(resolve => setTimeout(resolve, 1)); + }; + + while (!this._initialized) { + if (iterationToWait === 1e4) { + // eslint-disable-next-line no-console + console.warn('It is taking longer than usual for the object to be initialized'); + } + await sleep(); + iterationToWait++; + } + + return true; + } + + /** + * This method checks if the SDK is initialized and the user is authenticated. + * + * @param validateAuthentication - should user's authenticated status be checked as part of validation + * + * @return {Promise} - A Promise that resolves with `true` if the SDK is initialized and the + * user is authenticated. + * + * @memberof AsgardeoSPAClient + * + * @private + */ + private async _validateMethod(validateAuthentication: boolean = true): Promise { + if (!(await this._isInitialized())) { + return Promise.reject( + new AsgardeoAuthException( + 'SPA-AUTH_CLIENT-VM-NF01', + 'The SDK is not initialized.', + 'The SDK must be initialized first.', + ), + ); + } + + if (validateAuthentication && !(await this.isAuthenticated())) { + return Promise.reject( + new AsgardeoAuthException( + 'SPA-AUTH_CLIENT-VM-IV02', + 'The user is not authenticated.', + 'The user must be authenticated first.', + ), + ); + } + + return true; + } + + /** + * This method returns the instance of the singleton class. + * If an ID is provided, it will return the instance with the given ID. + * If no ID is provided, it will return the default instance value 0. + * + * @return {AsgardeoSPAClient} - Returns the instance of the singleton class. + * + * @example + * ``` + * const auth = AsgardeoSPAClient.getInstance(); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#getinstance + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public static getInstance(id?: number): AsgardeoSPAClient | undefined { + if (id && this._instances?.get(id)) { + return this._instances.get(id); + } else if (!id && this._instances?.get(0)) { + return this._instances.get(0); + } + + if (id) { + this._instances.set(id, new AsgardeoSPAClient(id)); + + return this._instances.get(id); + } + + this._instances.set(0, new AsgardeoSPAClient(0)); + + return this._instances.get(0); + } + + /** + * This method initializes the `AsgardeoSPAClient` instance. + * + * @param {ConfigInterface} config The config object to initialize with. + * + * @return {Promise} - Resolves to `true` if initialization is successful. + * + * @example + * ``` + * auth.initialize({ + * signInRedirectURL: "http://localhost:3000/sign-in", + * clientID: "client ID", + * baseUrl: "https://api.asgardeo.io" + * }); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#initialize + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + + public async initialize( + config: AuthSPAClientConfig, + authHelper?: typeof AuthenticationHelper, + workerFile?: new () => Worker, + ): Promise { + this._storage = (config.storage as Storage) ?? Storage.SessionStorage; + this._initialized = false; + this._startedInitialize = true; + + authHelper && this.instantiateAuthHelper(authHelper); + workerFile && this.instantiateWorker(workerFile); + + const _config = await this._client?.getConfigData(); + + if (!(this._storage === Storage.WebWorker)) { + const mainThreadClientConfig = config as AuthClientConfig; + const defaultConfig = {...DefaultConfig} as Partial>; + const mergedConfig: AuthClientConfig = { + ...defaultConfig, + ...mainThreadClientConfig, + }; + + // If the client is not initialized, initialize it as usual. + // NOTE: With React 19 strict mode, the initialization logic runs twice, and there's an intermittent + // issue where the config object is not getting stored in the storage layer with Vite scaffolding. + // Hence, we need to check if the client is initialized but the config object is empty, and reinitialize. + // Tracker: https://github.com/asgardeo/asgardeo-auth-react-sdk/issues/240 + if (!this._client || (this._client && (!_config || Object.keys(_config)?.length === 0))) { + this._client = await MainThreadClient( + this._instanceID, + mergedConfig, + (authClient: AsgardeoAuthClient, spaHelper: SPAHelper) => { + return new this._authHelper(authClient, spaHelper); + }, + ); + } + + this._initialized = true; + + if (this._onInitialize) { + this._onInitialize(true); + } + + // Do not sign out the user if the autoLogoutOnTokenRefreshError is set to false. + if (!mergedConfig.autoLogoutOnTokenRefreshError) { + return Promise.resolve(true); + } + + window.addEventListener('message', event => { + if (event?.data?.type === REFRESH_ACCESS_TOKEN_ERR0R) { + this.signOut(); + } + }); + + return Promise.resolve(true); + } else { + // If the client is not initialized, initialize it as usual. + // NOTE: With React 19 strict mode, the initialization logic runs twice, and there's an intermittent + // issue where the config object is not getting stored in the storage layer with Vite scaffolding. + // Hence, we need to check if the client is initialized but the config object is empty, and reinitialize. + // Tracker: https://github.com/asgardeo/asgardeo-auth-react-sdk/issues/240 + if (!this._client || (this._client && (!_config || Object.keys(_config)?.length === 0))) { + const webWorkerClientConfig = config as AuthClientConfig; + this._client = (await WebWorkerClient( + this._instanceID, + { + ...DefaultConfig, + ...webWorkerClientConfig, + }, + this._worker, + (authClient: AsgardeoAuthClient, spaHelper: SPAHelper) => { + return new this._authHelper(authClient, spaHelper); + }, + )) as WebWorkerClientInterface; + + return this._client + .initialize() + .then(() => { + if (this._onInitialize) { + this._onInitialize(true); + } + this._initialized = true; + + return Promise.resolve(true); + }) + .catch(error => { + return Promise.reject(error); + }); + } + + return Promise.resolve(true); + } + } + + /** + * This method returns a Promise that resolves with the basic user information obtained from the ID token. + * + * @return {Promise} - A promise that resolves with the user information. + * + * @example + * ``` + * auth.getBasicUserInfo().then((response) => { + * // console.log(response); + * }).catch((error) => { + * // console.error(error); + * }); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#getuserinfo + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async getBasicUserInfo(): Promise { + await this._validateMethod(); + + return this._client?.getBasicUserInfo(); + } + + /** + * This method initiates the authentication flow. This should be called twice. + * 1. To initiate the authentication flow. + * 2. To obtain the access token after getting the authorization code. + * + * To satisfy the second condition, one of the two strategies mentioned below can be used: + * 1. Redirect the user back to the same login page that initiated the authentication flow. + * 2. Call the `signIn()` method in the page the user is redirected to after authentication. + * + * **To fire a callback function after signing in, use the `on()` method.** + * **To learn more about the `on()` method:** + * @see {@link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#on} + * + * @param {SignInConfig} config - The sign-in config. + * The `SignInConfig` object has these two attributes in addition to any custom key-value pairs. + * 1. fidp - Specifies the FIDP parameter that is used to take the user directly to an IdP login page. + * 2. forceInit: Specifies if the OIDC Provider Meta Data should be loaded again from the `well-known` + * endpoint. + * 3. Any other parameters that should be appended to the authorization request. + * @param {string} authorizationCode - The authorization code. (Optional) + * @param {string} sessionState - The session state. (Optional) + * @param {string} state - The state. (Optional) + * + * @return {Promise} - A promise that resolves with the user information. + * + * @example + * ``` + * auth.signIn(); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#signin + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async signIn( + config?: SignInConfig, + authorizationCode?: string, + sessionState?: string, + state?: string, + tokenRequestConfig?: { + params: Record; + }, + ): Promise { + await this._isInitialized(); + + // Discontinues the execution of this method if `config.callOnlyOnRedirect` is true and the `signIn` method + // is not being called on redirect. + if (!SPAUtils.canContinueSignIn(Boolean(config?.callOnlyOnRedirect), authorizationCode)) { + return undefined; + } + + delete config?.callOnlyOnRedirect; + + return this._client + ?.signIn(config, authorizationCode, sessionState, state, tokenRequestConfig) + .then((response: BasicUserInfo) => { + if (this._onSignInCallback) { + if (response.allowedScopes || response.displayName || response.email || response.username) { + this._onSignInCallback(response); + } + } + + return response; + }); + } + + /** + * This method allows you to sign in silently. + * First, this method sends a prompt none request to see if there is an active user session in the identity server. + * If there is one, then it requests the access token and stores it. Else, it returns false. + * + * If this method is to be called on page load and the `signIn` method is also to be called on page load, + * then it is advisable to call this method after the `signIn` call. + * + * @return {Promise} - A Promise that resolves with the user information after signing in + * or with `false` if the user is not signed in. + * + * @example + *``` + * auth.trySignInSilently() + *``` + */ + public async trySignInSilently( + additionalParams?: Record, + tokenRequestConfig?: {params: Record}, + ): Promise { + await this._isInitialized(); + + // checks if the `signIn` method has been called. + if (SPAUtils.wasSignInCalled()) { + return undefined; + } + + return this._client + ?.trySignInSilently(additionalParams, tokenRequestConfig) + .then((response: BasicUserInfo | boolean) => { + if (this._onSignInCallback && response) { + const basicUserInfo = response as BasicUserInfo; + if ( + basicUserInfo.allowedScopes || + basicUserInfo.displayName || + basicUserInfo.email || + basicUserInfo.username + ) { + this._onSignInCallback(basicUserInfo); + } + } + + return response; + }); + } + + /** + * This method initiates the sign-out flow. + * + * **To fire a callback function after signing out, use the `on()` method.** + * **To learn more about the `on()` method:** + * @see {@link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#on} + * + * @return {Promise} - Returns a promise that resolves with `true` if sign out is successful. + * + * @example + * ``` + * auth.signOut(); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#signout + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async signOut(): Promise { + await this._validateMethod(false); + + const signOutResponse = (await this._client?.signOut()) ?? false; + + return signOutResponse; + } + + /** + * This method sends an API request to a protected endpoint. + * The access token is automatically attached to the header of the request. + * This is the only way by which protected endpoints can be accessed + * when the web worker is used to store session information. + * + * @param {HttpRequestConfig} config - The config object containing attributes necessary to send a request. + * + * @return {Promise} - Returns a Promise that resolves with the response to the request. + * + * @example + * ``` + * const requestConfig = { + * headers: { + * "Accept": "application/json", + * "Access-Control-Allow-Origin": "https://api.asgardeo.io/myaccount", + * "Content-Type": "application/scim+json" + * }, + * method: "GET", + * url: "https://api.asgardeo.io/scim2/me" + * }; + * + * return auth.httpRequest(requestConfig) + * .then((response) => { + * // console.log(response); + * }) + * .catch((error) => { + * // console.error(error); + * }); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#httprequest + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async httpRequest(config: HttpRequestConfig): Promise { + await this._validateMethod(false); + + return this._client?.httpRequest(config); + } + + /** + * This method sends multiple API requests to a protected endpoint. + * The access token is automatically attached to the header of the request. + * This is the only way by which multiple requests can be sent to protected endpoints + * when the web worker is used to store session information. + * + * @param {HttpRequestConfig[]} config - The config object containing attributes necessary to send a request. + * + * @return {Promise} - Returns a Promise that resolves with the responses to the requests. + * + * @example + * ``` + * const requestConfig = { + * headers: { + * "Accept": "application/json", + * "Content-Type": "application/scim+json" + * }, + * method: "GET", + * url: "https://api.asgardeo.io/scim2/me" + * }; + * + * const requestConfig2 = { + * headers: { + * "Accept": "application/json", + * "Content-Type": "application/scim+json" + * }, + * method: "GET", + * url: "https://api.asgardeo.io/scim2/me" + * }; + * + * return auth.httpRequest([requestConfig, requestConfig2]) + * .then((responses) => { + * response.forEach((response)=>{ + * // console.log(response); + * }); + * }) + * .catch((error) => { + * // console.error(error); + * }); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#httprequestall + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async httpRequestAll(config: HttpRequestConfig[]): Promise { + await this._validateMethod(false); + + return this._client?.httpRequestAll(config); + } + + /** + * This method allows you to send a request with a custom grant. + * + * @param {CustomGrantRequestParams} config - The request parameters. + * + * @return {Promise | SignInResponse>} - A Promise that resolves with + * the value returned by the custom grant request. + * + * @example + * ``` + * auth.customGrant({ + * attachToken: false, + * data: { + * client_id: "{{clientId}}", + * grant_type: "account_switch", + * scope: "{{scope}}", + * token: "{{token}}", + * }, + * id: "account-switch", + * returnResponse: true, + * returnsSession: true, + * signInRequired: true + * }); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#customgrant + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async requestCustomGrant(config: CustomGrantConfig): Promise | BasicUserInfo | undefined> { + if (config.signInRequired) { + await this._validateMethod(); + } else { + await this._validateMethod(); + } + + if (!config.id) { + return Promise.reject( + new AsgardeoAuthException( + 'SPA-AUTH_CLIENT-RCG-NF01', + 'The custom grant request id not found.', + 'The id attribute of the custom grant config object passed as an argument should have a value.', + ), + ); + } + + const customGrantResponse = await this._client?.requestCustomGrant(config); + + const customGrantCallback = this._onCustomGrant.get(config.id); + customGrantCallback && customGrantCallback(this._onCustomGrant?.get(config.id)); + + return customGrantResponse; + } + + /** + * This method ends a user session. The access token is revoked and the session information is destroyed. + * + * **To fire a callback function after ending user session, use the `on()` method.** + * **To learn more about the `on()` method:** + * @see {@link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#on} + * + * @return {Promise} - A promise that resolves with `true` if the process is successful. + * + * @example + * ``` + * auth.endUserSession(); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#endusersession + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async revokeAccessToken(): Promise { + await this._validateMethod(); + + const revokeAccessToken = await this._client?.revokeAccessToken(); + this._onEndUserSession && (await this._onEndUserSession(revokeAccessToken)); + + return revokeAccessToken; + } + + /** + * This method returns a Promise that resolves with an object containing the service endpoints. + * + * @return {Promise { + * // console.log(endpoints); + * }).error((error) => { + * // console.error(error); + * }); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#getserviceendpoints + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async getOIDCServiceEndpoints(): Promise { + await this._isInitialized(); + + return this._client?.getOIDCServiceEndpoints(); + } + + /** + * This methods returns the Axios http client. + * + * @return {HttpClientInstance} - The Axios HTTP client. + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public getHttpClient(): HttpClientInstance { + if (this._client) { + if (this._storage !== Storage.WebWorker) { + const mainThreadClient = this._client as MainThreadClientInterface; + return mainThreadClient.getHttpClient(); + } + + throw new AsgardeoAuthException( + 'SPA-AUTH_CLIENT-GHC-IV01', + 'Http client cannot be returned.', + 'The http client cannot be returned when the storage type is set to webWorker.', + ); + } + + throw new AsgardeoAuthException( + 'SPA-AUTH_CLIENT-GHC-NF02', + 'The SDK is not initialized.', + 'The SDK has not been initialized yet. Initialize the SDK using the initialize method ' + + 'before calling this method.', + ); + } + + /** + * This method decodes the payload of the id token and returns it. + * + * @return {Promise} - A Promise that resolves with + * the decoded payload of the id token. + * + * @example + * ``` + * auth.getDecodedIDToken().then((response)=>{ + * // console.log(response); + * }).catch((error)=>{ + * // console.error(error); + * }); + * ``` + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#getdecodedidtoken + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async getDecodedIDToken(): Promise { + await this._validateMethod(); + + return this._client?.getDecodedIDToken(); + } + + /** + * This method returns the IsomorphicCrypto instance. + * + * @return {Promise} - A Promise that resolves with + * the IsomorphicCrypto instance. + * + * @example + * ``` + * auth.getCryptoHelper().then((response)=>{ + * // console.log(response); + * }).catch((error)=>{ + * // console.error(error); + * }); + * ``` + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#getCryptoHelper + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async getCryptoHelper(): Promise { + await this._validateMethod(); + + return this._client?.getCryptoHelper(); + } + + /** + * This method return the ID token. + * + * @return {Promise} - A Promise that resolves with the ID token. + * + * @example + * ``` + * const idToken = await auth.getIDToken(); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getIDToken + * + * @memberof AsgardeoAuthClient + * + * @preserve + */ + public async getIDToken(): Promise { + await this._validateMethod(); + + return this._client?.getIDToken(); + } + + /** + * This method return a Promise that resolves with the access token. + * + * **This method will not return the access token if the storage type is set to `webWorker`.** + * + * @return {Promise} - A Promise that resolves with the access token. + * + * @example + * ``` + * auth.getAccessToken().then((token) => { + * // console.log(token); + * }).catch((error) => { + * // console.error(error); + * }); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#getaccesstoken + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async getAccessToken(): Promise { + await this._validateMethod(); + + if (this._storage && [(Storage.WebWorker, Storage.BrowserMemory)].includes(this._storage)) { + return Promise.reject( + new AsgardeoAuthException( + 'SPA-AUTH_CLIENT-GAT-IV01', + 'The access token cannot be returned.', + 'The access token cannot be returned when the storage type is set to webWorker or browserMemory.', + ), + ); + } + const mainThreadClient = this._client as MainThreadClientInterface; + + return mainThreadClient.getAccessToken(); + } + + /** + * This method return a Promise that resolves with the idp access token. + * + * **This method will not return the access token if the storage type is set to `webWorker`.** + * + * @return {Promise} - A Promise that resolves with the idp access token. + * + * @example + * ``` + * auth.getIDPAccessToken().then((token) => { + * // console.log(token); + * }).catch((error) => { + * // console.error(error); + * }); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#getaccesstoken + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async getIDPAccessToken(): Promise { + await this._validateMethod(); + + if (this._storage && [(Storage.WebWorker, Storage.BrowserMemory)].includes(this._storage)) { + return Promise.reject( + new AsgardeoAuthException( + 'SPA-AUTH_CLIENT-GIAT-IV01', + 'The access token cannot be returned.', + 'The access token cannot be returned when the storage type is set to webWorker or browserMemory.', + ), + ); + } + const mainThreadClient = this._client as MainThreadClientInterface; + + return mainThreadClient.getAccessToken(); + } + + /** + * This method return a Promise that resolves with the data layer object. + * + * **This method will not return the data layer object, if the storage type is set to `webWorker`.** + * + * @return {Promise} - A Promise that resolves with the data layer object. + * + * @example + * ``` + * auth.getDataLayer().then((dataLayer) => { + * // console.log(dataLayer); + * }).catch((error) => { + * // console.error(error); + * }); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#getdatalayer + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async getDataLayer(): Promise> { + await this._validateMethod(); + + if (this._storage && [(Storage.WebWorker, Storage.BrowserMemory)].includes(this._storage)) { + return Promise.reject( + new AsgardeoAuthException( + 'SPA-AUTH_CLIENT-GDL-IV01', + 'The data layer cannot be returned.', + 'The data layer cannot be returned when the storage type is set to webWorker or browserMemory.', + ), + ); + } + const mainThreadClient = this._client as MainThreadClientInterface; + + return mainThreadClient.getDataLayer(); + } + + /** + * This method return a Promise that resolves with the config data stored in the storage. + * + * @return - A Promise that resolves with the config data. + * + * @example + * ``` + * auth.getConfigData().then((configData) => { + * // console.log(configData); + * }).catch((error) => { + * // console.error(error); + * }); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/main#getConfigData + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async getConfigData(): Promise< + AuthClientConfig | AuthClientConfig | undefined + > { + return this._client?.getConfigData(); + } + + /** + * This method refreshes the access token. + * + * @return {TokenResponseInterface} - A Promise that resolves with an object containing + * information about the refreshed access token. + * + * @example + * ``` + * auth.refreshToken().then((response)=>{ + * // console.log(response); + * }).catch((error)=>{ + * // console.error(error); + * }); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#refreshtoken + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async refreshAccessToken(): Promise { + await this._validateMethod(false); + + return this._client?.refreshAccessToken(); + } + + /** + * This method specifies if the user is authenticated or not. + * + * @return {Promise} - A Promise that resolves with `true` if the user is authenticated. + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async isAuthenticated(): Promise { + await this._isInitialized(); + + return this._client?.isAuthenticated(); + } + + /** + * This method specifies if there is an active session in the browser or not. + * + * @return {Promise} - A Promise that resolves with `true` if there is a session. + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async isSessionActive(): Promise { + await this._isInitialized(); + + if (this._storage && [(Storage.WebWorker, Storage.BrowserMemory)].includes(this._storage)) { + return Promise.reject( + new AsgardeoAuthException( + 'SPA-AUTH_CLIENT-ISA-IV01', + 'The active session cannot be returned.', + 'The active session cannot be returned when the storage type is set to webWorker ' + 'or browserMemory.', + ), + ); + } + const mainThreadClient = this._client as MainThreadClientInterface; + + return mainThreadClient?.isSessionActive(); + } + + /** + * This method attaches a callback function to an event hook that fires the callback when the event happens. + * + * @param {Hooks.CustomGrant} hook - The name of the hook. + * @param {(response?: any) => void} callback - The callback function. + * @param {string} id (optional) - The id of the hook. This is used when multiple custom grants are used. + * + * @example + * ``` + * auth.on("sign-in", (response)=>{ + * // console.log(response); + * }); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#on + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async on(hook: Hooks.CustomGrant, callback: (response?: any) => void, id: string): Promise; + public async on(hook: Exclude, callback: (response?: any) => void): Promise; + public async on(hook: Hooks, callback: (response?: any) => void | Promise, id?: string): Promise { + await this._isInitialized(); + if (callback && typeof callback === 'function') { + switch (hook) { + case Hooks.SignIn: + this._onSignInCallback = callback; + break; + case Hooks.SignOut: + this._onSignOutCallback = callback; + if (await SPAUtils.isSignOutSuccessful()) { + this._onSignOutCallback(); + } + break; + case Hooks.RevokeAccessToken: + this._onEndUserSession = callback; + break; + case Hooks.Initialize: + this._onInitialize = callback; + break; + case Hooks.HttpRequestError: + this._client?.setHttpRequestErrorCallback(callback); + break; + case Hooks.HttpRequestFinish: + this._client?.setHttpRequestFinishCallback(callback); + break; + case Hooks.HttpRequestStart: + this._client?.setHttpRequestStartCallback(callback); + break; + case Hooks.HttpRequestSuccess: + this._client?.setHttpRequestSuccessCallback(callback); + break; + case Hooks.CustomGrant: + id && this._onCustomGrant.set(id, callback); + break; + case Hooks.SignOutFailed: { + this._onSignOutFailedCallback = callback; + const signOutFail: boolean | SignOutError = SPAUtils.didSignOutFail(); + + if (signOutFail) { + this._onSignOutFailedCallback(signOutFail as SignOutError); + } + break; + } + default: + throw new AsgardeoAuthException('SPA-AUTH_CLIENT-ON-IV01', 'Invalid hook.', 'The provided hook is invalid.'); + } + } else { + throw new AsgardeoAuthException( + 'SPA-AUTH_CLIENT-ON-IV02', + 'Invalid callback function.', + 'The provided callback function is invalid.', + ); + } + } + + /** + * This method enables callback functions attached to the http client. + * + * @return {Promise} - A promise that resolves with True. + * + * @example + * ``` + * auth.enableHttpHandler(); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#enableHttpHandler + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async enableHttpHandler(): Promise { + await this._isInitialized(); + + return this._client?.enableHttpHandler(); + } + + /** + * This method disables callback functions attached to the http client. + * + * @return {Promise} - A promise that resolves with True. + * + * @example + * ``` + * auth.disableHttpHandler(); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master#disableHttpHandler + * + * @memberof AsgardeoSPAClient + * + * @preserve + */ + public async disableHttpHandler(): Promise { + await this._isInitialized(); + + return this._client?.disableHttpHandler(); + } + + /** + * This method updates the configuration that was passed into the constructor when instantiating this class. + * + * @param {Partial>} config - A config object to update the SDK configurations with. + * + * @example + * ``` + * const config = { + * signInRedirectURL: "http://localhost:3000/sign-in", + * clientID: "client ID", + * baseUrl: "https://api.asgardeo.io" + * } + * const auth.updateConfig(config); + * ``` + * @link https://github.com/asgardeo/asgardeo-auth-spa-sdk/tree/master/lib#updateConfig + * + * @memberof AsgardeoAuthClient + * + * @preserve + */ + public async updateConfig(config: Partial>): Promise { + await this._isInitialized(); + if (this._storage === Storage.WebWorker) { + const client = this._client as WebWorkerClientInterface; + await client.updateConfig(config as Partial>); + } else { + const client = this._client as WebWorkerClientInterface; + await client.updateConfig(config as Partial>); + } + + return; + } +} diff --git a/packages/browser/src/__legacy__/clients/index.ts b/packages/browser/src/__legacy__/clients/index.ts new file mode 100644 index 000000000..6148f41d4 --- /dev/null +++ b/packages/browser/src/__legacy__/clients/index.ts @@ -0,0 +1,20 @@ +/** +* Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +export * from "./main-thread-client"; +export * from "./web-worker-client"; diff --git a/packages/browser/src/__legacy__/clients/main-thread-client.ts b/packages/browser/src/__legacy__/clients/main-thread-client.ts new file mode 100755 index 000000000..639ac72a6 --- /dev/null +++ b/packages/browser/src/__legacy__/clients/main-thread-client.ts @@ -0,0 +1,462 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + AsgardeoAuthClient, + AuthClientConfig, + BasicUserInfo, + IsomorphicCrypto, + DataLayer, + IdTokenPayload, + FetchResponse, + GetAuthURLConfig, + OIDCEndpoints, + ResponseMode, + OIDCRequestConstants, + SessionData, + Store, + extractPkceStorageKeyFromState, +} from '@asgardeo/javascript'; +import {SILENT_SIGN_IN_STATE, TOKEN_REQUEST_CONFIG_KEY} from '../constants'; +import {AuthenticationHelper, SPAHelper, SessionManagementHelper} from '../helpers'; +import {HttpClient, HttpClientInstance} from '../http-client'; +import {HttpError, HttpRequestConfig, HttpResponse, MainThreadClientConfig, MainThreadClientInterface} from '../models'; +import {SPACustomGrantConfig} from '../models/request-custom-grant'; +import {Storage} from '../models/storage'; +import {LocalStore, MemoryStore, SessionStore} from '../stores'; +import {SPAUtils} from '../utils'; +import {SPACryptoUtils} from '../utils/crypto-utils'; + +const initiateStore = (store: Storage | undefined): Store => { + switch (store) { + case Storage.LocalStorage: + return new LocalStore(); + case Storage.SessionStorage: + return new SessionStore(); + case Storage.BrowserMemory: + return new MemoryStore(); + default: + return new SessionStore(); + } +}; + +export const MainThreadClient = async ( + instanceID: number, + config: AuthClientConfig, + getAuthHelper: ( + authClient: AsgardeoAuthClient, + spaHelper: SPAHelper, + ) => AuthenticationHelper, +): Promise => { + const _store: Store = initiateStore(config.storage as Storage); + const _cryptoUtils: SPACryptoUtils = new SPACryptoUtils(); + const _authenticationClient = new AsgardeoAuthClient(); + await _authenticationClient.initialize(config, _store, _cryptoUtils, instanceID); + + const _spaHelper = new SPAHelper(_authenticationClient); + const _dataLayer = _authenticationClient.getDataLayer(); + const _sessionManagementHelper = await SessionManagementHelper( + async () => { + return _authenticationClient.getSignOutURL(); + }, + (config.storage as Storage) ?? Storage.SessionStorage, + (sessionState: string) => + _dataLayer.setSessionDataParameter( + OIDCRequestConstants.Params.SESSION_STATE as keyof SessionData, + sessionState ?? '', + ), + ); + + const _authenticationHelper = getAuthHelper(_authenticationClient, _spaHelper); + + let _getSignOutURLFromSessionStorage: boolean = false; + + const _httpClient: HttpClientInstance = HttpClient.getInstance(); + let _isHttpHandlerEnabled: boolean = true; + let _httpErrorCallback: (error: HttpError) => void | Promise; + let _httpFinishCallback: () => void; + + const attachToken = async (request: HttpRequestConfig): Promise => { + await _authenticationHelper.attachTokenToRequestConfig(request); + }; + + _httpClient?.init && (await _httpClient.init(true, attachToken)); + + const setHttpRequestStartCallback = (callback: () => void): void => { + _httpClient?.setHttpRequestStartCallback && _httpClient.setHttpRequestStartCallback(callback); + }; + + const setHttpRequestSuccessCallback = (callback: (response: HttpResponse) => void): void => { + _httpClient?.setHttpRequestSuccessCallback && _httpClient.setHttpRequestSuccessCallback(callback); + }; + + const setHttpRequestFinishCallback = (callback: () => void): void => { + _httpClient?.setHttpRequestFinishCallback && _httpClient.setHttpRequestFinishCallback(callback); + }; + + const setHttpRequestErrorCallback = (callback: (error: HttpError) => void | Promise): void => { + _httpErrorCallback = callback; + }; + + const httpRequest = async (requestConfig: HttpRequestConfig): Promise => { + return await _authenticationHelper.httpRequest( + _httpClient, + requestConfig, + _isHttpHandlerEnabled, + _httpErrorCallback, + _httpFinishCallback, + ); + }; + + const httpRequestAll = async (requestConfigs: HttpRequestConfig[]): Promise => { + return await _authenticationHelper.httpRequestAll( + requestConfigs, + _httpClient, + _isHttpHandlerEnabled, + _httpErrorCallback, + _httpFinishCallback, + ); + }; + + const getHttpClient = (): HttpClientInstance => { + return _httpClient; + }; + + const enableHttpHandler = (): boolean => { + _authenticationHelper.enableHttpHandler(_httpClient); + _isHttpHandlerEnabled = true; + + return true; + }; + + const disableHttpHandler = (): boolean => { + _authenticationHelper.disableHttpHandler(_httpClient); + _isHttpHandlerEnabled = false; + + return true; + }; + + const checkSession = async (): Promise => { + const oidcEndpoints: OIDCEndpoints = await _authenticationClient.getOIDCServiceEndpoints() as OIDCEndpoints; + const config = await _dataLayer.getConfigData(); + + _authenticationHelper.initializeSessionManger( + config, + oidcEndpoints, + async () => (await _authenticationClient.getBasicUserInfo()).sessionState, + async (params?: GetAuthURLConfig): Promise => _authenticationClient.getAuthorizationURL(params), + _sessionManagementHelper, + ); + }; + + const shouldStopAuthn = async (): Promise => { + return await _sessionManagementHelper.receivePromptNoneResponse(async (sessionState: string | null) => { + await _dataLayer.setSessionDataParameter( + OIDCRequestConstants.Params.SESSION_STATE as keyof SessionData, + sessionState ?? '', + ); + return; + }); + }; + + const setSessionStatus = async (sessionStatus: string): Promise => { + await _dataLayer.setSessionStatus(sessionStatus); + }; + + const signIn = async ( + signInConfig?: GetAuthURLConfig, + authorizationCode?: string, + sessionState?: string, + state?: string, + tokenRequestConfig?: { + params: Record; + }, + ): Promise => { + const basicUserInfo = await _authenticationHelper.handleSignIn(shouldStopAuthn, checkSession, undefined); + + if (basicUserInfo) { + return basicUserInfo; + } else { + let resolvedAuthorizationCode: string; + let resolvedSessionState: string; + let resolvedState: string; + let resolvedTokenRequestConfig: { + params: Record; + } = {params: {}}; + + if (config?.responseMode === ResponseMode.FormPost && authorizationCode) { + resolvedAuthorizationCode = authorizationCode; + resolvedSessionState = sessionState ?? ''; + resolvedState = state ?? ''; + } else { + resolvedAuthorizationCode = + new URL(window.location.href).searchParams.get(OIDCRequestConstants.Params.AUTHORIZATION_CODE) ?? ''; + resolvedSessionState = + new URL(window.location.href).searchParams.get(OIDCRequestConstants.Params.SESSION_STATE) ?? ''; + resolvedState = new URL(window.location.href).searchParams.get(OIDCRequestConstants.Params.STATE) ?? ''; + + SPAUtils.removeAuthorizationCode(); + } + + if (resolvedAuthorizationCode && resolvedState) { + setSessionStatus('true'); + const storedTokenRequestConfig = await _dataLayer.getTemporaryDataParameter(TOKEN_REQUEST_CONFIG_KEY); + if (storedTokenRequestConfig && typeof storedTokenRequestConfig === 'string') { + resolvedTokenRequestConfig = JSON.parse(storedTokenRequestConfig); + } + return requestAccessToken( + resolvedAuthorizationCode, + resolvedSessionState, + resolvedState, + resolvedTokenRequestConfig, + ); + } + + return _authenticationClient.getAuthorizationURL(signInConfig).then(async (url: string) => { + if (config.storage === Storage.BrowserMemory && config.enablePKCE) { + const pkceKey: string = extractPkceStorageKeyFromState(resolvedState); + + SPAUtils.setPKCE(pkceKey, (await _authenticationClient.getPKCECode(resolvedState)) as string); + } + + if (tokenRequestConfig) { + _dataLayer.setTemporaryDataParameter(TOKEN_REQUEST_CONFIG_KEY, JSON.stringify(tokenRequestConfig)); + } + + location.href = url; + + await SPAUtils.waitTillPageRedirect(); + + return Promise.resolve({ + allowedScopes: '', + displayName: '', + email: '', + sessionState: '', + sub: '', + tenantDomain: '', + username: '', + }); + }); + } + }; + + const signOut = async (): Promise => { + if ((await _authenticationClient.isAuthenticated()) && !_getSignOutURLFromSessionStorage) { + location.href = await _authenticationClient.getSignOutURL(); + } else { + location.href = SPAUtils.getSignOutURL(config.clientID, instanceID); + } + + _spaHelper.clearRefreshTokenTimeout(); + + await _dataLayer.removeOIDCProviderMetaData(); + await _dataLayer.removeTemporaryData(); + await _dataLayer.removeSessionData(); + await _dataLayer.removeSessionStatus(); + + await SPAUtils.waitTillPageRedirect(); + + return true; + }; + + const enableRetrievingSignOutURLFromSession = (config: SPACustomGrantConfig) => { + if (config.preventSignOutURLUpdate) { + _getSignOutURLFromSessionStorage = true; + } + }; + + const requestCustomGrant = async (config: SPACustomGrantConfig): Promise => { + return await _authenticationHelper.requestCustomGrant(config, enableRetrievingSignOutURLFromSession); + }; + + const refreshAccessToken = async (): Promise => { + try { + return await _authenticationHelper.refreshAccessToken(enableRetrievingSignOutURLFromSession); + } catch (error) { + return Promise.reject(error); + } + }; + + const revokeAccessToken = async (): Promise => { + const timer: number = await _spaHelper.getRefreshTimeoutTimer(); + + return _authenticationClient + .revokeAccessToken() + .then(() => { + _sessionManagementHelper.reset(); + _spaHelper.clearRefreshTokenTimeout(timer); + + return Promise.resolve(true); + }) + .catch(error => Promise.reject(error)); + }; + + const requestAccessToken = async ( + resolvedAuthorizationCode: string, + resolvedSessionState: string, + resolvedState: string, + tokenRequestConfig?: { + params: Record; + }, + ): Promise => { + return await _authenticationHelper.requestAccessToken( + resolvedAuthorizationCode, + resolvedSessionState, + checkSession, + undefined, + resolvedState, + tokenRequestConfig, + ); + }; + + const constructSilentSignInUrl = async (additionalParams: Record = {}): Promise => { + const config = await _dataLayer.getConfigData(); + const urlString: string = await _authenticationClient.getAuthorizationURL({ + prompt: 'none', + state: SILENT_SIGN_IN_STATE, + ...additionalParams, + }); + + // Replace form_post with query + const urlObject = new URL(urlString); + urlObject.searchParams.set('response_mode', 'query'); + const url: string = urlObject.toString(); + + if (config.storage === Storage.BrowserMemory && config.enablePKCE) { + const state = urlObject.searchParams.get(OIDCRequestConstants.Params.STATE); + + SPAUtils.setPKCE( + extractPkceStorageKeyFromState(state ?? ''), + (await _authenticationClient.getPKCECode(state ?? '')) as string, + ); + } + + return url; + }; + + /** + * This method checks if there is an active user session in the server by sending a prompt none request. + * If the user is signed in, this method sends a token request. Returns false otherwise. + * + * @return {Promise, + tokenRequestConfig?: {params: Record}, + ): Promise => { + return await _authenticationHelper.trySignInSilently( + constructSilentSignInUrl, + requestAccessToken, + _sessionManagementHelper, + additionalParams, + tokenRequestConfig, + ); + }; + + const getBasicUserInfo = async (): Promise => { + return _authenticationHelper.getBasicUserInfo(); + }; + + const getDecodedIDToken = async (): Promise => { + return _authenticationHelper.getDecodedIDToken(); + }; + + const getCryptoHelper = async (): Promise => { + return _authenticationHelper.getCryptoHelper(); + }; + + const getIDToken = async (): Promise => { + return _authenticationHelper.getIDToken(); + }; + + const getOIDCServiceEndpoints = async (): Promise => { + return _authenticationHelper.getOIDCServiceEndpoints(); + }; + + const getAccessToken = async (): Promise => { + return _authenticationHelper.getAccessToken(); + }; + + const getDataLayer = async (): Promise> => { + return _authenticationHelper.getDataLayer(); + }; + + const getConfigData = async (): Promise> => { + return await _dataLayer.getConfigData(); + }; + + const isAuthenticated = async (): Promise => { + return _authenticationHelper.isAuthenticated(); + }; + + const isSessionActive = async (): Promise => { + return (await _dataLayer.getSessionStatus()) === 'true'; + }; + + const updateConfig = async (newConfig: Partial>): Promise => { + const existingConfig = await _dataLayer.getConfigData(); + const isCheckSessionIframeDifferent: boolean = !( + existingConfig && + existingConfig.endpoints && + existingConfig.endpoints.checkSessionIframe && + newConfig && + newConfig.endpoints && + newConfig.endpoints.checkSessionIframe && + existingConfig.endpoints.checkSessionIframe === newConfig.endpoints.checkSessionIframe + ); + const config = {...existingConfig, ...newConfig}; + await _authenticationClient.updateConfig(config); + + // Re-initiates check session if the check session endpoint is updated. + if (config.enableOIDCSessionManagement && isCheckSessionIframeDifferent) { + _sessionManagementHelper.reset(); + + checkSession(); + } + }; + + return { + disableHttpHandler, + enableHttpHandler, + getAccessToken, + getBasicUserInfo, + getConfigData, + getCryptoHelper, + getDataLayer, + getDecodedIDToken, + getHttpClient, + getIDToken, + getOIDCServiceEndpoints, + httpRequest, + httpRequestAll, + isAuthenticated, + isSessionActive, + refreshAccessToken, + requestCustomGrant, + revokeAccessToken, + setHttpRequestErrorCallback, + setHttpRequestFinishCallback, + setHttpRequestStartCallback, + setHttpRequestSuccessCallback, + signIn, + signOut, + trySignInSilently, + updateConfig, + }; +}; diff --git a/packages/browser/src/__legacy__/clients/web-worker-client.ts b/packages/browser/src/__legacy__/clients/web-worker-client.ts new file mode 100755 index 000000000..9a4ab4939 --- /dev/null +++ b/packages/browser/src/__legacy__/clients/web-worker-client.ts @@ -0,0 +1,864 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + AsgardeoAuthClient, + AsgardeoAuthException, + AuthClientConfig, + BasicUserInfo, + IsomorphicCrypto, + CustomGrantConfig, + IdTokenPayload, + FetchResponse, + GetAuthURLConfig, + OIDCEndpoints, + ResponseMode, + OIDCRequestConstants, + Store, + extractPkceStorageKeyFromState, +} from '@asgardeo/javascript'; +import { + DISABLE_HTTP_HANDLER, + ENABLE_HTTP_HANDLER, + GET_AUTH_URL, + GET_BASIC_USER_INFO, + GET_CONFIG_DATA, + GET_CRYPTO_HELPER, + GET_DECODED_IDP_ID_TOKEN, + GET_DECODED_ID_TOKEN, + GET_ID_TOKEN, + GET_OIDC_SERVICE_ENDPOINTS, + GET_SIGN_OUT_URL, + HTTP_REQUEST, + HTTP_REQUEST_ALL, + INIT, + IS_AUTHENTICATED, + REFRESH_ACCESS_TOKEN, + REQUEST_ACCESS_TOKEN, + REQUEST_CUSTOM_GRANT, + REQUEST_FINISH, + REQUEST_START, + REQUEST_SUCCESS, + REVOKE_ACCESS_TOKEN, + SET_SESSION_STATE, + SIGN_OUT, + SILENT_SIGN_IN_STATE, + START_AUTO_REFRESH_TOKEN, + UPDATE_CONFIG, +} from '../constants'; +import {AuthenticationHelper, SPAHelper, SessionManagementHelper} from '../helpers'; +import { + AuthorizationInfo, + AuthorizationResponse, + HttpClient, + HttpError, + HttpRequestConfig, + HttpResponse, + Message, + ResponseMessage, + WebWorkerClientConfig, + WebWorkerClientInterface, +} from '../models'; +import {SPACustomGrantConfig} from '../models/request-custom-grant'; +import {Storage} from '../models/storage'; +import {LocalStore, MemoryStore, SessionStore} from '../stores'; +import {SPAUtils} from '../utils'; +import {SPACryptoUtils} from '../utils/crypto-utils'; + +const initiateStore = (store: Storage | undefined): Store => { + switch (store) { + case Storage.LocalStorage: + return new LocalStore(); + case Storage.SessionStorage: + return new SessionStore(); + case Storage.BrowserMemory: + return new MemoryStore(); + default: + return new SessionStore(); + } +}; + +export const WebWorkerClient = async ( + instanceID: number, + config: AuthClientConfig, + webWorker: new () => Worker, + getAuthHelper: ( + authClient: AsgardeoAuthClient, + spaHelper: SPAHelper, + ) => AuthenticationHelper, +): Promise => { + /** + * HttpClient handlers + */ + let httpClientHandlers: HttpClient; + /** + * API request time out. + */ + const _requestTimeout: number = config?.requestTimeout ?? 60000; + let _isHttpHandlerEnabled: boolean = true; + let _getSignOutURLFromSessionStorage: boolean = false; + + const _store: Store = initiateStore(config.storage as Storage); + const _cryptoUtils: SPACryptoUtils = new SPACryptoUtils(); + const _authenticationClient = new AsgardeoAuthClient(); + await _authenticationClient.initialize(config, _store, _cryptoUtils, instanceID); + const _spaHelper = new SPAHelper(_authenticationClient); + + const _sessionManagementHelper = await SessionManagementHelper( + async () => { + const message: Message = { + type: SIGN_OUT, + }; + + try { + const signOutURL = await communicate(message); + + return signOutURL; + } catch { + return SPAUtils.getSignOutURL(config.clientID, instanceID); + } + }, + config.storage as Storage, + (sessionState: string) => setSessionState(sessionState), + ); + + const _authenticationHelper: AuthenticationHelper = getAuthHelper( + _authenticationClient, + _spaHelper, + ); + + const worker: Worker = new webWorker(); + + const communicate = (message: Message): Promise => { + const channel = new MessageChannel(); + + worker.postMessage(message, [channel.port2]); + + return new Promise((resolve, reject) => { + const timer = setTimeout(() => { + reject( + new AsgardeoAuthException( + 'SPA-WEB_WORKER_CLIENT-COM-TO01', + 'Operation timed out.', + 'No response was received from the web worker for ' + + _requestTimeout / 1000 + + ' since dispatching the request', + ), + ); + }, _requestTimeout); + + return (channel.port1.onmessage = ({data}: {data: ResponseMessage}) => { + clearTimeout(timer); + channel.port1.close(); + channel.port2.close(); + + if (data?.success) { + const responseData = data?.data ? JSON.parse(data?.data) : null; + if (data?.blob) { + responseData.data = data?.blob; + } + + resolve(responseData); + } else { + reject(data.error ? JSON.parse(data.error) : null); + } + }); + }); + }; + + /** + * Allows using custom grant types. + * + * @param {CustomGrantRequestParams} requestParams Request Parameters. + * + * @returns {Promise} A promise that resolves with a boolean value or the request + * response if the the `returnResponse` attribute in the `requestParams` object is set to `true`. + */ + const requestCustomGrant = (requestParams: SPACustomGrantConfig): Promise => { + const message: Message = { + data: requestParams, + type: REQUEST_CUSTOM_GRANT, + }; + + return communicate(message) + .then(response => { + if (requestParams.preventSignOutURLUpdate) { + _getSignOutURLFromSessionStorage = true; + } + + return Promise.resolve(response); + }) + .catch(error => { + return Promise.reject(error); + }); + }; + + /** + * + * Send the API request to the web worker and returns the response. + * + * @param {HttpRequestConfig} config The Http Request Config object + * + * @returns {Promise} A promise that resolves with the response data. + */ + const httpRequest = (config: HttpRequestConfig): Promise> => { + /** + * + * Currently FormData is not supported to send to a web worker + * + * Below workaround will represent FormData object as a JSON. + * This workaround will not be needed once FormData object is made cloneable + * Reference: https://github.com/whatwg/xhr/issues/55 + */ + if (config?.data && config?.data instanceof FormData) { + config.data = {...Object.fromEntries((config?.data as any).entries()), formData: true}; + } + + const message: Message = { + data: config, + type: HTTP_REQUEST, + }; + + return communicate>(message) + .then(response => { + return Promise.resolve(response); + }) + .catch(async error => { + if (_isHttpHandlerEnabled) { + if (typeof httpClientHandlers.requestErrorCallback === 'function') { + await httpClientHandlers.requestErrorCallback(error); + } + if (typeof httpClientHandlers.requestFinishCallback === 'function') { + httpClientHandlers.requestFinishCallback(); + } + } + + return Promise.reject(error); + }); + }; + + /** + * + * Send multiple API requests to the web worker and returns the response. + * Similar `axios.spread` in functionality. + * + * @param {HttpRequestConfig[]} configs - The Http Request Config object + * + * @returns {Promise[]>} A promise that resolves with the response data. + */ + const httpRequestAll = (configs: HttpRequestConfig[]): Promise[]> => { + const message: Message = { + data: configs, + type: HTTP_REQUEST_ALL, + }; + + return communicate[]>(message) + .then(response => { + return Promise.resolve(response); + }) + .catch(async error => { + if (_isHttpHandlerEnabled) { + if (typeof httpClientHandlers.requestErrorCallback === 'function') { + await httpClientHandlers.requestErrorCallback(error); + } + if (typeof httpClientHandlers.requestFinishCallback === 'function') { + httpClientHandlers.requestFinishCallback(); + } + } + + return Promise.reject(error); + }); + }; + + const enableHttpHandler = (): Promise => { + const message: Message = { + type: ENABLE_HTTP_HANDLER, + }; + return communicate(message) + .then(() => { + _isHttpHandlerEnabled = true; + + return Promise.resolve(true); + }) + .catch(error => { + return Promise.reject(error); + }); + }; + + const disableHttpHandler = (): Promise => { + const message: Message = { + type: DISABLE_HTTP_HANDLER, + }; + return communicate(message) + .then(() => { + _isHttpHandlerEnabled = false; + + return Promise.resolve(true); + }) + .catch(error => { + return Promise.reject(error); + }); + }; + + /** + * Initializes the object with authentication parameters. + * + * @param {ConfigInterface} config The configuration object. + * + * @returns {Promise} Promise that resolves when initialization is successful. + * + */ + const initialize = (): Promise => { + if (!httpClientHandlers) { + httpClientHandlers = { + requestErrorCallback: () => Promise.resolve(), + requestFinishCallback: () => null, + requestStartCallback: () => null, + requestSuccessCallback: () => null, + }; + } + + worker.onmessage = ({data}) => { + switch (data.type) { + case REQUEST_FINISH: + httpClientHandlers?.requestFinishCallback && httpClientHandlers?.requestFinishCallback(); + break; + case REQUEST_START: + httpClientHandlers?.requestStartCallback && httpClientHandlers?.requestStartCallback(); + break; + case REQUEST_SUCCESS: + httpClientHandlers?.requestSuccessCallback && + httpClientHandlers?.requestSuccessCallback(data.data ? JSON.parse(data.data) : null); + break; + } + }; + + const message: Message> = { + data: config, + type: INIT, + }; + + return communicate, null>(message) + .then(() => { + return Promise.resolve(true); + }) + .catch(error => { + return Promise.reject(error); + }); + }; + + const setSessionState = (sessionState: string | null): Promise => { + const message: Message = { + data: sessionState, + type: SET_SESSION_STATE, + }; + + return communicate(message); + }; + + const startAutoRefreshToken = (): Promise => { + const message: Message = { + type: START_AUTO_REFRESH_TOKEN, + }; + + return communicate(message); + }; + + const checkSession = async (): Promise => { + const oidcEndpoints: OIDCEndpoints = await getOIDCServiceEndpoints(); + const config: AuthClientConfig = await getConfigData(); + + _authenticationHelper.initializeSessionManger( + config, + oidcEndpoints, + async () => (await getBasicUserInfo()).sessionState, + async (params?: GetAuthURLConfig): Promise => (await getAuthorizationURL(params)).authorizationURL, + _sessionManagementHelper, + ); + }; + + const constructSilentSignInUrl = async (additionalParams: Record = {}): Promise => { + const config: AuthClientConfig = await getConfigData(); + const message: Message = { + data: { + prompt: 'none', + state: SILENT_SIGN_IN_STATE, + ...additionalParams, + }, + type: GET_AUTH_URL, + }; + + const response: AuthorizationResponse = await communicate(message); + + const pkceKey: string = extractPkceStorageKeyFromState( + new URL(response.authorizationURL).searchParams.get(OIDCRequestConstants.Params.STATE) ?? '', + ); + + response.pkce && config.enablePKCE && SPAUtils.setPKCE(pkceKey, response.pkce); + + const urlString: string = response.authorizationURL; + + // Replace form_post with query + const urlObject = new URL(urlString); + urlObject.searchParams.set('response_mode', 'query'); + const url: string = urlObject.toString(); + + return url; + }; + + /** + * This method checks if there is an active user session in the server by sending a prompt none request. + * If the user is signed in, this method sends a token request. Returns false otherwise. + * + * @return {Promise, + tokenRequestConfig?: {params: Record}, + ): Promise => { + return await _authenticationHelper.trySignInSilently( + constructSilentSignInUrl, + requestAccessToken, + _sessionManagementHelper, + additionalParams, + tokenRequestConfig, + ); + }; + + /** + * Generates an authorization URL. + * + * @param {GetAuthURLConfig} params Authorization URL params. + * @returns {Promise} Authorization URL. + */ + const getAuthorizationURL = async (params?: GetAuthURLConfig): Promise => { + const config: AuthClientConfig = await getConfigData(); + + const message: Message = { + data: params, + type: GET_AUTH_URL, + }; + + return communicate(message).then( + async (response: AuthorizationResponse) => { + if (response.pkce && config.enablePKCE) { + const pkceKey: string = extractPkceStorageKeyFromState( + new URL(response.authorizationURL).searchParams.get(OIDCRequestConstants.Params.STATE) ?? '', + ); + + SPAUtils.setPKCE(pkceKey, response.pkce); + } + + return Promise.resolve(response); + }, + ); + }; + + const requestAccessToken = async ( + resolvedAuthorizationCode: string, + resolvedSessionState: string, + resolvedState: string, + tokenRequestConfig?: { + params: Record; + }, + ): Promise => { + const config: AuthClientConfig = await getConfigData(); + const pkceKey: string = extractPkceStorageKeyFromState(resolvedState); + + const message: Message = { + data: { + code: resolvedAuthorizationCode, + pkce: config.enablePKCE ? SPAUtils.getPKCE(pkceKey) : undefined, + sessionState: resolvedSessionState, + state: resolvedState, + tokenRequestConfig, + }, + type: REQUEST_ACCESS_TOKEN, + }; + + config.enablePKCE && SPAUtils.removePKCE(pkceKey); + + return communicate(message) + .then(response => { + const message: Message = { + type: GET_SIGN_OUT_URL, + }; + + return communicate(message) + .then((url: string) => { + SPAUtils.setSignOutURL(url, config.clientID, instanceID); + + // Enable OIDC Sessions Management only if it is set to true in the config. + if (config.enableOIDCSessionManagement) { + checkSession(); + } + + startAutoRefreshToken(); + + return Promise.resolve(response); + }) + .catch(error => { + return Promise.reject(error); + }); + }) + .catch(error => { + return Promise.reject(error); + }); + }; + + const shouldStopAuthn = async (): Promise => { + return await _sessionManagementHelper.receivePromptNoneResponse(async (sessionState: string | null) => { + return setSessionState(sessionState); + }); + }; + + const tryRetrievingUserInfo = async (): Promise => { + if (await isAuthenticated()) { + await startAutoRefreshToken(); + + // Enable OIDC Sessions Management only if it is set to true in the config. + if (config.enableOIDCSessionManagement) { + checkSession(); + } + + return getBasicUserInfo(); + } + + return Promise.resolve(undefined); + }; + + /** + * Initiates the authentication flow. + * + * @returns {Promise} A promise that resolves when authentication is successful. + */ + const signIn = async ( + params?: GetAuthURLConfig, + authorizationCode?: string, + sessionState?: string, + state?: string, + tokenRequestConfig?: { + params: Record; + }, + ): Promise => { + const basicUserInfo = await _authenticationHelper.handleSignIn( + shouldStopAuthn, + checkSession, + tryRetrievingUserInfo, + ); + + if (basicUserInfo) { + return basicUserInfo; + } else { + let resolvedAuthorizationCode: string; + let resolvedSessionState: string; + let resolvedState: string; + + if (config?.responseMode === ResponseMode.FormPost && authorizationCode) { + resolvedAuthorizationCode = authorizationCode; + resolvedSessionState = sessionState ?? ''; + resolvedState = state ?? ''; + } else { + resolvedAuthorizationCode = + new URL(window.location.href).searchParams.get(OIDCRequestConstants.Params.AUTHORIZATION_CODE) ?? ''; + resolvedSessionState = + new URL(window.location.href).searchParams.get(OIDCRequestConstants.Params.SESSION_STATE) ?? ''; + resolvedState = new URL(window.location.href).searchParams.get(OIDCRequestConstants.Params.STATE) ?? ''; + + SPAUtils.removeAuthorizationCode(); + } + + if (resolvedAuthorizationCode && resolvedState) { + return requestAccessToken(resolvedAuthorizationCode, resolvedSessionState, resolvedState, tokenRequestConfig); + } + + return getAuthorizationURL(params) + .then(async (response: AuthorizationResponse) => { + location.href = response.authorizationURL; + + await SPAUtils.waitTillPageRedirect(); + + return Promise.resolve({ + allowedScopes: '', + displayName: '', + email: '', + sessionState: '', + sub: '', + tenantDomain: '', + username: '', + }); + }) + .catch(error => { + return Promise.reject(error); + }); + } + }; + + /** + * Initiates the sign out flow. + * + * @returns {Promise} A promise that resolves when sign out is completed. + */ + const signOut = (): Promise => { + return new Promise((resolve, reject) => { + if (!_getSignOutURLFromSessionStorage) { + const message: Message = { + type: SIGN_OUT, + }; + + return communicate(message) + .then(async response => { + window.location.href = response; + + await SPAUtils.waitTillPageRedirect(); + + return resolve(true); + }) + .catch(error => { + return reject(error); + }); + } else { + window.location.href = SPAUtils.getSignOutURL(config.clientID, instanceID); + + return SPAUtils.waitTillPageRedirect().then(() => { + return Promise.resolve(true); + }); + } + }); + }; + + /** + * Revokes token. + * + * @returns {Promise} A promise that resolves when revoking is completed. + */ + const revokeAccessToken = (): Promise => { + const message: Message = { + type: REVOKE_ACCESS_TOKEN, + }; + + return communicate(message) + .then(response => { + _sessionManagementHelper.reset(); + return Promise.resolve(response); + }) + .catch(error => { + return Promise.reject(error); + }); + }; + + const getOIDCServiceEndpoints = (): Promise => { + const message: Message = { + type: GET_OIDC_SERVICE_ENDPOINTS, + }; + + return communicate(message) + .then(response => { + return Promise.resolve(response); + }) + .catch(error => { + return Promise.reject(error); + }); + }; + + const getConfigData = (): Promise> => { + const message: Message = { + type: GET_CONFIG_DATA, + }; + + return communicate>(message) + .then(response => { + return Promise.resolve(response); + }) + .catch(error => { + return Promise.reject(error); + }); + }; + + const getBasicUserInfo = (): Promise => { + const message: Message = { + type: GET_BASIC_USER_INFO, + }; + + return communicate(message) + .then(response => { + return Promise.resolve(response); + }) + .catch(error => { + return Promise.reject(error); + }); + }; + + const getDecodedIDToken = (): Promise => { + const message: Message = { + type: GET_DECODED_ID_TOKEN, + }; + + return communicate(message) + .then(response => { + return Promise.resolve(response); + }) + .catch(error => { + return Promise.reject(error); + }); + }; + + const getDecodedIDPIDToken = (): Promise => { + const message: Message = { + type: GET_DECODED_IDP_ID_TOKEN, + }; + + return communicate(message) + .then(response => { + return Promise.resolve(response); + }) + .catch(error => { + return Promise.reject(error); + }); + }; + + const getCryptoHelper = (): Promise => { + const message: Message = { + type: GET_CRYPTO_HELPER, + }; + + return communicate(message) + .then(response => { + return Promise.resolve(response); + }) + .catch(error => { + return Promise.reject(error); + }); + }; + + const getIDToken = (): Promise => { + const message: Message = { + type: GET_ID_TOKEN, + }; + + return communicate(message) + .then(response => { + return Promise.resolve(response); + }) + .catch(error => { + return Promise.reject(error); + }); + }; + + const isAuthenticated = (): Promise => { + const message: Message = { + type: IS_AUTHENTICATED, + }; + + return communicate(message) + .then(response => { + return Promise.resolve(response); + }) + .catch(error => { + return Promise.reject(error); + }); + }; + + const refreshAccessToken = (): Promise => { + const message: Message = { + type: REFRESH_ACCESS_TOKEN, + }; + + return communicate(message); + }; + + const setHttpRequestSuccessCallback = (callback: (response: HttpResponse) => void): void => { + if (callback && typeof callback === 'function') { + httpClientHandlers.requestSuccessCallback = callback; + } + }; + + const setHttpRequestErrorCallback = (callback: (response: HttpError) => void | Promise): void => { + if (callback && typeof callback === 'function') { + httpClientHandlers.requestErrorCallback = callback; + } + }; + + const setHttpRequestStartCallback = (callback: () => void): void => { + if (callback && typeof callback === 'function') { + httpClientHandlers.requestStartCallback = callback; + } + }; + + const setHttpRequestFinishCallback = (callback: () => void): void => { + if (callback && typeof callback === 'function') { + httpClientHandlers.requestFinishCallback = callback; + } + }; + + const updateConfig = async (newConfig: Partial>): Promise => { + const existingConfig = await getConfigData(); + const isCheckSessionIframeDifferent: boolean = !( + existingConfig && + existingConfig.endpoints && + existingConfig.endpoints.checkSessionIframe && + newConfig && + newConfig.endpoints && + newConfig.endpoints.checkSessionIframe && + existingConfig.endpoints.checkSessionIframe === newConfig.endpoints.checkSessionIframe + ); + const config = {...existingConfig, ...newConfig}; + + const message: Message>> = { + data: config, + type: UPDATE_CONFIG, + }; + + await communicate>, void>(message); + + // Re-initiates check session if the check session endpoint is updated. + if (config.enableOIDCSessionManagement && isCheckSessionIframeDifferent) { + _sessionManagementHelper.reset(); + + checkSession(); + } + }; + + return { + disableHttpHandler, + enableHttpHandler, + getBasicUserInfo, + getConfigData, + getCryptoHelper, + getDecodedIDPIDToken, + getDecodedIDToken, + getIDToken, + getOIDCServiceEndpoints, + httpRequest, + httpRequestAll, + initialize, + isAuthenticated, + refreshAccessToken, + requestCustomGrant, + revokeAccessToken, + setHttpRequestErrorCallback, + setHttpRequestFinishCallback, + setHttpRequestStartCallback, + setHttpRequestSuccessCallback, + signIn, + signOut, + trySignInSilently, + updateConfig, + }; +}; diff --git a/packages/browser/src/__legacy__/constants/errors.ts b/packages/browser/src/__legacy__/constants/errors.ts new file mode 100644 index 000000000..506db48e9 --- /dev/null +++ b/packages/browser/src/__legacy__/constants/errors.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.com) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const ACCESS_TOKEN_INVALID = "Access token is invalid"; diff --git a/packages/browser/src/__legacy__/constants/hooks.ts b/packages/browser/src/__legacy__/constants/hooks.ts new file mode 100644 index 000000000..e34baf4b0 --- /dev/null +++ b/packages/browser/src/__legacy__/constants/hooks.ts @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export enum Hooks { + SignIn = "sign-in", + SignOut = "sign-out", + Initialize = "initialize", + HttpRequestStart = "http-request-start", + HttpRequestFinish = "http-request-finish", + HttpRequestError = "http-request-error", + HttpRequestSuccess = "http-request-success", + RevokeAccessToken = "revoke-access-token", + CustomGrant = "custom-grant", + SignOutFailed = "sign-out-failed" +} diff --git a/packages/browser/src/__legacy__/constants/index.ts b/packages/browser/src/__legacy__/constants/index.ts new file mode 100644 index 000000000..67b72880a --- /dev/null +++ b/packages/browser/src/__legacy__/constants/index.ts @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from "./messages-types"; +export * from "./storage"; +export * from "./hooks"; +export * from "./session-management"; +export * from "./parameters"; +export * from "./errors"; diff --git a/packages/browser/src/__legacy__/constants/messages-types.ts b/packages/browser/src/__legacy__/constants/messages-types.ts new file mode 100644 index 000000000..a37317af1 --- /dev/null +++ b/packages/browser/src/__legacy__/constants/messages-types.ts @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const INIT = "init"; +export const SIGN_IN = "sign-in"; +export const AUTH_CODE = "auth-code"; +export const SIGN_OUT = "sign-out"; +export const HTTP_REQUEST = "http-request"; +export const HTTP_REQUEST_ALL = "http-request-all"; +export const REQUEST_CUSTOM_GRANT = "request-custom-grant"; +export const REVOKE_ACCESS_TOKEN = "revoke-access-token"; +export const END_USER_SESSION = "end-user-session"; +export const REQUEST_START = "request-start"; +export const REQUEST_SUCCESS = "request-success"; +export const REQUEST_ERROR = "request-error"; +export const REQUEST_FINISH = "request-finish"; +export const GET_OIDC_SERVICE_ENDPOINTS = "get-oidc-service-endpoints"; +export const GET_BASIC_USER_INFO = "get-basic-user-info"; +export const GET_DECODED_ID_TOKEN = "get-decoded-id-token"; +export const GET_DECODED_IDP_ID_TOKEN = "get-decoded-idp-id-token"; +export const GET_CRYPTO_HELPER = "get-crypto-helper" +export const ENABLE_HTTP_HANDLER = "enable_http_handler"; +export const DISABLE_HTTP_HANDLER = "disable_http_handler"; +export const GET_AUTH_URL = "get_auth_url"; +export const REQUEST_ACCESS_TOKEN = "request_get_token"; +export const IS_AUTHENTICATED = "is_authenticated"; +export const GET_SIGN_OUT_URL = "get_sign_out_url"; +export const REFRESH_ACCESS_TOKEN = "refresh_access-token"; +export const REFRESH_ACCESS_TOKEN_ERR0R = "refresh-access-token-error"; +export const SET_SESSION_STATE = "set_session_state"; +export const START_AUTO_REFRESH_TOKEN = "start_auto_refresh_token"; +export const UPDATE_CONFIG = "update_config"; +export const GET_ID_TOKEN = "get_id_token"; +export const CHECK_SESSION_SIGNED_IN = "check_session_signed_in"; +export const CHECK_SESSION_SIGNED_OUT = "check_session_signed_out"; +export const GET_CONFIG_DATA = "get_config_data"; +export const SET_SESSION_STATE_FROM_IFRAME = "set_session_state_from_iframe"; diff --git a/packages/browser/src/__legacy__/constants/parameters.ts b/packages/browser/src/__legacy__/constants/parameters.ts new file mode 100644 index 000000000..869771ca7 --- /dev/null +++ b/packages/browser/src/__legacy__/constants/parameters.ts @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const ERROR = "error"; +export const ERROR_DESCRIPTION = "error_description"; +export const CUSTOM_GRANT_CONFIG = "custom_grant_config"; +export const STATE_QUERY = "state"; diff --git a/packages/browser/src/__legacy__/constants/session-management.ts b/packages/browser/src/__legacy__/constants/session-management.ts new file mode 100644 index 000000000..9102f7dd0 --- /dev/null +++ b/packages/browser/src/__legacy__/constants/session-management.ts @@ -0,0 +1,26 @@ +/** +* Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +export const OP_IFRAME = "opIFrame"; +export const RP_IFRAME = "rpIFrame"; +export const PROMPT_NONE_IFRAME = "promptNoneIFrame"; +export const STATE = "Y2hlY2tTZXNzaW9u"; +export const SILENT_SIGN_IN_STATE = "sign-in-silently"; +export const INITIALIZED_SIGN_IN = "initialized-sign-in"; +export const INITIALIZED_SILENT_SIGN_IN = "initialized-silent-sign-in"; +export const PROMPT_NONE_REQUEST_SENT = "promptNoneRequestSent"; diff --git a/packages/browser/src/__legacy__/constants/storage.ts b/packages/browser/src/__legacy__/constants/storage.ts new file mode 100644 index 000000000..56661a09e --- /dev/null +++ b/packages/browser/src/__legacy__/constants/storage.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const TOKEN_REQUEST_CONFIG_KEY = "token_request_config"; diff --git a/packages/browser/src/__legacy__/helpers/authentication-helper.ts b/packages/browser/src/__legacy__/helpers/authentication-helper.ts new file mode 100644 index 000000000..cb9f83e0d --- /dev/null +++ b/packages/browser/src/__legacy__/helpers/authentication-helper.ts @@ -0,0 +1,698 @@ +/** + * Copyright (c) 2022-2024, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + AsgardeoAuthClient, + AsgardeoAuthException, + AuthClientConfig, + BasicUserInfo, + IsomorphicCrypto, + CustomGrantConfig, + DataLayer, + IdTokenPayload, + FetchResponse, + GetAuthURLConfig, + OIDCEndpoints, + TokenResponse, + extractPkceStorageKeyFromState, +} from '@asgardeo/javascript'; +import {SPAHelper} from './spa-helper'; +import { + ACCESS_TOKEN_INVALID, + CHECK_SESSION_SIGNED_IN, + CHECK_SESSION_SIGNED_OUT, + CUSTOM_GRANT_CONFIG, + ERROR, + ERROR_DESCRIPTION, + PROMPT_NONE_IFRAME, + REFRESH_ACCESS_TOKEN_ERR0R, + RP_IFRAME, +} from '../constants'; +import { + AuthorizationInfo, + HttpClientInstance, + HttpError, + HttpRequestConfig, + HttpRequestInterface, + HttpResponse, + MainThreadClientConfig, + Message, + SessionManagementHelperInterface, + WebWorkerClientConfig, +} from '../models'; +import {SPACustomGrantConfig} from '../models/request-custom-grant'; +import {Storage} from '../models/storage'; +import {SPAUtils} from '../utils'; + +export class AuthenticationHelper { + protected _authenticationClient: AsgardeoAuthClient; + protected _dataLayer: DataLayer; + protected _spaHelper: SPAHelper; + protected _instanceID: number; + protected _isTokenRefreshing: boolean; + + public constructor(authClient: AsgardeoAuthClient, spaHelper: SPAHelper) { + this._authenticationClient = authClient; + this._dataLayer = this._authenticationClient.getDataLayer(); + this._spaHelper = spaHelper; + this._instanceID = this._authenticationClient.getInstanceID(); + this._isTokenRefreshing = false; + } + + public enableHttpHandler(httpClient: HttpClientInstance): void { + httpClient?.enableHandler && httpClient.enableHandler(); + } + + public disableHttpHandler(httpClient: HttpClientInstance): void { + httpClient?.disableHandler && httpClient.disableHandler(); + } + + public initializeSessionManger( + config: AuthClientConfig, + oidcEndpoints: OIDCEndpoints, + getSessionState: () => Promise, + getAuthzURL: (params?: GetAuthURLConfig) => Promise, + sessionManagementHelper: SessionManagementHelperInterface, + ): void { + sessionManagementHelper.initialize( + config.clientID, + oidcEndpoints.checkSessionIframe ?? '', + getSessionState, + config.checkSessionInterval ?? 3, + config.sessionRefreshInterval ?? 300, + config.signInRedirectURL, + getAuthzURL, + ); + } + + public async requestCustomGrant( + config: SPACustomGrantConfig, + enableRetrievingSignOutURLFromSession?: (config: SPACustomGrantConfig) => void, + ): Promise { + let useDefaultEndpoint = true; + let matches = false; + + // If the config does not contains a token endpoint, default token endpoint will be used. + if (config?.tokenEndpoint) { + useDefaultEndpoint = false; + + for (const baseUrl of [ + ...((await this._dataLayer.getConfigData())?.resourceServerURLs ?? []), + (config as any).baseUrl, + ]) { + if (baseUrl && config.tokenEndpoint?.startsWith(baseUrl)) { + matches = true; + break; + } + } + } + if (config.shouldReplayAfterRefresh) { + this._dataLayer.setTemporaryDataParameter(CUSTOM_GRANT_CONFIG, JSON.stringify(config)); + } + if (useDefaultEndpoint || matches) { + return this._authenticationClient + .requestCustomGrant(config) + .then(async (response: FetchResponse | TokenResponse) => { + if (enableRetrievingSignOutURLFromSession && typeof enableRetrievingSignOutURLFromSession === 'function') { + enableRetrievingSignOutURLFromSession(config); + } + + if (config.returnsSession) { + this._spaHelper.refreshAccessTokenAutomatically(this); + + return this._authenticationClient.getBasicUserInfo(); + } else { + return response as FetchResponse; + } + }) + .catch(error => { + return Promise.reject(error); + }); + } else { + return Promise.reject( + new AsgardeoAuthException( + 'SPA-MAIN_THREAD_CLIENT-RCG-IV01', + 'Request to the provided endpoint is prohibited.', + 'Requests can only be sent to resource servers specified by the `resourceServerURLs`' + + ' attribute while initializing the SDK. The specified token endpoint in this request ' + + 'cannot be found among the `resourceServerURLs`', + ), + ); + } + } + + public async getCustomGrantConfigData(): Promise | null> { + const configString = await this._dataLayer.getTemporaryDataParameter(CUSTOM_GRANT_CONFIG); + + if (configString) { + return JSON.parse(configString as string); + } else { + return null; + } + } + + public async refreshAccessToken( + enableRetrievingSignOutURLFromSession?: (config: SPACustomGrantConfig) => void, + ): Promise { + try { + await this._authenticationClient.refreshAccessToken(); + const customGrantConfig = await this.getCustomGrantConfigData(); + if (customGrantConfig) { + await this.requestCustomGrant(customGrantConfig, enableRetrievingSignOutURLFromSession); + } + this._spaHelper.refreshAccessTokenAutomatically(this); + + return this._authenticationClient.getBasicUserInfo(); + } catch (error) { + const refreshTokenError: Message = { + type: REFRESH_ACCESS_TOKEN_ERR0R, + }; + + window.postMessage(refreshTokenError); + return Promise.reject(error); + } + } + + protected async retryFailedRequests(failedRequest: HttpRequestInterface): Promise { + const httpClient = failedRequest.httpClient; + const requestConfig = failedRequest.requestConfig; + const isHttpHandlerEnabled = failedRequest.isHttpHandlerEnabled; + const httpErrorCallback = failedRequest.httpErrorCallback; + const httpFinishCallback = failedRequest.httpFinishCallback; + + // Wait until the token is refreshed. + await SPAUtils.until(() => !this._isTokenRefreshing); + + try { + const httpResponse = await httpClient.request(requestConfig); + + return Promise.resolve(httpResponse); + } catch (error: any) { + if (isHttpHandlerEnabled) { + if (typeof httpErrorCallback === 'function') { + await httpErrorCallback(error); + } + if (typeof httpFinishCallback === 'function') { + httpFinishCallback(); + } + } + + return Promise.reject(error); + } + } + + public async httpRequest( + httpClient: HttpClientInstance, + requestConfig: HttpRequestConfig, + isHttpHandlerEnabled?: boolean, + httpErrorCallback?: (error: HttpError) => void | Promise, + httpFinishCallback?: () => void, + enableRetrievingSignOutURLFromSession?: (config: SPACustomGrantConfig) => void, + ): Promise { + let matches = false; + const config = await this._dataLayer.getConfigData(); + + for (const baseUrl of [...((await config?.resourceServerURLs) ?? []), (config as any).baseUrl]) { + if (baseUrl && requestConfig?.url?.startsWith(baseUrl)) { + matches = true; + + break; + } + } + + if (matches) { + return httpClient + .request(requestConfig) + .then((response: HttpResponse) => { + return Promise.resolve(response); + }) + .catch(async (error: HttpError) => { + if (error?.response?.status === 401 || !error?.response) { + if (this._isTokenRefreshing) { + return this.retryFailedRequests({ + enableRetrievingSignOutURLFromSession, + httpClient, + httpErrorCallback, + httpFinishCallback, + isHttpHandlerEnabled, + requestConfig, + }); + } + + this._isTokenRefreshing = true; + // Try to refresh the token + let refreshAccessTokenResponse: BasicUserInfo; + try { + refreshAccessTokenResponse = await this.refreshAccessToken(enableRetrievingSignOutURLFromSession); + + this._isTokenRefreshing = false; + } catch (refreshError: any) { + this._isTokenRefreshing = false; + + if (isHttpHandlerEnabled) { + if (typeof httpErrorCallback === 'function') { + await httpErrorCallback({ + ...error, + code: ACCESS_TOKEN_INVALID, + }); + } + if (typeof httpFinishCallback === 'function') { + httpFinishCallback(); + } + } + + throw new AsgardeoAuthException( + 'SPA-AUTH_HELPER-HR-SE01', + refreshError?.name ?? 'Refresh token request failed.', + refreshError?.message ?? + 'An error occurred while trying to refresh the ' + + 'access token following a 401 response from the server.', + ); + } + + // Retry the request after refreshing the token + if (refreshAccessTokenResponse) { + try { + const httpResponse = await httpClient.request(requestConfig); + return Promise.resolve(httpResponse); + } catch (error: any) { + if (isHttpHandlerEnabled) { + if (typeof httpErrorCallback === 'function') { + await httpErrorCallback(error); + } + if (typeof httpFinishCallback === 'function') { + httpFinishCallback(); + } + } + return Promise.reject(error); + } + } + } + + if (isHttpHandlerEnabled) { + if (typeof httpErrorCallback === 'function') { + await httpErrorCallback(error); + } + if (typeof httpFinishCallback === 'function') { + httpFinishCallback(); + } + } + + return Promise.reject(error); + }); + } else { + return Promise.reject( + new AsgardeoAuthException( + 'SPA-AUTH_HELPER-HR-IV02', + 'Request to the provided endpoint is prohibited.', + 'Requests can only be sent to resource servers specified by the `resourceServerURLs`' + + ' attribute while initializing the SDK. The specified endpoint in this request ' + + 'cannot be found among the `resourceServerURLs`', + ), + ); + } + } + + public async httpRequestAll( + requestConfigs: HttpRequestConfig[], + httpClient: HttpClientInstance, + isHttpHandlerEnabled?: boolean, + httpErrorCallback?: (error: HttpError) => void | Promise, + httpFinishCallback?: () => void, + ): Promise { + let matches = true; + const config = await this._dataLayer.getConfigData(); + + for (const requestConfig of requestConfigs) { + let urlMatches = false; + + for (const baseUrl of [...((await config)?.resourceServerURLs ?? []), (config as any).baseUrl]) { + if (baseUrl && requestConfig.url?.startsWith(baseUrl)) { + urlMatches = true; + + break; + } + } + + if (!urlMatches) { + matches = false; + + break; + } + } + + const requests: Promise>[] = []; + + if (matches) { + requestConfigs.forEach(request => { + requests.push(httpClient.request(request)); + }); + + return ( + httpClient?.all && + httpClient + .all(requests) + .then((responses: HttpResponse[]) => { + return Promise.resolve(responses); + }) + .catch(async (error: HttpError) => { + if (error?.response?.status === 401 || !error?.response) { + let refreshTokenResponse: TokenResponse | BasicUserInfo; + try { + refreshTokenResponse = await this._authenticationClient.refreshAccessToken(); + } catch (refreshError: any) { + if (isHttpHandlerEnabled) { + if (typeof httpErrorCallback === 'function') { + await httpErrorCallback({ + ...error, + code: ACCESS_TOKEN_INVALID, + }); + } + if (typeof httpFinishCallback === 'function') { + httpFinishCallback(); + } + } + + throw new AsgardeoAuthException( + 'SPA-AUTH_HELPER-HRA-SE01', + refreshError?.name ?? 'Refresh token request failed.', + refreshError?.message ?? + 'An error occurred while trying to refresh the ' + + 'access token following a 401 response from the server.', + ); + } + + if (refreshTokenResponse) { + return ( + httpClient.all && + httpClient + .all(requests) + .then(response => { + return Promise.resolve(response); + }) + .catch(async error => { + if (isHttpHandlerEnabled) { + if (typeof httpErrorCallback === 'function') { + await httpErrorCallback(error); + } + if (typeof httpFinishCallback === 'function') { + httpFinishCallback(); + } + } + + return Promise.reject(error); + }) + ); + } + } + + if (isHttpHandlerEnabled) { + if (typeof httpErrorCallback === 'function') { + await httpErrorCallback(error); + } + if (typeof httpFinishCallback === 'function') { + httpFinishCallback(); + } + } + + return Promise.reject(error); + }) + ); + } else { + throw new AsgardeoAuthException( + 'SPA-AUTH_HELPER-HRA-IV02', + 'Request to the provided endpoint is prohibited.', + 'Requests can only be sent to resource servers specified by the `resourceServerURLs`' + + ' attribute while initializing the SDK. The specified endpoint in this request ' + + 'cannot be found among the `resourceServerURLs`', + ); + } + } + + public async requestAccessToken( + authorizationCode?: string, + sessionState?: string, + checkSession?: () => Promise, + pkce?: string, + state?: string, + tokenRequestConfig?: { + params: Record; + }, + ): Promise { + const config = await this._dataLayer.getConfigData(); + + if (config.storage === Storage.BrowserMemory && config.enablePKCE && sessionState) { + const pkce = SPAUtils.getPKCE(extractPkceStorageKeyFromState(sessionState)); + + await this._authenticationClient.setPKCECode(extractPkceStorageKeyFromState(sessionState), pkce); + } else if (config.storage === Storage.WebWorker && pkce) { + await this._authenticationClient.setPKCECode(pkce, state ?? ''); + } + + if (authorizationCode) { + return this._authenticationClient + .requestAccessToken(authorizationCode, sessionState ?? '', state ?? '', undefined, tokenRequestConfig) + .then(async () => { + // Disable this temporarily + /* if (config.storage === Storage.BrowserMemory) { + SPAUtils.setSignOutURL(await _authenticationClient.getSignOutURL()); + } */ + if (config.storage !== Storage.WebWorker) { + SPAUtils.setSignOutURL(await this._authenticationClient.getSignOutURL(), config.clientID, this._instanceID); + + if (this._spaHelper) { + this._spaHelper.clearRefreshTokenTimeout(); + this._spaHelper.refreshAccessTokenAutomatically(this); + } + + // Enable OIDC Sessions Management only if it is set to true in the config. + if (checkSession && typeof checkSession === 'function' && config.enableOIDCSessionManagement) { + checkSession(); + } + } else { + if (this._spaHelper) { + this._spaHelper.refreshAccessTokenAutomatically(this); + } + } + + return this._authenticationClient.getBasicUserInfo(); + }) + .catch(error => { + return Promise.reject(error); + }); + } + + return Promise.reject( + new AsgardeoAuthException( + 'SPA-AUTH_HELPER-RAT1-NF01', + 'No authorization code.', + 'No authorization code was found.', + ), + ); + } + + public async trySignInSilently( + constructSilentSignInUrl: (additionalParams?: Record) => Promise, + requestAccessToken: ( + authzCode: string, + sessionState: string, + state: string, + tokenRequestConfig?: {params: Record}, + ) => Promise, + sessionManagementHelper: SessionManagementHelperInterface, + additionalParams?: Record, + tokenRequestConfig?: {params: Record}, + ): Promise { + // This block is executed by the iFrame when the server redirects with the authorization code. + if (SPAUtils.isInitializedSilentSignIn()) { + await sessionManagementHelper.receivePromptNoneResponse(); + + return Promise.resolve({ + allowedScopes: '', + displayName: '', + email: '', + sessionState: '', + sub: '', + tenantDomain: '', + username: '', + }); + } + + // This gets executed in the main thread and sends the prompt none request. + const rpIFrame = document.getElementById(RP_IFRAME) as HTMLIFrameElement; + + const promptNoneIFrame: HTMLIFrameElement = rpIFrame?.contentDocument?.getElementById( + PROMPT_NONE_IFRAME, + ) as HTMLIFrameElement; + + try { + const url = await constructSilentSignInUrl(additionalParams); + + promptNoneIFrame.src = url; + } catch (error) { + return Promise.reject(error); + } + + return new Promise((resolve, reject) => { + const timer = setTimeout(() => { + resolve(false); + }, 10000); + + const listenToPromptNoneIFrame = async (e: MessageEvent) => { + const data: Message = e.data; + + if (data?.type == CHECK_SESSION_SIGNED_OUT) { + window.removeEventListener('message', listenToPromptNoneIFrame); + clearTimeout(timer); + resolve(false); + } + + if (data?.type == CHECK_SESSION_SIGNED_IN && data?.data?.code) { + requestAccessToken(data?.data?.code, data?.data?.sessionState, data?.data?.state, tokenRequestConfig) + .then((response: BasicUserInfo) => { + window.removeEventListener('message', listenToPromptNoneIFrame); + resolve(response); + }) + .catch(error => { + window.removeEventListener('message', listenToPromptNoneIFrame); + reject(error); + }) + .finally(() => { + clearTimeout(timer); + }); + } + }; + + window.addEventListener('message', listenToPromptNoneIFrame); + }); + } + + public async handleSignIn( + shouldStopAuthn: () => Promise, + checkSession: () => Promise, + tryRetrievingUserInfo?: () => Promise, + ): Promise { + const config = await this._dataLayer.getConfigData(); + + if (await shouldStopAuthn()) { + return Promise.resolve({ + allowedScopes: '', + displayName: '', + email: '', + sessionState: '', + sub: '', + tenantDomain: '', + username: '', + }); + } + + if (config.storage !== Storage.WebWorker) { + if (await this._authenticationClient.isAuthenticated()) { + this._spaHelper.clearRefreshTokenTimeout(); + this._spaHelper.refreshAccessTokenAutomatically(this); + + // Enable OIDC Sessions Management only if it is set to true in the config. + if (config.enableOIDCSessionManagement) { + checkSession(); + } + + return Promise.resolve(await this._authenticationClient.getBasicUserInfo()); + } + } + + const error = new URL(window.location.href).searchParams.get(ERROR); + const errorDescription = new URL(window.location.href).searchParams.get(ERROR_DESCRIPTION); + + if (error) { + const url = new URL(window.location.href); + url.searchParams.delete(ERROR); + url.searchParams.delete(ERROR_DESCRIPTION); + + history.pushState(null, document.title, url.toString()); + + throw new AsgardeoAuthException('SPA-AUTH_HELPER-SI-SE01', error, errorDescription ?? ''); + } + + if (config.storage === Storage.WebWorker && tryRetrievingUserInfo) { + const basicUserInfo = await tryRetrievingUserInfo(); + + if (basicUserInfo) { + return basicUserInfo; + } + } + + return Promise.resolve(undefined); + } + + public async attachTokenToRequestConfig(request: HttpRequestConfig): Promise { + const requestConfig = {attachToken: true, ...request}; + if (requestConfig.attachToken) { + if (requestConfig.shouldAttachIDPAccessToken) { + request.headers = { + ...request.headers, + Authorization: `Bearer ${await this.getIDPAccessToken()}`, + }; + } else { + request.headers = { + ...request.headers, + Authorization: `Bearer ${await this.getAccessToken()}`, + }; + } + } + } + + public async getBasicUserInfo(): Promise { + return this._authenticationClient.getBasicUserInfo(); + } + + public async getDecodedIDToken(): Promise { + return this._authenticationClient.getDecodedIDToken(); + } + + public async getDecodedIDPIDToken(): Promise { + return this._authenticationClient.getDecodedIDToken(); + } + + public async getCryptoHelper(): Promise { + return this._authenticationClient.getCryptoHelper(); + } + + public async getIDToken(): Promise { + return this._authenticationClient.getIDToken(); + } + + public async getOIDCServiceEndpoints(): Promise { + return this._authenticationClient.getOIDCServiceEndpoints() as any; + } + + public async getAccessToken(): Promise { + return this._authenticationClient.getAccessToken(); + } + + public async getIDPAccessToken(): Promise { + return (await this._dataLayer.getSessionData())?.access_token; + } + + public getDataLayer(): DataLayer { + return this._dataLayer; + } + + public async isAuthenticated(): Promise { + return this._authenticationClient.isAuthenticated(); + } +} diff --git a/packages/browser/src/__legacy__/helpers/index.ts b/packages/browser/src/__legacy__/helpers/index.ts new file mode 100644 index 000000000..03b8ee07a --- /dev/null +++ b/packages/browser/src/__legacy__/helpers/index.ts @@ -0,0 +1,21 @@ +/** +* Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +export * from "./authentication-helper"; +export * from "./spa-helper"; +export * from "./session-management-helper"; diff --git a/packages/browser/src/__legacy__/helpers/session-management-helper.ts b/packages/browser/src/__legacy__/helpers/session-management-helper.ts new file mode 100644 index 000000000..e6c70b85c --- /dev/null +++ b/packages/browser/src/__legacy__/helpers/session-management-helper.ts @@ -0,0 +1,312 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {AsgardeoAuthClient, GetAuthURLConfig, OIDCRequestConstants} from '@asgardeo/javascript'; +import { + CHECK_SESSION_SIGNED_IN, + CHECK_SESSION_SIGNED_OUT, + INITIALIZED_SILENT_SIGN_IN, + OP_IFRAME, + PROMPT_NONE_IFRAME, + RP_IFRAME, + SET_SESSION_STATE_FROM_IFRAME, + SILENT_SIGN_IN_STATE, + STATE, + STATE_QUERY, +} from '../constants'; +import {AuthorizationInfo, Message, SessionManagementHelperInterface} from '../models'; +import {Storage} from '../models/storage'; +import {SPAUtils} from '../utils'; + +export const SessionManagementHelper = (() => { + let _clientID: string; + let _checkSessionEndpoint: string; + let _sessionState: () => Promise; + let _interval: number; + let _redirectURL: string; + let _sessionRefreshInterval: number; + let _signOut: () => Promise; + let _sessionRefreshIntervalTimeout: number; + let _checkSessionIntervalTimeout: number; + let _storage: Storage; + let _setSessionState: (sessionState: string) => void; + let _getAuthorizationURL: (params?: GetAuthURLConfig) => Promise; + + const initialize = ( + clientID: string, + checkSessionEndpoint: string, + getSessionState: () => Promise, + interval: number, + sessionRefreshInterval: number, + redirectURL: string, + getAuthorizationURL: (params?: GetAuthURLConfig) => Promise, + ): void => { + _clientID = clientID; + _checkSessionEndpoint = checkSessionEndpoint; + _sessionState = getSessionState; + _interval = interval; + _redirectURL = redirectURL; + _sessionRefreshInterval = sessionRefreshInterval; + _getAuthorizationURL = getAuthorizationURL; + + if (_interval > -1) { + initiateCheckSession(); + } + + if (_sessionRefreshInterval > -1) { + sessionRefreshInterval = setInterval(() => { + sendPromptNoneRequest(); + }, _sessionRefreshInterval * 1000) as unknown as number; + } + }; + + const initiateCheckSession = async (): Promise => { + if (!_checkSessionEndpoint || !_clientID || !_redirectURL) { + return; + } + + const OP_IFRAME = 'opIFrame'; + + async function checkSession(): Promise { + const sessionState = await _sessionState(); + if (Boolean(_clientID) && Boolean(sessionState)) { + const message = `${_clientID} ${sessionState}`; + const rpIFrame = document.getElementById(RP_IFRAME) as HTMLIFrameElement; + const opIframe: HTMLIFrameElement = rpIFrame?.contentDocument?.getElementById(OP_IFRAME) as HTMLIFrameElement; + const win: Window | null = opIframe.contentWindow; + win?.postMessage(message, _checkSessionEndpoint); + } + } + + const rpIFrame = document.getElementById(RP_IFRAME) as HTMLIFrameElement; + const opIframe: HTMLIFrameElement = rpIFrame?.contentDocument?.getElementById(OP_IFRAME) as HTMLIFrameElement; + opIframe.src = _checkSessionEndpoint + '?client_id=' + _clientID + '&redirect_uri=' + _redirectURL; + + _checkSessionIntervalTimeout = setInterval(checkSession, _interval * 1000) as unknown as number; + + listenToResponseFromOPIFrame(); + }; + + /** + * Destroys session intervals. + */ + const reset = (): void => { + clearInterval(_checkSessionIntervalTimeout); + clearInterval(_sessionRefreshIntervalTimeout); + }; + + const listenToResponseFromOPIFrame = (): void => { + async function receiveMessage(e: MessageEvent) { + const targetOrigin = _checkSessionEndpoint; + + if (!targetOrigin || targetOrigin?.indexOf(e.origin) < 0 || e?.data?.type === SET_SESSION_STATE_FROM_IFRAME) { + return; + } + + if (e.data === 'unchanged') { + // [RP] session state has not changed + } else if (e.data === 'error') { + window.location.href = await _signOut(); + } else if (e.data === 'changed') { + // [RP] session state has changed. Sending prompt=none request... + sendPromptNoneRequest(); + } + } + + window?.addEventListener('message', receiveMessage, false); + }; + + const sendPromptNoneRequest = async () => { + const rpIFrame = document.getElementById(RP_IFRAME) as HTMLIFrameElement; + + const promptNoneIFrame: HTMLIFrameElement = rpIFrame?.contentDocument?.getElementById( + PROMPT_NONE_IFRAME, + ) as HTMLIFrameElement; + + if (SPAUtils.canSendPromptNoneRequest()) { + SPAUtils.setPromptNoneRequestSent(true); + + const receiveMessageListener = (e: MessageEvent>) => { + if (e?.data?.type === SET_SESSION_STATE_FROM_IFRAME) { + _setSessionState(e?.data?.data ?? ''); + window?.removeEventListener('message', receiveMessageListener); + } + }; + + if (_storage === Storage.BrowserMemory || _storage === Storage.WebWorker) { + window?.addEventListener('message', receiveMessageListener); + } + + const promptNoneURL: string = await _getAuthorizationURL({ + prompt: 'none', + response_mode: 'query', + state: STATE, + }); + + promptNoneIFrame.src = promptNoneURL; + } + }; + + /** + * This contains the logic to process the response of a prompt none request. + * + * @param setSessionState The method that sets the session state. + * on the output of the content of the redirect URL + */ + const receivePromptNoneResponse = async ( + setSessionState?: (sessionState: string | null) => Promise, + ): Promise => { + const state = new URL(window.location.href).searchParams.get(STATE_QUERY); + const sessionState = new URL(window.location.href).searchParams.get(OIDCRequestConstants.Params.SESSION_STATE); + const parent = window.parent.parent; + + if (state !== null && (state.includes(STATE) || state.includes(SILENT_SIGN_IN_STATE))) { + // Prompt none response. + const code = new URL(window.location.href).searchParams.get('code'); + + if (code !== null && code.length !== 0) { + if (state.includes(SILENT_SIGN_IN_STATE)) { + const message: Message = { + data: { + code, + sessionState: sessionState ?? '', + state, + }, + type: CHECK_SESSION_SIGNED_IN, + }; + + sessionStorage.setItem(INITIALIZED_SILENT_SIGN_IN, 'false'); + parent.postMessage(message, parent.origin); + SPAUtils.setPromptNoneRequestSent(false); + + window.location.href = 'about:blank'; + + await SPAUtils.waitTillPageRedirect(); + + return true; + } + + const newSessionState = new URL(window.location.href).searchParams.get('session_state'); + + if (_storage === Storage.LocalStorage || _storage === Storage.SessionStorage) { + setSessionState && (await setSessionState(newSessionState)); + } else { + const message: Message = { + data: newSessionState ?? '', + type: SET_SESSION_STATE_FROM_IFRAME, + }; + + window?.parent?.parent?.postMessage(message); + } + + SPAUtils.setPromptNoneRequestSent(false); + + window.location.href = 'about:blank'; + + await SPAUtils.waitTillPageRedirect(); + + return true; + } else { + if (state.includes(SILENT_SIGN_IN_STATE)) { + const message: Message = { + type: CHECK_SESSION_SIGNED_OUT, + }; + + window.parent.parent.postMessage(message, parent.origin); + SPAUtils.setPromptNoneRequestSent(false); + + window.location.href = 'about:blank'; + + await SPAUtils.waitTillPageRedirect(); + + return true; + } + + SPAUtils.setPromptNoneRequestSent(false); + + const signOutURL = await _signOut(); + // Clearing user session data before redirecting to the signOutURL because user has been already logged + // out by the initial logout request in the single logout flow. + await AsgardeoAuthClient.clearUserSessionData(); + parent.location.href = signOutURL; + window.location.href = 'about:blank'; + + await SPAUtils.waitTillPageRedirect(); + + return true; + } + } + + return false; + }; + + return async ( + signOut: () => Promise, + storage: Storage, + setSessionState: (sessionState: string) => void, + ): Promise => { + let rpIFrame = document.createElement('iframe'); + rpIFrame.setAttribute('id', RP_IFRAME); + rpIFrame.style.display = 'none'; + + let rpIframeLoaded: boolean = false; + rpIFrame.onload = () => { + rpIFrame = document.getElementById(RP_IFRAME) as HTMLIFrameElement; + + const rpDoc = rpIFrame?.contentDocument; + + const opIFrame = rpDoc?.createElement('iframe'); + if (opIFrame) { + opIFrame.setAttribute('id', OP_IFRAME); + opIFrame.style.display = 'none'; + } + + const promptNoneIFrame = rpDoc?.createElement('iframe'); + if (promptNoneIFrame) { + promptNoneIFrame.setAttribute('id', PROMPT_NONE_IFRAME); + promptNoneIFrame.style.display = 'none'; + } + + opIFrame && rpIFrame?.contentDocument?.body?.appendChild(opIFrame); + promptNoneIFrame && rpIFrame?.contentDocument?.body?.appendChild(promptNoneIFrame); + + rpIframeLoaded = true; + }; + + document?.body?.appendChild(rpIFrame); + + _signOut = signOut; + + _storage = storage; + _setSessionState = setSessionState; + + const sleep = (): Promise => { + return new Promise(resolve => setTimeout(resolve, 1)); + }; + + while (rpIframeLoaded === false) { + await sleep(); + } + + return { + initialize, + receivePromptNoneResponse, + reset, + }; + }; +})(); diff --git a/packages/browser/src/__legacy__/helpers/spa-helper.ts b/packages/browser/src/__legacy__/helpers/spa-helper.ts new file mode 100644 index 000000000..33cc0ac1e --- /dev/null +++ b/packages/browser/src/__legacy__/helpers/spa-helper.ts @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {AsgardeoAuthClient, DataLayer, TokenConstants} from '@asgardeo/javascript'; + +import {AuthenticationHelper} from '../helpers/authentication-helper'; +import {MainThreadClientConfig, WebWorkerClientConfig} from '../models/client-config'; + +export class SPAHelper { + private _authenticationClient: AsgardeoAuthClient; + private _dataLayer: DataLayer; + public constructor(authClient: AsgardeoAuthClient) { + this._authenticationClient = authClient; + this._dataLayer = this._authenticationClient.getDataLayer(); + } + + public async refreshAccessTokenAutomatically( + authenticationHelper: AuthenticationHelper, + ): Promise { + const shouldRefreshAutomatically: boolean = (await this._dataLayer.getConfigData())?.periodicTokenRefresh ?? false; + + if (!shouldRefreshAutomatically) { + return; + } + + const sessionData = await this._dataLayer.getSessionData(); + if (sessionData.refresh_token) { + // Refresh 10 seconds before the expiry time + const expiryTime = parseInt(sessionData.expires_in); + const time = expiryTime <= 10 ? expiryTime : expiryTime - 10; + + const timer = setTimeout(async () => { + await authenticationHelper.refreshAccessToken(); + }, time * 1000); + + await this._dataLayer.setTemporaryDataParameter( + TokenConstants.Storage.StorageKeys.REFRESH_TOKEN_TIMER, + JSON.stringify(timer), + ); + } + } + + public async getRefreshTimeoutTimer(): Promise { + if (await this._dataLayer.getTemporaryDataParameter(TokenConstants.Storage.StorageKeys.REFRESH_TOKEN_TIMER)) { + return JSON.parse( + (await this._dataLayer.getTemporaryDataParameter( + TokenConstants.Storage.StorageKeys.REFRESH_TOKEN_TIMER, + )) as string, + ); + } + + return -1; + } + + public async clearRefreshTokenTimeout(timer?: number): Promise { + if (timer) { + clearTimeout(timer); + + return; + } + + const refreshTimer: number = await this.getRefreshTimeoutTimer(); + + if (refreshTimer !== -1) { + clearTimeout(refreshTimer); + } + } +} diff --git a/packages/browser/src/__legacy__/http-client/clients/axios-http-client.ts b/packages/browser/src/__legacy__/http-client/clients/axios-http-client.ts new file mode 100755 index 000000000..ee39da645 --- /dev/null +++ b/packages/browser/src/__legacy__/http-client/clients/axios-http-client.ts @@ -0,0 +1,242 @@ +/** + * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +import axios from 'axios'; +import {HttpError, HttpRequestConfig, HttpResponse} from '../../..'; +import {staticDecorator} from '../helpers'; +import {HttpClientInstance, HttpClientInterface, HttpClientStatic} from '../models'; + +/** + * An Http Http client to perform Http requests. + * + * @remarks + * Typescript doesn't support static functions in interfaces. Therefore, + * a decorator i.e `staticDecorator` was written to add static support. + * Follow {@link https://github.com/Microsoft/TypeScript/issues/13462} + * for more info. + * + * @example + * Example usage. + * ``` + * + * const httpClient = HttpClient.getInstance(); + * httpClient.init(true, onRequestStart, onRequestSuccess, onRequestError, onRequestFinish); + * ``` + */ +@staticDecorator>() +export class HttpClient implements HttpClientInterface { + private static axiosInstance: HttpClientInstance; + private static clientInstance: HttpClient; + private static isHandlerEnabled: boolean; + private attachToken: (request: HttpRequestConfig) => Promise = () => Promise.resolve(); + private requestStartCallback: (request: HttpRequestConfig) => void = () => null; + private requestSuccessCallback: (response: HttpResponse) => void = () => null; + private requestErrorCallback: (error: HttpError) => void = () => null; + private requestFinishCallback: () => void = () => null; + private static readonly DEFAULT_HANDLER_DISABLE_TIMEOUT: number = 1000; + + /** + * Private constructor to avoid object instantiation from outside + * the class. + * + * @hideconstructor + */ + private constructor() { + this.init = this.init.bind(this); + this.setHttpRequestErrorCallback = this.setHttpRequestErrorCallback.bind(this); + this.setHttpRequestFinishCallback = this.setHttpRequestFinishCallback.bind(this); + this.setHttpRequestStartCallback = this.setHttpRequestStartCallback.bind(this); + this.setHttpRequestSuccessCallback = this.setHttpRequestSuccessCallback.bind(this); + } + + /** + * Returns an aggregated instance of type `HttpInstance` of `HttpClient`. + * + * @return {any} + */ + public static getInstance(): HttpClientInstance { + if (this.axiosInstance) { + return this.axiosInstance; + } + + this.axiosInstance = axios.create({ + withCredentials: true, + }); + + if (!this.clientInstance) { + this.clientInstance = new HttpClient(); + } + + // Register request interceptor + this.axiosInstance.interceptors.request.use(async request => await this.clientInstance.requestHandler(request)); + + // Register response interceptor + this.axiosInstance.interceptors.response.use( + response => this.clientInstance.successHandler(response), + error => this.clientInstance.errorHandler(error), + ); + + // Add the missing helper methods from axios + this.axiosInstance.all = axios.all; + this.axiosInstance.spread = axios.spread; + + // Add the init method from the `HttpClient` instance. + this.axiosInstance.init = this.clientInstance.init; + + // Add the handler enabling & disabling methods to the instance. + this.axiosInstance.enableHandler = this.clientInstance.enableHandler; + this.axiosInstance.disableHandler = this.clientInstance.disableHandler; + this.axiosInstance.disableHandlerWithTimeout = this.clientInstance.disableHandlerWithTimeout; + this.axiosInstance.setHttpRequestStartCallback = this.clientInstance.setHttpRequestStartCallback; + this.axiosInstance.setHttpRequestSuccessCallback = this.clientInstance.setHttpRequestSuccessCallback; + this.axiosInstance.setHttpRequestErrorCallback = this.clientInstance.setHttpRequestErrorCallback; + this.axiosInstance.setHttpRequestFinishCallback = this.clientInstance.setHttpRequestFinishCallback; + return this.axiosInstance; + } + + /** + * Intercepts all the requests. + * If the `isHandlerEnabled` flag is set to true, fires the `requestStartCallback` + * and retrieves the access token from the server and attaches it to the request. + * Else, just returns the original request. + * + * @param {HttpRequestConfig} request - Original request. + * @return {HttpRequestConfig} + */ + public async requestHandler(request: HttpRequestConfig): Promise { + await this.attachToken(request); + + if (request?.shouldEncodeToFormData) { + const data = request?.data; + const formData = new FormData(); + Object.keys(data).forEach(key => { + formData.append(key, data[key]); + }); + + request.data = formData; + } + + request.startTimeInMs = new Date().getTime(); + + if (HttpClient.isHandlerEnabled) { + if (this.requestStartCallback && typeof this.requestStartCallback === 'function') { + this.requestStartCallback(request); + } + } + return request; + } + + /** + * Handles response errors. + * If the `isHandlerEnabled` flag is set to true, fires the `requestErrorCallback` + * and the `requestFinishCallback` functions. Else, just returns the original error. + * + * @param {HttpError} error - Original error. + * @return {HttpError} + */ + public errorHandler(error: HttpError): HttpError { + if (HttpClient.isHandlerEnabled) { + if (this.requestErrorCallback && typeof this.requestErrorCallback === 'function') { + this.requestErrorCallback(error); + } + if (this.requestFinishCallback && typeof this.requestFinishCallback === 'function') { + this.requestFinishCallback(); + } + } + throw error; + } + + /** + * Handles response success. + * If the `isHandlerEnabled` flag is set to true, fires the `requestSuccessCallback` + * and the `requestFinishCallback` functions. Else, just returns the original response. + * + * @param {HttpResponse} response - Original response. + * @return {HttpResponse} + */ + public successHandler(response: HttpResponse): HttpResponse { + if (HttpClient.isHandlerEnabled) { + if (this.requestSuccessCallback && typeof this.requestSuccessCallback === 'function') { + this.requestSuccessCallback(response); + } + if (this.requestFinishCallback && typeof this.requestFinishCallback === 'function') { + this.requestFinishCallback(); + } + } + return response; + } + + /** + * Initializes the Http client. + * + * @param isHandlerEnabled - Flag to toggle handler enablement. + * @param requestStartCallback - Callback function to be triggered on request start. + * @param requestSuccessCallback - Callback function to be triggered on request success. + * @param requestErrorCallback - Callback function to be triggered on request error. + * @param requestFinishCallback - Callback function to be triggered on request error. + */ + public async init( + isHandlerEnabled = true, + attachToken: (request: HttpRequestConfig) => Promise, + ): Promise { + HttpClient.isHandlerEnabled = isHandlerEnabled; + this.attachToken = attachToken; + } + + /** + * Enables the handler. + */ + public enableHandler(): void { + HttpClient.isHandlerEnabled = true; + } + + /** + * Disables the handler. + */ + public disableHandler(): void { + HttpClient.isHandlerEnabled = false; + } + + /** + * Disables the handler for a given period of time. + * + * @param {number} timeout - Timeout in milliseconds. + */ + public disableHandlerWithTimeout(timeout: number = HttpClient.DEFAULT_HANDLER_DISABLE_TIMEOUT): void { + HttpClient.isHandlerEnabled = false; + + setTimeout(() => { + HttpClient.isHandlerEnabled = true; + }, timeout); + } + + public setHttpRequestStartCallback(callback: () => void): void { + this.requestStartCallback = callback; + } + + public setHttpRequestSuccessCallback(callback: (response: HttpResponse) => void): void { + this.requestSuccessCallback = callback; + } + public setHttpRequestErrorCallback(callback: (error: HttpError) => void): void { + this.requestErrorCallback = callback; + } + public setHttpRequestFinishCallback(callback: () => void): void { + this.requestFinishCallback = callback; + } +} diff --git a/packages/browser/src/__legacy__/http-client/clients/index.ts b/packages/browser/src/__legacy__/http-client/clients/index.ts new file mode 100644 index 000000000..126301e2d --- /dev/null +++ b/packages/browser/src/__legacy__/http-client/clients/index.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +export * from "./axios-http-client"; diff --git a/packages/browser/src/__legacy__/http-client/helpers/decorators.ts b/packages/browser/src/__legacy__/http-client/helpers/decorators.ts new file mode 100644 index 000000000..16be28c98 --- /dev/null +++ b/packages/browser/src/__legacy__/http-client/helpers/decorators.ts @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/* eslint-disable @typescript-eslint/no-empty-function */ +/* eslint-disable @typescript-eslint/no-unused-vars */ + +/** + * A decorator to supplement static interface support. + * + * @return {(constructor: U) => void} + */ +export function staticDecorator() { + return (_constructor: U): any => {}; +} diff --git a/packages/browser/src/__legacy__/http-client/helpers/index.ts b/packages/browser/src/__legacy__/http-client/helpers/index.ts new file mode 100644 index 000000000..01c98f57d --- /dev/null +++ b/packages/browser/src/__legacy__/http-client/helpers/index.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +export * from "./decorators"; diff --git a/packages/browser/src/__legacy__/http-client/index.ts b/packages/browser/src/__legacy__/http-client/index.ts new file mode 100644 index 000000000..b34e08dd2 --- /dev/null +++ b/packages/browser/src/__legacy__/http-client/index.ts @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +export * from "./clients"; +export * from "./models"; diff --git a/packages/browser/src/__legacy__/http-client/models/axios-http-client.ts b/packages/browser/src/__legacy__/http-client/models/axios-http-client.ts new file mode 100644 index 000000000..ebaf1d3cb --- /dev/null +++ b/packages/browser/src/__legacy__/http-client/models/axios-http-client.ts @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +import {HttpError, HttpInstance, HttpRequestConfig, HttpResponse} from '../../..'; + +/** + * Http Http Client model + */ +export interface HttpClientInstance extends HttpInstance { + init?(isHandlerEnabled: boolean, attachToken: (request: HttpRequestConfig) => Promise): Promise; + disableHandler?: () => void; + disableHandlerWithTimeout?: (timeout: number) => void; + enableHandler?: () => void; + all?(values: (T | Promise)[]): Promise; + spread?(callback: (...args: T[]) => R): (array: T[]) => R; + setHttpRequestStartCallback?: (callback: () => void) => void; + setHttpRequestSuccessCallback?: (callback: (response: HttpResponse) => void) => void; + setHttpRequestErrorCallback?: (callback: (error: HttpError) => void) => void; + setHttpRequestFinishCallback?: (callback: () => void) => void; +} diff --git a/packages/browser/src/__legacy__/http-client/models/http-client.ts b/packages/browser/src/__legacy__/http-client/models/http-client.ts new file mode 100644 index 000000000..d6e612fed --- /dev/null +++ b/packages/browser/src/__legacy__/http-client/models/http-client.ts @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +import { HttpError, HttpResponse } from "../../models"; + +/** + * Http client interface with static functions. + */ +export interface HttpClientStatic { + getInstance(): S; +} + +/** + * Http client interface. + */ +export interface HttpClientInterface { + init( + isHandlerEnabled: boolean, + attachToken: () => Promise + ): Promise; + disableHandler: () => void; + disableHandlerWithTimeout: (timeout: number) => void; + enableHandler: () => void; + errorHandler(error: V): V; + requestHandler(request: T): Promise; + successHandler(response: U): U; + setHttpRequestStartCallback?:(callback: () => void) => void; + setHttpRequestSuccessCallback?: (callback: (response: HttpResponse) => void) => void; + setHttpRequestErrorCallback?: (callback: (error: HttpError) => void) => void; + setHttpRequestFinishCallback?: (callback: () => void) => void; +} diff --git a/packages/browser/src/__legacy__/http-client/models/index.ts b/packages/browser/src/__legacy__/http-client/models/index.ts new file mode 100644 index 000000000..0addc03ee --- /dev/null +++ b/packages/browser/src/__legacy__/http-client/models/index.ts @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +export * from "./axios-http-client"; +export * from "./http-client"; diff --git a/packages/browser/src/__legacy__/models/client-config.ts b/packages/browser/src/__legacy__/models/client-config.ts new file mode 100644 index 000000000..c9930e8e0 --- /dev/null +++ b/packages/browser/src/__legacy__/models/client-config.ts @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {AuthClientConfig} from '@asgardeo/javascript'; +import {Storage} from './storage'; + +export interface SPAConfig { + /** + * Enable OIDC Session Management with PR Iframe. + * @remarks If the consumer app the OP is hosted in different domains, + * third party cookies has to be enabled for this to work properly. + */ + enableOIDCSessionManagement?: boolean; + checkSessionInterval?: number; + sessionRefreshInterval?: number; + resourceServerURLs?: string[]; + authParams?: Record; + periodicTokenRefresh?: boolean; + autoLogoutOnTokenRefreshError?: boolean; +} + +/** + * SDK Client config parameters. + */ +export interface MainThreadClientConfig extends SPAConfig { + /** + * The storage type to be used for storing the session information. + */ + storage?: + | Storage.SessionStorage + | Storage.LocalStorage + | Storage.BrowserMemory + | 'sessionStorage' + | 'localStorage' + | 'browserMemory'; +} + +export interface WebWorkerClientConfig extends SPAConfig { + /** + * The storage type to be used for storing the session information. + */ + storage: Storage.WebWorker | 'webWorker'; + /** + * Specifies in seconds how long a request to the web worker should wait before being timed. + */ + requestTimeout?: number; +} + +export type Config = MainThreadClientConfig | WebWorkerClientConfig; + +export type AuthSPAClientConfig = AuthClientConfig; diff --git a/packages/browser/src/__legacy__/models/client.ts b/packages/browser/src/__legacy__/models/client.ts new file mode 100755 index 000000000..286ac78be --- /dev/null +++ b/packages/browser/src/__legacy__/models/client.ts @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + AuthClientConfig, + BasicUserInfo, + IsomorphicCrypto, + CustomGrantConfig, + DataLayer, + IdTokenPayload, + FetchResponse, + OIDCEndpoints, +} from '@asgardeo/javascript'; +import { + HttpError, + HttpRequestConfig, + HttpResponse, + MainThreadClientConfig, + SignInConfig, + WebWorkerClientConfig, +} from '.'; +import {HttpClientInstance} from '../http-client'; + +export interface MainThreadClientInterface { + setHttpRequestStartCallback(callback: () => void): void; + setHttpRequestSuccessCallback(callback: (response: HttpResponse) => void): void; + setHttpRequestFinishCallback(callback: () => void): void; + setHttpRequestErrorCallback(callback: (error: HttpError) => void | Promise): void; + httpRequest(config: HttpRequestConfig): Promise; + httpRequestAll(config: HttpRequestConfig[]): Promise; + getHttpClient(): HttpClientInstance; + enableHttpHandler(): boolean; + disableHttpHandler(): boolean; + signIn( + config?: SignInConfig, + authorizationCode?: string, + sessionState?: string, + signInRedirectURL?: string, + tokenRequestConfig?: { + params: Record; + }, + ): Promise; + signOut(signOutRedirectURL?: string): Promise; + requestCustomGrant(config: CustomGrantConfig): Promise; + refreshAccessToken(): Promise; + revokeAccessToken(): Promise; + getBasicUserInfo(): Promise; + getDecodedIDToken(): Promise; + getCryptoHelper(): Promise; + getConfigData(): Promise>; + getIDToken(): Promise; + getOIDCServiceEndpoints(): Promise; + getAccessToken(): Promise; + getDataLayer(): Promise>; + isAuthenticated(): Promise; + updateConfig(config: Partial>): Promise; + trySignInSilently( + additionalParams?: Record, + tokenRequestConfig?: {params: Record}, + ): Promise; + isSessionActive(): Promise; +} + +export interface WebWorkerClientInterface { + requestCustomGrant(requestParams: CustomGrantConfig): Promise; + httpRequest(config: HttpRequestConfig): Promise>; + httpRequestAll(configs: HttpRequestConfig[]): Promise[]>; + enableHttpHandler(): Promise; + disableHttpHandler(): Promise; + initialize(): Promise; + signIn( + params?: SignInConfig, + authorizationCode?: string, + sessionState?: string, + signInRedirectURL?: string, + tokenRequestConfig?: { + params: Record; + }, + ): Promise; + signOut(signOutRedirectURL?: string): Promise; + revokeAccessToken(): Promise; + getOIDCServiceEndpoints(): Promise; + getBasicUserInfo(): Promise; + getConfigData(): Promise>; + getDecodedIDToken(): Promise; + getDecodedIDPIDToken(): Promise; + getCryptoHelper(): Promise; + getIDToken(): Promise; + isAuthenticated(): Promise; + setHttpRequestSuccessCallback(callback: (response: HttpResponse) => void): void; + setHttpRequestErrorCallback(callback: (response: HttpError) => void | Promise): void; + setHttpRequestStartCallback(callback: () => void): void; + setHttpRequestFinishCallback(callback: () => void): void; + refreshAccessToken(): Promise; + updateConfig(config: Partial>): Promise; + trySignInSilently( + additionalParams?: Record, + tokenRequestConfig?: {params: Record}, + ): Promise; +} diff --git a/packages/browser/src/__legacy__/models/http-client.ts b/packages/browser/src/__legacy__/models/http-client.ts new file mode 100755 index 000000000..8b05646dc --- /dev/null +++ b/packages/browser/src/__legacy__/models/http-client.ts @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2020-2024, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {AxiosRequestConfig} from 'axios'; +import {HttpClientInstance, HttpError, HttpResponse} from '.'; +import {SPACustomGrantConfig} from '../..'; + +export interface HttpClient { + requestStartCallback: () => void; + requestSuccessCallback: (response: HttpResponse) => void; + requestErrorCallback: (error: HttpError) => void | Promise; + requestFinishCallback: () => void; +} + +export interface HttpRequestInterface { + httpClient: HttpClientInstance; + requestConfig: HttpRequestConfig; + isHttpHandlerEnabled?: boolean; + httpErrorCallback?: (error: HttpError) => void | Promise; + httpFinishCallback?: () => void; + enableRetrievingSignOutURLFromSession?: (config: SPACustomGrantConfig) => void; +} + +export interface HttpRequestConfig extends AxiosRequestConfig { + attachToken?: boolean; + shouldEncodeToFormData?: boolean; + shouldAttachIDPAccessToken?: boolean; + startTimeInMs?: number; +} + +export { + AxiosResponse as HttpResponse, + Method as HttpMethod, + AxiosRequestTransformer as HttpRequestTransformer, + AxiosResponseTransformer as HttpResponseTransformer, + AxiosAdapter as HttpAdapter, + AxiosBasicCredentials as HttpBasicCredentials, + ResponseType, + AxiosProxyConfig as HttpProxyConfig, + CancelToken, + AxiosError as HttpError, + AxiosPromise as HttpPromise, + AxiosInstance as HttpInstance, +} from 'axios'; + +export {HttpClientInstance} from '../http-client'; diff --git a/packages/browser/src/__legacy__/models/index.ts b/packages/browser/src/__legacy__/models/index.ts new file mode 100644 index 000000000..0ae035f78 --- /dev/null +++ b/packages/browser/src/__legacy__/models/index.ts @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from './client'; +export * from './message'; +export * from './http-client'; +export * from './web-worker'; +export * from './session-management-helper'; +export * from './sign-in'; +export * from './sign-out-error'; + +export {Config as LegacyConfig} from './client-config'; +export {SPAConfig, MainThreadClientConfig, WebWorkerClientConfig, AuthSPAClientConfig} from './client-config'; diff --git a/packages/browser/src/__legacy__/models/message.ts b/packages/browser/src/__legacy__/models/message.ts new file mode 100644 index 000000000..e6285ae84 --- /dev/null +++ b/packages/browser/src/__legacy__/models/message.ts @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + AUTH_CODE, + CHECK_SESSION_SIGNED_IN, + CHECK_SESSION_SIGNED_OUT, + DISABLE_HTTP_HANDLER, + ENABLE_HTTP_HANDLER, + END_USER_SESSION, + GET_AUTH_URL, + GET_BASIC_USER_INFO, + GET_CONFIG_DATA, + GET_CRYPTO_HELPER, + GET_DECODED_IDP_ID_TOKEN, + GET_DECODED_ID_TOKEN, + GET_ID_TOKEN, + GET_OIDC_SERVICE_ENDPOINTS, + GET_SIGN_OUT_URL, + HTTP_REQUEST, + HTTP_REQUEST_ALL, + INIT, + IS_AUTHENTICATED, + REFRESH_ACCESS_TOKEN, + REFRESH_ACCESS_TOKEN_ERR0R, + REQUEST_ACCESS_TOKEN, + REQUEST_CUSTOM_GRANT, + REQUEST_ERROR, + REQUEST_FINISH, + REQUEST_START, + REQUEST_SUCCESS, + REVOKE_ACCESS_TOKEN, + SET_SESSION_STATE, + SET_SESSION_STATE_FROM_IFRAME, + SIGN_IN, + SIGN_OUT, + START_AUTO_REFRESH_TOKEN, + UPDATE_CONFIG +} from "../constants"; + +export interface ResponseMessage { + success: boolean; + error?: string; + data?: T; + blob?: Blob; +} + +export interface Message { + type: MessageType; + data?: T; +} + +export interface AuthorizationInfo { + code: string; + sessionState: string; + pkce?: string; + state: string; + tokenRequestConfig?: { + params: Record + } +} + +export type MessageType = + | typeof INIT + | typeof SIGN_IN + | typeof AUTH_CODE + | typeof SIGN_OUT + | typeof HTTP_REQUEST + | typeof HTTP_REQUEST_ALL + | typeof REQUEST_CUSTOM_GRANT + | typeof REVOKE_ACCESS_TOKEN + | typeof END_USER_SESSION + | typeof REQUEST_ERROR + | typeof REQUEST_FINISH + | typeof REQUEST_START + | typeof REQUEST_SUCCESS + | typeof GET_OIDC_SERVICE_ENDPOINTS + | typeof GET_BASIC_USER_INFO + | typeof GET_DECODED_ID_TOKEN + | typeof GET_CRYPTO_HELPER + | typeof GET_DECODED_IDP_ID_TOKEN + | typeof ENABLE_HTTP_HANDLER + | typeof DISABLE_HTTP_HANDLER + | typeof GET_AUTH_URL + | typeof REQUEST_ACCESS_TOKEN + | typeof IS_AUTHENTICATED + | typeof GET_SIGN_OUT_URL + | typeof REFRESH_ACCESS_TOKEN + | typeof REFRESH_ACCESS_TOKEN_ERR0R + | typeof SET_SESSION_STATE + | typeof START_AUTO_REFRESH_TOKEN + | typeof UPDATE_CONFIG + | typeof GET_ID_TOKEN + | typeof CHECK_SESSION_SIGNED_IN + | typeof CHECK_SESSION_SIGNED_OUT + | typeof GET_CONFIG_DATA + | typeof SET_SESSION_STATE_FROM_IFRAME; + +export interface CommunicationHelperInterface { + communicate: (message: Message) => Promise; +} + +export interface AuthorizationResponse { + authorizationURL: string; + pkce?: string; +} diff --git a/packages/browser/src/__legacy__/models/request-custom-grant.ts b/packages/browser/src/__legacy__/models/request-custom-grant.ts new file mode 100644 index 000000000..1c8b995f7 --- /dev/null +++ b/packages/browser/src/__legacy__/models/request-custom-grant.ts @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2022, WSO2 Inc. (http://www.wso2.com) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {CustomGrantConfig} from '@asgardeo/javascript'; + +/** + * SPA Custom Request Grant config model + */ +export interface SPACustomGrantConfig extends CustomGrantConfig { + preventSignOutURLUpdate?: boolean; +} diff --git a/packages/browser/src/__legacy__/models/session-management-helper.ts b/packages/browser/src/__legacy__/models/session-management-helper.ts new file mode 100644 index 000000000..795f830a5 --- /dev/null +++ b/packages/browser/src/__legacy__/models/session-management-helper.ts @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {GetAuthURLConfig} from '@asgardeo/javascript'; + +export interface SessionManagementHelperInterface { + initialize( + clientID: string, + checkSessionEndpoint: string, + getSessionState: () => Promise, + interval: number, + sessionRefreshInterval: number, + redirectURL: string, + getAuthorizationURL: (params?: GetAuthURLConfig) => Promise, + ): void; + receivePromptNoneResponse(setSessionState?: (sessionState: string | null) => Promise): Promise; + reset(); +} diff --git a/packages/browser/src/__legacy__/models/sign-in.ts b/packages/browser/src/__legacy__/models/sign-in.ts new file mode 100644 index 000000000..0ce815a57 --- /dev/null +++ b/packages/browser/src/__legacy__/models/sign-in.ts @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {GetAuthURLConfig} from '@asgardeo/javascript'; + +export type SignInConfig = GetAuthURLConfig & {callOnlyOnRedirect?: boolean}; diff --git a/packages/browser/src/__legacy__/models/sign-out-error.ts b/packages/browser/src/__legacy__/models/sign-out-error.ts new file mode 100644 index 000000000..af1ec0100 --- /dev/null +++ b/packages/browser/src/__legacy__/models/sign-out-error.ts @@ -0,0 +1,22 @@ +/** +* Copyright (c) 2022, WSO2 Inc. (http://www.wso2.com) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +export interface SignOutError { + error: string; + description: string; +} diff --git a/packages/browser/src/__legacy__/models/storage.ts b/packages/browser/src/__legacy__/models/storage.ts new file mode 100644 index 000000000..ef4150c5f --- /dev/null +++ b/packages/browser/src/__legacy__/models/storage.ts @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Enum for the different storage types. + */ +export enum Storage { + /** + * Stores the session information in the local storage + */ + LocalStorage = "localStorage", + /** + * Store the session information in the session storage. + */ + SessionStorage = "sessionStorage", + /** + * Store the session information in the web worker. + */ + WebWorker = "webWorker", + /** + * Store the session information in the browser memory. + */ + BrowserMemory = "browserMemory" +} diff --git a/packages/browser/src/__legacy__/models/web-worker.ts b/packages/browser/src/__legacy__/models/web-worker.ts new file mode 100755 index 000000000..f46ed5fed --- /dev/null +++ b/packages/browser/src/__legacy__/models/web-worker.ts @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + AuthClientConfig, + AuthorizationURLParams, + BasicUserInfo, + IsomorphicCrypto, + CustomGrantConfig, + IdTokenPayload, + FetchResponse, + OIDCEndpoints, +} from '@asgardeo/javascript'; +import {HttpRequestConfig, HttpResponse, Message} from '.'; +import {AuthorizationResponse, WebWorkerClientConfig} from '../..'; + +interface WebWorkerEvent extends MessageEvent { + data: Message; +} + +export class WebWorkerClass extends Worker { + public override onmessage: (this: Worker, event: WebWorkerEvent) => any = () => null; +} + +export interface WebWorkerCoreInterface { + setHttpRequestStartCallback(callback: () => void): void; + setHttpRequestSuccessCallback(callback: (response: HttpResponse) => void): void; + setHttpRequestFinishCallback(callback: () => void): void; + httpRequest(config: HttpRequestConfig): Promise; + httpRequestAll(configs: HttpRequestConfig[]): Promise; + enableHttpHandler(): void; + disableHttpHandler(): void; + getAuthorizationURL(params?: AuthorizationURLParams, signInRedirectURL?: string): Promise; + requestAccessToken( + authorizationCode?: string, + sessionState?: string, + pkce?: string, + state?: string, + ): Promise; + signOut(signOutRedirectURL?: string): Promise; + getSignOutURL(signOutRedirectURL?: string): Promise; + requestCustomGrant(config: CustomGrantConfig): Promise; + refreshAccessToken(): Promise; + revokeAccessToken(): Promise; + getBasicUserInfo(): Promise; + getDecodedIDToken(): Promise; + getDecodedIDPIDToken(): Promise; + getCryptoHelper(): Promise; + getIDToken(): Promise; + getOIDCServiceEndpoints(): Promise; + getAccessToken(): Promise; + isAuthenticated(): Promise; + startAutoRefreshToken(): Promise; + setSessionState(sessionState: string): Promise; + updateConfig(config: Partial>): Promise; + getConfigData(): Promise>; +} diff --git a/packages/browser/src/__legacy__/stores/index.ts b/packages/browser/src/__legacy__/stores/index.ts new file mode 100644 index 000000000..4c1a1f2cd --- /dev/null +++ b/packages/browser/src/__legacy__/stores/index.ts @@ -0,0 +1,21 @@ +/** +* Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +export * from "./local-store"; +export * from "./memory-store"; +export * from "./session-store"; diff --git a/packages/browser/src/__legacy__/stores/local-store.ts b/packages/browser/src/__legacy__/stores/local-store.ts new file mode 100644 index 000000000..0a0d0e6f4 --- /dev/null +++ b/packages/browser/src/__legacy__/stores/local-store.ts @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import {Store} from '@asgardeo/javascript'; + +export class LocalStore implements Store { + public async setData(key: string, value: string): Promise { + localStorage.setItem(key, value); + } + + public async getData(key: string): Promise { + return localStorage.getItem(key) ?? '{}'; + } + + public async removeData(key: string): Promise { + localStorage.removeItem(key); + } +} diff --git a/packages/browser/src/__legacy__/stores/memory-store.ts b/packages/browser/src/__legacy__/stores/memory-store.ts new file mode 100644 index 000000000..f1362eca0 --- /dev/null +++ b/packages/browser/src/__legacy__/stores/memory-store.ts @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import {Store} from '@asgardeo/javascript'; + +export class MemoryStore implements Store { + private _data: Map; + + public constructor() { + this._data = new Map(); + } + + public async setData(key: string, value: string): Promise { + this._data.set(key, value); + } + + public async getData(key: string): Promise { + return this._data?.get(key) ?? '{}'; + } + + public async removeData(key: string): Promise { + this._data.delete(key); + } +} diff --git a/packages/browser/src/__legacy__/stores/session-store.ts b/packages/browser/src/__legacy__/stores/session-store.ts new file mode 100644 index 000000000..b963ec38c --- /dev/null +++ b/packages/browser/src/__legacy__/stores/session-store.ts @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import {Store} from '@asgardeo/javascript'; + +export class SessionStore implements Store { + public async setData(key: string, value: string): Promise { + sessionStorage.setItem(key, value); + } + + public async getData(key: string): Promise { + return sessionStorage.getItem(key) ?? '{}'; + } + + public async removeData(key: string): Promise { + sessionStorage.removeItem(key); + } +} diff --git a/packages/browser/src/__legacy__/utils/crypto-utils.ts b/packages/browser/src/__legacy__/utils/crypto-utils.ts new file mode 100644 index 000000000..3958ab0f2 --- /dev/null +++ b/packages/browser/src/__legacy__/utils/crypto-utils.ts @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {Buffer} from 'buffer'; +import {AsgardeoAuthException, Crypto, JWKInterface} from '@asgardeo/javascript'; +import base64url from 'base64url'; +import sha256 from 'fast-sha256'; +import {createLocalJWKSet, jwtVerify} from 'jose'; +import randombytes from 'randombytes'; + +export class SPACryptoUtils implements Crypto { + /** + * Get URL encoded string. + * + * @returns {string} base 64 url encoded value. + */ + public base64URLEncode(value: Buffer | string): string { + return base64url.encode(value).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); + } + + public base64URLDecode(value: string): string { + return base64url.decode(value).toString(); + } + + public hashSha256(data: string): string | Buffer { + return Buffer.from(sha256(new TextEncoder().encode(data))); + } + + public generateRandomBytes(length: number): string | Buffer { + return randombytes(length); + } + + public verifyJwt( + idToken: string, + jwk: Partial, + algorithms: string[], + clientID: string, + issuer: string, + subject: string, + clockTolerance?: number, + validateJwtIssuer?: boolean, + ): Promise { + const jwtVerifyOptions = { + algorithms: algorithms, + audience: clientID, + clockTolerance: clockTolerance, + subject: subject, + }; + + if (validateJwtIssuer ?? true) { + jwtVerifyOptions['issuer'] = issuer; + } + + return jwtVerify( + idToken, + createLocalJWKSet({ + keys: [jwk], + }), + jwtVerifyOptions, + ) + .then(() => { + return Promise.resolve(true); + }) + .catch(error => { + return Promise.reject( + new AsgardeoAuthException( + 'SPA-CRYPTO-UTILS-VJ-IV01', + error?.reason ?? JSON.stringify(error), + `${error?.code} ${error?.claim}`, + ), + ); + }); + } +} diff --git a/packages/browser/src/__legacy__/utils/index.ts b/packages/browser/src/__legacy__/utils/index.ts new file mode 100644 index 000000000..ca1d41288 --- /dev/null +++ b/packages/browser/src/__legacy__/utils/index.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from "./message-utils"; +export * from "./spa-utils"; diff --git a/packages/browser/src/__legacy__/utils/message-utils.ts b/packages/browser/src/__legacy__/utils/message-utils.ts new file mode 100644 index 000000000..466f564be --- /dev/null +++ b/packages/browser/src/__legacy__/utils/message-utils.ts @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { ResponseMessage } from "../models"; + +export class MessageUtils { + + // eslint-disable-next-line @typescript-eslint/no-empty-function + private constructor() { } + + /** + * JSON stringifies the passed object. + * + * @param {any} data The data object. + * + * @return {ResponseMessage} JSON string. + */ + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + public static generateSuccessMessage(data?: any): ResponseMessage{ + return { + blob: data?.data instanceof Blob ? data?.data : null, + data: JSON.stringify(data ?? ""), + success: true + }; + } + + /** + * JSON stringifies the passed object. + * + * @param {any} error The error object. + * + * @return {ResponseMessage} JSON string. + */ + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + public static generateFailureMessage(error?: any): ResponseMessage { + if (error?.toJSON) { + delete error.toJSON; + } + + return { + error: JSON.stringify(error ?? ""), + success: false + }; + } +} diff --git a/packages/browser/src/__legacy__/utils/spa-utils.ts b/packages/browser/src/__legacy__/utils/spa-utils.ts new file mode 100644 index 000000000..f20583d42 --- /dev/null +++ b/packages/browser/src/__legacy__/utils/spa-utils.ts @@ -0,0 +1,234 @@ +/** + * Copyright (c) 2020-2024, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {AsgardeoAuthClient, OIDCRequestConstants} from '@asgardeo/javascript'; +import {SignOutError} from '../..'; +import { + ERROR, + ERROR_DESCRIPTION, + INITIALIZED_SILENT_SIGN_IN, + PROMPT_NONE_REQUEST_SENT, + SILENT_SIGN_IN_STATE, + STATE_QUERY, +} from '../constants'; + +export class SPAUtils { + // eslint-disable-next-line @typescript-eslint/no-empty-function + private constructor() {} + + public static removeAuthorizationCode(): void { + const url = location.href; + + history.pushState({}, document.title, url.replace(/\?code=.*$/, '')); + } + + public static getPKCE(pkceKey: string): string { + return sessionStorage.getItem(pkceKey) ?? ''; + } + + public static setPKCE(pkceKey: string, pkce: string): void { + sessionStorage.setItem(pkceKey, pkce); + } + + public static setSignOutURL(url: string, clientID: string, instanceID: number): void { + sessionStorage.setItem( + `${OIDCRequestConstants.SignOut.Storage.StorageKeys.SIGN_OUT_URL}-instance_${instanceID}-${clientID}`, + url, + ); + } + + public static getSignOutURL(clientID: string, instanceID: number): string { + return ( + sessionStorage.getItem( + `${OIDCRequestConstants.SignOut.Storage.StorageKeys.SIGN_OUT_URL}-instance_${instanceID}-${clientID}`, + ) ?? '' + ); + } + + public static removePKCE(pkceKey: string): void { + sessionStorage.removeItem(pkceKey); + } + + /** + * This method is used to discontinue the execution of the `signIn` method if `callOnlyOnRedirect` is true and + * the method is not called on being redirected from the authorization server. + * + * This method can be used to allow the `signIn` method to be called only + * on being redirected from the authorization server. + * + * @param callOnlyOnRedirect {boolean} - True if the method should only be called on redirect. + * @param authorizationCode {string} - Authorization code. + * + * @returns {boolean} - True if the method should be called. + */ + public static canContinueSignIn(callOnlyOnRedirect: boolean, authorizationCode?: string): boolean { + if (callOnlyOnRedirect && !SPAUtils.hasErrorInURL() && !SPAUtils.hasAuthSearchParamsInURL() && !authorizationCode) { + return false; + } + + return true; + } + + /** + * Specifies if `trySilentSignIn` has been called. + * + * @returns {boolean} True if the `trySilentSignIn` method has been called once. + */ + public static isInitializedSilentSignIn(): boolean { + return SPAUtils.isSilentStatePresentInURL(); + } + + /** + * Specifies if the `signIn` method has been called. + * + * @returns {boolean} True if the `signIn` has been called. + */ + public static wasSignInCalled(): boolean { + if (SPAUtils.hasErrorInURL() || SPAUtils.hasAuthSearchParamsInURL()) { + if (!this.isSilentStatePresentInURL()) { + return true; + } + } + + return false; + } + + public static wasSilentSignInCalled(): boolean { + const silentSignIsInitialized = sessionStorage.getItem(INITIALIZED_SILENT_SIGN_IN); + const isSilentSignInInitialized = silentSignIsInitialized ? JSON.parse(silentSignIsInitialized) : null; + + return Boolean(isSilentSignInInitialized); + } + + public static async isSignOutSuccessful(): Promise { + if (AsgardeoAuthClient.isSignOutSuccessful(window.location.href)) { + const newUrl = window.location.href.split('?')[0]; + history.pushState({}, document.title, newUrl); + + await AsgardeoAuthClient.clearUserSessionData(); + + return true; + } + return false; + } + + public static didSignOutFail(): boolean | SignOutError { + if (AsgardeoAuthClient.didSignOutFail(window.location.href)) { + const url: URL = new URL(window.location.href); + const error: string | null = url.searchParams.get(ERROR); + const description: string | null = url.searchParams.get(ERROR_DESCRIPTION); + const newUrl = window.location.href.split('?')[0]; + history.pushState({}, document.title, newUrl); + + return { + description: description ?? '', + error: error ?? '', + }; + } + + return false; + } + + /** + * Checks if the URL the user agent is redirected to after an authorization request has the state parameter. + * + * @returns {boolean} True if there is a session-check state or a silent sign-in state. + */ + public static isSilentStatePresentInURL(): boolean { + const state = new URL(window.location.href).searchParams.get('state'); + + return state?.includes(SILENT_SIGN_IN_STATE) ?? false; + } + + /** + * Util function to test if `code` and `session_state` are available in the URL as search params. + * @since 0.2.0 + * @deprecated Use `hasAuthParamsInUrl` from `@asgardeo/browser` instead. + * + * @param params - Search params. + * @return {boolean} + */ + public static hasAuthSearchParamsInURL(params: string = window.location.search): boolean { + const AUTH_CODE_REGEXP: RegExp = /[?&]code=[^&]+/; + + return AUTH_CODE_REGEXP.test(params); + } + + /** + * Util function to check if the URL contains an error. + * + * @param url - URL to be checked. + * + * @returns {boolean} - True if the URL contains an error. + */ + public static hasErrorInURL(url: string = window.location.href): boolean { + const urlObject: URL = new URL(url); + return ( + !!urlObject.searchParams.get(ERROR) && + urlObject.searchParams.get(STATE_QUERY) !== OIDCRequestConstants.Params.SIGN_OUT_SUCCESS + ); + } + + /** + * Checks if a prompt none can be sent by checking if a request has already been sent. + * + * @since 0.2.3 + * + * @returns {boolean} - True if a prompt none request has not been sent. + */ + public static canSendPromptNoneRequest(): boolean { + const promptNoneRequestSentRaw = sessionStorage.getItem(PROMPT_NONE_REQUEST_SENT); + const promptNoneRequestSent = promptNoneRequestSentRaw ? JSON.parse(promptNoneRequestSentRaw) : null; + + return !promptNoneRequestSent; + } + + /** + * Sets the status of prompt none request. + * + * @since 0.2.3 + * + * @param canSend {boolean} - True if a prompt none request can be sent. + */ + public static setPromptNoneRequestSent(canSend: boolean): void { + sessionStorage.setItem(PROMPT_NONE_REQUEST_SENT, JSON.stringify(canSend)); + } + + /** + * Waits for a specified amount of time to give the user agent enough time to redirect. + * + * @param time {number} - Time in seconds. + */ + public static async waitTillPageRedirect(time?: number): Promise { + const timeToWait = time ?? 3000; + + await new Promise(resolve => setTimeout(resolve, timeToWait * 1000)); + } + + /** + * Waits for a condition before executing the rest of the code in non-blocking manner. + * + * @param condition {() => boolean} - Condition to be checked. + * @param timeout {number} - Time in miliseconds. + */ + public static until = (condition: () => boolean, timeout: number = 500) => { + const poll = done => (condition() ? done() : setTimeout(() => poll(done), timeout)); + + return new Promise(poll); + }; +} diff --git a/packages/browser/src/__legacy__/worker/index.ts b/packages/browser/src/__legacy__/worker/index.ts new file mode 100644 index 000000000..2bef373ce --- /dev/null +++ b/packages/browser/src/__legacy__/worker/index.ts @@ -0,0 +1,20 @@ +/** +* Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +export * from "./worker-receiver"; +export * from "./worker-core"; diff --git a/packages/browser/src/__legacy__/worker/worker-core.ts b/packages/browser/src/__legacy__/worker/worker-core.ts new file mode 100755 index 000000000..38b672971 --- /dev/null +++ b/packages/browser/src/__legacy__/worker/worker-core.ts @@ -0,0 +1,244 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + AsgardeoAuthClient, + AuthClientConfig, + AuthorizationURLParams, + BasicUserInfo, + IsomorphicCrypto, + CustomGrantConfig, + IdTokenPayload, + FetchResponse, + OIDCEndpoints, + OIDCRequestConstants, + SessionData, + Store, +} from '@asgardeo/javascript'; +import {AuthenticationHelper, SPAHelper} from '../helpers'; +import {HttpClient, HttpClientInstance} from '../http-client'; +import { + AuthorizationResponse, + HttpRequestConfig, + HttpResponse, + WebWorkerClientConfig, + WebWorkerCoreInterface, +} from '../models'; +import {MemoryStore} from '../stores'; +import {SPACryptoUtils} from '../utils/crypto-utils'; + +export const WebWorkerCore = async ( + config: AuthClientConfig, + getAuthHelper: ( + authClient: AsgardeoAuthClient, + spaHelper: SPAHelper, + ) => AuthenticationHelper, +): Promise => { + const _store: Store = new MemoryStore(); + const _cryptoUtils: SPACryptoUtils = new SPACryptoUtils(); + const _authenticationClient = new AsgardeoAuthClient(); + await _authenticationClient.initialize(config, _store, _cryptoUtils); + + const _spaHelper = new SPAHelper(_authenticationClient); + + const _authenticationHelper: AuthenticationHelper = getAuthHelper( + _authenticationClient, + _spaHelper, + ); + + const _dataLayer = _authenticationClient.getDataLayer(); + + const _httpClient: HttpClientInstance = HttpClient.getInstance(); + + const attachToken = async (request: HttpRequestConfig): Promise => { + await _authenticationHelper.attachTokenToRequestConfig(request); + }; + + _httpClient?.init && (await _httpClient.init(true, attachToken)); + + const setHttpRequestStartCallback = (callback: () => void): void => { + _httpClient?.setHttpRequestStartCallback && _httpClient.setHttpRequestStartCallback(callback); + }; + + const setHttpRequestSuccessCallback = (callback: (response: HttpResponse) => void): void => { + _httpClient?.setHttpRequestSuccessCallback && _httpClient.setHttpRequestSuccessCallback(callback); + }; + + const setHttpRequestFinishCallback = (callback: () => void): void => { + _httpClient?.setHttpRequestFinishCallback && _httpClient.setHttpRequestFinishCallback(callback); + }; + + const httpRequest = async (requestConfig: HttpRequestConfig): Promise => { + return await _authenticationHelper.httpRequest(_httpClient, requestConfig); + }; + + const httpRequestAll = async (requestConfigs: HttpRequestConfig[]): Promise => { + return await _authenticationHelper.httpRequestAll(requestConfigs, _httpClient); + }; + + const enableHttpHandler = (): void => { + _authenticationHelper.enableHttpHandler(_httpClient); + }; + + const disableHttpHandler = (): void => { + _authenticationHelper.disableHttpHandler(_httpClient); + }; + + const getAuthorizationURL = async (params?: AuthorizationURLParams): Promise => { + return _authenticationClient + .getAuthorizationURL(params) + .then(async (url: string) => { + const urlObject: URL = new URL(url); + const state: string = urlObject.searchParams.get(OIDCRequestConstants.Params.STATE) ?? ''; + const pkce: string = await _authenticationClient.getPKCECode(state); + + return {authorizationURL: url, pkce: pkce}; + }) + .catch(error => Promise.reject(error)); + }; + + const startAutoRefreshToken = async (): Promise => { + _spaHelper.clearRefreshTokenTimeout(); + _spaHelper.refreshAccessTokenAutomatically(_authenticationHelper); + + return; + }; + + const requestAccessToken = async ( + authorizationCode?: string, + sessionState?: string, + pkce?: string, + state?: string, + ): Promise => { + return await _authenticationHelper.requestAccessToken(authorizationCode, sessionState, undefined, pkce, state); + }; + + const signOut = async (): Promise => { + _spaHelper.clearRefreshTokenTimeout(); + + return await _authenticationClient.getSignOutURL(); + }; + + const getSignOutURL = async (): Promise => { + return await _authenticationClient.getSignOutURL(); + }; + + const requestCustomGrant = async (config: CustomGrantConfig): Promise => { + return await _authenticationHelper.requestCustomGrant(config); + }; + + const refreshAccessToken = async (): Promise => { + try { + return await _authenticationHelper.refreshAccessToken(); + } catch (error) { + return Promise.reject(error); + } + }; + + const revokeAccessToken = async (): Promise => { + const timer: number = await _spaHelper.getRefreshTimeoutTimer(); + + return _authenticationClient + .revokeAccessToken() + .then(() => { + _spaHelper.clearRefreshTokenTimeout(timer); + + return Promise.resolve(true); + }) + .catch(error => Promise.reject(error)); + }; + + const getBasicUserInfo = async (): Promise => { + return _authenticationHelper.getBasicUserInfo(); + }; + + const getDecodedIDToken = async (): Promise => { + return _authenticationHelper.getDecodedIDToken(); + }; + + const getCryptoHelper = async (): Promise => { + return _authenticationHelper.getCryptoHelper(); + }; + + const getDecodedIDPIDToken = async (): Promise => { + return _authenticationHelper.getDecodedIDPIDToken(); + }; + + const getIDToken = async (): Promise => { + return _authenticationHelper.getIDToken(); + }; + const getOIDCServiceEndpoints = async (): Promise => { + return _authenticationHelper.getOIDCServiceEndpoints(); + }; + + const getAccessToken = (): Promise => { + return _authenticationHelper.getAccessToken(); + }; + + const isAuthenticated = (): Promise => { + return _authenticationHelper.isAuthenticated(); + }; + + const setSessionState = async (sessionState: string): Promise => { + await _dataLayer.setSessionDataParameter( + OIDCRequestConstants.Params.SESSION_STATE as keyof SessionData, + sessionState, + ); + + return; + }; + + const updateConfig = async (config: Partial>): Promise => { + await _authenticationClient.updateConfig(config); + + return; + }; + + const getConfigData = async (): Promise> => { + return _dataLayer.getConfigData(); + }; + + return { + disableHttpHandler, + enableHttpHandler, + getAccessToken, + getAuthorizationURL, + getBasicUserInfo, + getConfigData, + getCryptoHelper, + getDecodedIDPIDToken, + getDecodedIDToken, + getIDToken, + getOIDCServiceEndpoints, + getSignOutURL, + httpRequest, + httpRequestAll, + isAuthenticated, + refreshAccessToken, + requestAccessToken, + requestCustomGrant, + revokeAccessToken, + setHttpRequestFinishCallback, + setHttpRequestStartCallback, + setHttpRequestSuccessCallback, + setSessionState, + signOut, + startAutoRefreshToken, + updateConfig, + }; +}; diff --git a/packages/browser/src/__legacy__/worker/worker-receiver.ts b/packages/browser/src/__legacy__/worker/worker-receiver.ts new file mode 100644 index 000000000..094b52c9f --- /dev/null +++ b/packages/browser/src/__legacy__/worker/worker-receiver.ts @@ -0,0 +1,314 @@ +/** + * Copyright (c) 2022, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {AsgardeoAuthClient, AsgardeoAuthException, AuthClientConfig, BasicUserInfo} from '@asgardeo/javascript'; +import {WebWorkerCore} from './worker-core'; +import { + DISABLE_HTTP_HANDLER, + ENABLE_HTTP_HANDLER, + GET_AUTH_URL, + GET_BASIC_USER_INFO, + GET_CONFIG_DATA, + GET_CRYPTO_HELPER, + GET_DECODED_ID_TOKEN, + GET_ID_TOKEN, + GET_OIDC_SERVICE_ENDPOINTS, + GET_SIGN_OUT_URL, + HTTP_REQUEST, + HTTP_REQUEST_ALL, + INIT, + IS_AUTHENTICATED, + REFRESH_ACCESS_TOKEN, + REQUEST_ACCESS_TOKEN, + REQUEST_CUSTOM_GRANT, + REQUEST_FINISH, + REQUEST_START, + REQUEST_SUCCESS, + REVOKE_ACCESS_TOKEN, + SET_SESSION_STATE, + SIGN_OUT, + START_AUTO_REFRESH_TOKEN, + UPDATE_CONFIG, +} from '../constants'; +import {AuthenticationHelper, SPAHelper} from '../helpers'; +import { + AuthorizationResponse, + HttpResponse, + WebWorkerClass, + WebWorkerClientConfig, + WebWorkerCoreInterface, +} from '../models'; +import {MessageUtils} from '../utils'; + +export const workerReceiver = ( + getAuthHelper: ( + authClient: AsgardeoAuthClient, + spaHelper: SPAHelper, + ) => AuthenticationHelper, +) => { + const ctx: WebWorkerClass = self as any; + + let webWorker: WebWorkerCoreInterface; + + ctx.onmessage = async ({data, ports}) => { + const port = ports[0]; + if (data.type !== INIT && !webWorker) { + port.postMessage( + MessageUtils.generateFailureMessage( + new AsgardeoAuthException( + 'SPA-CLIENT_WORKER-ONMSG-NF01', + 'The web worker has not been initialized yet.', + 'The initialize method needs to be called before the specified operation can be carried out.', + ), + ), + ); + + return; + } + + switch (data.type) { + case INIT: + try { + const config: AuthClientConfig = {...data.data}; + webWorker = await WebWorkerCore(config, getAuthHelper); + webWorker.setHttpRequestFinishCallback(onRequestFinishCallback); + webWorker.setHttpRequestStartCallback(onRequestStartCallback); + webWorker.setHttpRequestSuccessCallback(onRequestSuccessCallback); + port.postMessage(MessageUtils.generateSuccessMessage()); + } catch (error) { + port.postMessage(MessageUtils.generateFailureMessage(error)); + } + + break; + case GET_AUTH_URL: + webWorker + .getAuthorizationURL(data?.data) + .then((response: AuthorizationResponse) => { + port.postMessage(MessageUtils.generateSuccessMessage(response)); + }) + .catch(error => { + port.postMessage(MessageUtils.generateFailureMessage(error)); + }); + + break; + case REQUEST_ACCESS_TOKEN: + webWorker + .requestAccessToken(data?.data?.code, data?.data?.sessionState, data?.data?.pkce, data?.data?.state) + .then((response: BasicUserInfo) => { + port.postMessage(MessageUtils.generateSuccessMessage(response)); + }) + .catch(error => { + port.postMessage(MessageUtils.generateFailureMessage(error)); + }); + + break; + case HTTP_REQUEST: { + const request = data.data; + const requestData = request?.data; + if (data.data?.data?.formData === true) { + const formData = new FormData(); + for (const key in requestData) { + if (key === 'formData') { + continue; + } + formData.append(key, requestData[key]); + } + request.data = formData; + } + webWorker + .httpRequest(request) + .then(response => { + port.postMessage(MessageUtils.generateSuccessMessage(response)); + }) + .catch(error => { + port.postMessage(MessageUtils.generateFailureMessage(error)); + }); + + break; + } + case HTTP_REQUEST_ALL: + webWorker + .httpRequestAll(data.data) + .then(response => { + port.postMessage(MessageUtils.generateSuccessMessage(response)); + }) + .catch(error => { + port.postMessage(MessageUtils.generateFailureMessage(error)); + }); + + break; + case SIGN_OUT: + try { + port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.signOut())); + } catch (error) { + port.postMessage(MessageUtils.generateFailureMessage(error)); + } + + break; + case REQUEST_CUSTOM_GRANT: + webWorker + .requestCustomGrant(data.data) + .then(response => { + port.postMessage(MessageUtils.generateSuccessMessage(response)); + }) + .catch(error => { + port.postMessage(MessageUtils.generateFailureMessage(error)); + }); + + break; + case REVOKE_ACCESS_TOKEN: + webWorker + .revokeAccessToken() + .then(response => { + port.postMessage(MessageUtils.generateSuccessMessage(response)); + }) + .catch(error => { + port.postMessage(MessageUtils.generateFailureMessage(error)); + }); + break; + case GET_OIDC_SERVICE_ENDPOINTS: + try { + port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.getOIDCServiceEndpoints())); + } catch (error) { + port.postMessage(MessageUtils.generateFailureMessage(error)); + } + + break; + case GET_BASIC_USER_INFO: + try { + port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.getBasicUserInfo())); + } catch (error) { + port.postMessage(MessageUtils.generateFailureMessage(error)); + } + + break; + case GET_DECODED_ID_TOKEN: + try { + port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.getDecodedIDToken())); + } catch (error) { + port.postMessage(MessageUtils.generateFailureMessage(error)); + } + + break; + case GET_CRYPTO_HELPER: + try { + port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.getCryptoHelper())); + } catch (error) { + port.postMessage(MessageUtils.generateFailureMessage(error)); + } + + break; + case GET_ID_TOKEN: + try { + port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.getIDToken())); + } catch (error) { + port.postMessage(MessageUtils.generateFailureMessage(error)); + } + + break; + case ENABLE_HTTP_HANDLER: + webWorker.enableHttpHandler(); + port.postMessage(MessageUtils.generateSuccessMessage()); + + break; + case DISABLE_HTTP_HANDLER: + webWorker.disableHttpHandler(); + port.postMessage(MessageUtils.generateSuccessMessage()); + + break; + case IS_AUTHENTICATED: + try { + port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.isAuthenticated())); + } catch (error) { + port.postMessage(MessageUtils.generateFailureMessage(error)); + } + + break; + case GET_SIGN_OUT_URL: + try { + port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.getSignOutURL())); + } catch (error) { + port.postMessage(MessageUtils.generateFailureMessage(error)); + } + + break; + case REFRESH_ACCESS_TOKEN: + try { + port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.refreshAccessToken())); + } catch (error) { + port.postMessage(MessageUtils.generateFailureMessage(error)); + } + + break; + case START_AUTO_REFRESH_TOKEN: + try { + port.postMessage(MessageUtils.generateSuccessMessage(webWorker.startAutoRefreshToken())); + } catch (error) { + port.postMessage(MessageUtils.generateFailureMessage(error)); + } + + break; + case SET_SESSION_STATE: + try { + port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.setSessionState(data?.data))); + } catch (error) { + port.postMessage(MessageUtils.generateFailureMessage(error)); + } + + break; + case UPDATE_CONFIG: + try { + port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.updateConfig(data?.data))); + } catch (error) { + port.postMessage(MessageUtils.generateFailureMessage(error)); + } + + break; + case GET_CONFIG_DATA: + try { + port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.getConfigData())); + } catch (error) { + port.postMessage(MessageUtils.generateFailureMessage(error)); + } + + break; + default: + port?.postMessage( + MessageUtils.generateFailureMessage( + new AsgardeoAuthException( + 'SPA-CLIENT_WORKER-ONMSG-IV02', + 'The message type is invalid.', + `The message type provided, ${data.type}, is invalid.`, + ), + ), + ); + } + }; + + const onRequestStartCallback = (): void => { + ctx.postMessage({type: REQUEST_START}); + }; + + const onRequestSuccessCallback = (response: HttpResponse): void => { + ctx.postMessage({data: JSON.stringify(response ?? ''), type: REQUEST_SUCCESS}); + }; + + const onRequestFinishCallback = (): void => { + ctx.postMessage({type: REQUEST_FINISH}); + }; +}; diff --git a/packages/browser/src/__tests__/.gitkeep b/packages/browser/src/__tests__/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/packages/browser/src/constants/StyleConstants.ts b/packages/browser/src/constants/StyleConstants.ts new file mode 100644 index 000000000..6b7bbf9ab --- /dev/null +++ b/packages/browser/src/constants/StyleConstants.ts @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Class defining style constants for the downstream libraries. + */ +class StyleConstants { + /** + * CSS class prefix for out of the box components. + */ + static readonly VENDOR_CSS_CLASS_PREFIX: string = 'asgardeo'; + + protected constructor() { + // Protected constructor allows inheritance while still preventing direct instantiation + } +} + +export default StyleConstants; diff --git a/packages/browser/src/index.ts b/packages/browser/src/index.ts new file mode 100644 index 000000000..080f532ab --- /dev/null +++ b/packages/browser/src/index.ts @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Entry point for all public APIs of this SDK. + */ +export * from './__legacy__/client'; +export * from './__legacy__/models'; + +// Utils +export * from './__legacy__/utils/spa-utils'; + +// Constants +export * from './__legacy__/constants/storage'; +export * from './__legacy__/constants/hooks'; + +// clients +export * from './__legacy__/clients/main-thread-client'; +export * from './__legacy__/clients/web-worker-client'; + +// models +export * from './__legacy__/models/request-custom-grant'; + +// helpers +export * from './__legacy__/helpers/authentication-helper'; +export * from './__legacy__/helpers/spa-helper'; + +// worker receiver +export * from './__legacy__/worker/worker-receiver'; + +export {default as StyleConstants} from './constants/StyleConstants'; + +export {AsgardeoBrowserConfig} from './models/config'; + +export {default as hasAuthParamsInUrl} from './utils/hasAuthParamsInUrl'; +export {default as withVendorCSSClassPrefix} from './utils/withVendorCSSClassPrefix'; + +export {default as AsgardeoBrowserClient} from './AsgardeoBrowserClient'; + +export * from '@asgardeo/javascript'; diff --git a/packages/browser/src/models/config.ts b/packages/browser/src/models/config.ts new file mode 100644 index 000000000..8066dd4dc --- /dev/null +++ b/packages/browser/src/models/config.ts @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {Config} from '@asgardeo/javascript'; + +export type AsgardeoBrowserConfig = Config; diff --git a/packages/browser/src/utils/hasAuthParamsInUrl.ts b/packages/browser/src/utils/hasAuthParamsInUrl.ts new file mode 100644 index 000000000..d849ae952 --- /dev/null +++ b/packages/browser/src/utils/hasAuthParamsInUrl.ts @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Utility to check if `code` and `session_state` are available in the URL as search params. + * + * @param params - The URL search params to check. Defaults to `window.location.search`. + * @return `true` if the URL contains `code` and `session_state` search params, otherwise `false`. + */ +const hasAuthParamsInUrl = (params: string = window.location.search): boolean => { + const MATCHER: RegExp = /[?&]code=[^&]+/; + + return MATCHER.test(params); +}; + +export default hasAuthParamsInUrl; diff --git a/packages/browser/src/utils/withVendorCSSClassPrefix.ts b/packages/browser/src/utils/withVendorCSSClassPrefix.ts new file mode 100644 index 000000000..8d0f5297d --- /dev/null +++ b/packages/browser/src/utils/withVendorCSSClassPrefix.ts @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import StyleConstants from '../constants/StyleConstants'; + +/** + * Adds a vendor-specific prefix to a CSS class name. + * + * @param className - The original CSS class name to be prefixed + * @returns A new string with the vendor prefix added to the class name + * + * @example + * ```typescript + * // Usage with clsx + * clsx(withVendorCSSClassPrefix('sign-in-button'), className) + * // Result: "wso2-sign-in-button" + * ``` + */ +const withVendorCSSClassPrefix = (className: string): string => { + return `${StyleConstants.VENDOR_CSS_CLASS_PREFIX}-${className}`; +}; + +export default withVendorCSSClassPrefix; diff --git a/packages/browser/src/web-worker.d.ts b/packages/browser/src/web-worker.d.ts new file mode 100644 index 000000000..892b7a263 --- /dev/null +++ b/packages/browser/src/web-worker.d.ts @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +declare module "web-worker:*" { + const WorkerFactory: new () => Worker; + export default WorkerFactory; +} diff --git a/packages/browser/src/worker.ts b/packages/browser/src/worker.ts new file mode 100644 index 000000000..62de03a92 --- /dev/null +++ b/packages/browser/src/worker.ts @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2022, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {AsgardeoAuthClient} from '@asgardeo/javascript'; +import {AuthenticationHelper, SPAHelper} from './__legacy__/helpers'; +import {WebWorkerClientConfig} from './__legacy__/models'; +import {workerReceiver} from './__legacy__/worker/worker-receiver'; + +workerReceiver((authClient: AsgardeoAuthClient, spaHelper: SPAHelper) => { + return new AuthenticationHelper(authClient, spaHelper); +}); + +export default {} as typeof Worker & {new (): Worker}; diff --git a/packages/browser/tsconfig.eslint.json b/packages/browser/tsconfig.eslint.json new file mode 100644 index 000000000..23fadc266 --- /dev/null +++ b/packages/browser/tsconfig.eslint.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "include": [ + "**/.*.js", + "**/.*.cjs", + "**/.*.ts", + "**/*.js", + "**/*.cjs", + "**/*.ts", + ] +} diff --git a/packages/browser/tsconfig.json b/packages/browser/tsconfig.json new file mode 100644 index 000000000..56fc2075c --- /dev/null +++ b/packages/browser/tsconfig.json @@ -0,0 +1,34 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "declaration": false, + "emitDecoratorMetadata": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "importHelpers": true, + "lib": ["ESNext", "DOM"], + "module": "ESNext", + "moduleResolution": "node", + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "sourceMap": true, + "target": "ESNext", + "forceConsistentCasingInFileNames": true, + "strict": false, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "exclude": ["node_modules", "tmp", "dist"], + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/packages/browser/tsconfig.lib.json b/packages/browser/tsconfig.lib.json new file mode 100644 index 000000000..b2c9c1aef --- /dev/null +++ b/packages/browser/tsconfig.lib.json @@ -0,0 +1,20 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "declaration": true, + "outDir": "dist", + "declarationDir": "dist", + "types": ["node"] + }, + "exclude": [ + "**/*.spec.ts", + "**/*.test.ts", + "**/*.spec.tsx", + "**/*.test.tsx", + "**/*.spec.js", + "**/*.test.js", + "**/*.spec.jsx", + "**/*.test.jsx" + ], + "include": ["src/**/*.js", "src/**/*.ts", "types/**/*.d.ts"] +} diff --git a/packages/browser/tsconfig.spec.json b/packages/browser/tsconfig.spec.json new file mode 100644 index 000000000..46a76e285 --- /dev/null +++ b/packages/browser/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "test-configs", + "jest.config.js", + "**/*.test.ts", + "**/*.spec.ts", + "**/*.test.js", + "**/*.spec.js", + "**/*.d.ts" + ] +} diff --git a/packages/browser/vitest.config.ts b/packages/browser/vitest.config.ts new file mode 100644 index 000000000..bfcf53bd8 --- /dev/null +++ b/packages/browser/vitest.config.ts @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {defineConfig} from 'vitest/config'; + +export default defineConfig({ + test: { + browser: { + enabled: true, + headless: true, + instances: [{browser: 'chromium'}], + provider: 'playwright', + }, + }, +}); diff --git a/packages/javascript/.editorconfig b/packages/javascript/.editorconfig new file mode 100644 index 000000000..1b3ce07de --- /dev/null +++ b/packages/javascript/.editorconfig @@ -0,0 +1 @@ +../../.editorconfig \ No newline at end of file diff --git a/packages/javascript/.eslintignore b/packages/javascript/.eslintignore new file mode 100644 index 000000000..177586b6b --- /dev/null +++ b/packages/javascript/.eslintignore @@ -0,0 +1,4 @@ +/dist +/build +/node_modules +/coverage \ No newline at end of file diff --git a/packages/javascript/.eslintrc.cjs b/packages/javascript/.eslintrc.cjs new file mode 100644 index 000000000..2676ca816 --- /dev/null +++ b/packages/javascript/.eslintrc.cjs @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const path = require('path'); + +module.exports = { + env: { + es6: true, + node: true, + }, + extends: [ + 'plugin:@wso2/typescript', + 'plugin:@wso2/strict', + 'plugin:@wso2/internal', + 'plugin:@wso2/jest', + 'plugin:@wso2/prettier', + ], + parserOptions: { + ecmaVersion: 2018, + project: [path.resolve(__dirname, 'tsconfig.eslint.json')], + }, + plugins: ['@wso2'], +}; diff --git a/packages/javascript/.gitignore b/packages/javascript/.gitignore new file mode 100644 index 000000000..c6bba5913 --- /dev/null +++ b/packages/javascript/.gitignore @@ -0,0 +1,130 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* diff --git a/packages/javascript/.prettierignore b/packages/javascript/.prettierignore new file mode 100644 index 000000000..99b0b518a --- /dev/null +++ b/packages/javascript/.prettierignore @@ -0,0 +1,4 @@ +/dist +/build +/node_modules +/coverage diff --git a/packages/javascript/README.md b/packages/javascript/README.md new file mode 100644 index 000000000..5236fad90 --- /dev/null +++ b/packages/javascript/README.md @@ -0,0 +1,57 @@ +

+

@asgardeo/javascript

+

+

Framework Agnostic JavaScript SDK for Asgardeo

+
+ npm (scoped) + npm + License +
+ +## Installation + +```bash +# Using npm +npm install @asgardeo/javascript + +# or using pnpm +pnpm add @asgardeo/javascript + +# or using yarn +yarn add @asgardeo/javascript +``` + +## Quick Start + +```javascript +import { AsgardeoAuth } from "@asgardeo/javascript"; + +// Initialize the auth instance +const auth = new AsgardeoAuth({ + signInRedirectURL: "https://localhost:3000", + clientID: "", + baseUrl: "https://api.asgardeo.io/t/" +}); + +// Handle authentication +auth.signIn() + .then(() => { + // Handle successful sign in + }) + .catch((error) => { + // Handle sign in error + }); + +// Get authenticated user +auth.getBasicUserInfo() + .then((userInfo) => { + console.log(userInfo); + }); + +// Sign out +auth.signOut(); +``` + +## License + +Apache-2.0 diff --git a/packages/javascript/esbuild.config.mjs b/packages/javascript/esbuild.config.mjs new file mode 100644 index 000000000..75bd11607 --- /dev/null +++ b/packages/javascript/esbuild.config.mjs @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {readFileSync} from 'fs'; +import * as esbuild from 'esbuild'; + +const pkg = JSON.parse(readFileSync('./package.json', 'utf8')); + +const commonOptions = { + bundle: true, + entryPoints: ['src/index.ts'], + external: [...Object.keys(pkg.dependencies || {}), ...Object.keys(pkg.peerDependencies || {})], + platform: 'node', + target: ['es2020'], +}; + +await esbuild.build({ + ...commonOptions, + format: 'esm', + outfile: 'dist/index.js', + sourcemap: true, +}); + +await esbuild.build({ + ...commonOptions, + format: 'cjs', + outfile: 'dist/cjs/index.js', + sourcemap: true, +}); diff --git a/packages/javascript/package.json b/packages/javascript/package.json new file mode 100644 index 000000000..69d4a8810 --- /dev/null +++ b/packages/javascript/package.json @@ -0,0 +1,61 @@ +{ + "name": "@asgardeo/javascript", + "version": "0.0.0", + "description": "Framework agnostic JavaScript SDK for Asgardeo.", + "keywords": [ + "asgardeo", + "javascript", + "core", + "agnostic", + "js" + ], + "homepage": "https://github.com/asgardeo/javascript/tree/main/packages/javascript#readme", + "bugs": { + "url": "https://github.com/asgardeo/javascript/issues" + }, + "author": "WSO2", + "license": "Apache-2.0", + "type": "module", + "main": "dist/cjs/index.js", + "module": "dist/index.js", + "exports": { + "import": "./dist/index.js", + "require": "./dist/cjs/index.js" + }, + "files": [ + "dist", + "README.md", + "LICENSE" + ], + "types": "dist/index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/asgardeo/javascript", + "directory": "packages/javascript" + }, + "scripts": { + "build": "pnpm clean && node esbuild.config.mjs && tsc -p tsconfig.lib.json --emitDeclarationOnly --outDir dist", + "clean": "rimraf dist", + "fix:lint": "eslint . --ext .js,.jsx,.ts,.tsx,.cjs,.mjs", + "lint": "eslint . --ext .js,.jsx,.ts,.tsx,.cjs,.mjs", + "test": "vitest", + "typecheck": "tsc -p tsconfig.lib.json" + }, + "devDependencies": { + "@types/node": "^22.15.3", + "@wso2/eslint-plugin": "catalog:", + "@wso2/prettier-config": "catalog:", + "esbuild": "^0.25.4", + "eslint": "8.57.0", + "prettier": "^2.6.2", + "rimraf": "^6.0.1", + "typescript": "~5.7.2", + "vitest": "^3.1.3" + }, + "dependencies": { + "tslib": "^2.8.1" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/packages/javascript/prettier.config.cjs b/packages/javascript/prettier.config.cjs new file mode 100644 index 000000000..929b9b15f --- /dev/null +++ b/packages/javascript/prettier.config.cjs @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +module.exports = require('@wso2/prettier-config'); diff --git a/packages/javascript/src/AsgardeoJavaScriptClient.ts b/packages/javascript/src/AsgardeoJavaScriptClient.ts new file mode 100644 index 000000000..d13433016 --- /dev/null +++ b/packages/javascript/src/AsgardeoJavaScriptClient.ts @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {AsgardeoClient, SignInOptions, SignOutOptions} from './models/client'; +import {User} from './models/user'; +import {Config} from './models/config'; + +/** + * Base class for implementing Asgardeo clients. + * This class provides the core functionality for managing user authentication and sessions. + * + * @typeParam T - Configuration type that extends Config. + */ +abstract class AsgardeoJavaScriptClient implements AsgardeoClient { + /** + * Initializes the authentication client with provided configuration. + * + * @param config - SDK Client instance configuration options. + * @returns Promise resolving to boolean indicating success. + */ + abstract initialize(config: T): Promise; + + /** + * Gets user information from the session. + * + * @returns User object containing user details. + */ + abstract getUser(): Promise; + + /** + * Checks if the client is currently loading. + * This can be used to determine if the client is in the process of initializing or fetching user data. + * + * @returns Boolean indicating if the client is loading. + */ + abstract isLoading(): boolean; + + /** + * Checks if a user is signed in. + * FIXME: Check if this should return a boolean or a Promise. + * + * @returns Promise resolving to boolean indicating sign-in status. + */ + abstract isSignedIn(): Promise; + + /** + * Initiates the sign-in process for the user. + * + * @param options - Optional sign-in options like additional parameters to be sent in the authorize request, etc. + * @returns Promise resolving the user upon successful sign in. + */ + abstract signIn(options?: SignInOptions): Promise; + + /** + * Signs out the currently signed-in user. + * + * @param options - Optional sign-out options like additional parameters to be sent in the sign-out request, etc. + * @param afterSignOut - Callback function to be executed after sign-out is complete. + * @returns A promise that resolves to true if sign-out is successful + */ + abstract signOut(options?: SignOutOptions, afterSignOut?: (redirectUrl: string) => void): Promise; + + /** + * Signs out the currently signed-in user with an optional session ID. + * + * @param options - Optional sign-out options like additional parameters to be sent in the sign-out request, etc. + * @param sessionId - Optional session ID to be used for sign-out. + * This can be useful in scenarios where multiple sessions are managed. + * @param afterSignOut - Callback function to be executed after sign-out is complete. + * @returns A promise that resolves to true if sign-out is successful + */ + abstract signOut( + options?: SignOutOptions, + sessionId?: string, + afterSignOut?: (redirectUrl: string) => void, + ): Promise; +} + +export default AsgardeoJavaScriptClient; diff --git a/packages/javascript/src/IsomorphicCrypto.ts b/packages/javascript/src/IsomorphicCrypto.ts new file mode 100644 index 000000000..6cab9808e --- /dev/null +++ b/packages/javascript/src/IsomorphicCrypto.ts @@ -0,0 +1,149 @@ +/** + * Copyright (c) 2022, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {AsgardeoAuthException} from './__legacy__/exception'; +import {Crypto, JWKInterface} from './models/crypto'; +import {IdTokenPayload} from './models/id-token'; +import TokenConstants from './constants/TokenConstants'; + +export class IsomorphicCrypto { + private _cryptoUtils: Crypto; + + public constructor(cryptoUtils: Crypto) { + this._cryptoUtils = cryptoUtils; + } + + /** + * Generate code verifier. + * + * @returns code verifier. + */ + public getCodeVerifier(): string { + return this._cryptoUtils.base64URLEncode(this._cryptoUtils.generateRandomBytes(32)); + } + + /** + * Derive code challenge from the code verifier. + * + * @param verifier - Code verifier. + * + * @returns - code challenge. + */ + public getCodeChallenge(verifier: string): string { + return this._cryptoUtils.base64URLEncode(this._cryptoUtils.hashSha256(verifier)); + } + + /** + * Get JWK used for the id_token + * + * @param jwtHeader - header of the id_token. + * @param keys - jwks response. + * + * @returns public key. + * + * @throws + */ + /* eslint-disable @typescript-eslint/no-explicit-any */ + public getJWKForTheIdToken(jwtHeader: string, keys: JWKInterface[]): JWKInterface { + const headerJSON: Record = JSON.parse(this._cryptoUtils.base64URLDecode(jwtHeader)); + + for (const key of keys) { + if (headerJSON['kid'] === key.kid) { + return key; + } + } + + throw new AsgardeoAuthException( + 'JS-CRYPTO_UTIL-GJFTIT-IV01', + 'kid not found.', + "Failed to find the 'kid' specified in the id_token. 'kid' found in the header : " + + headerJSON['kid'] + + ', Expected values: ' + + keys.map((key: JWKInterface) => key.kid).join(', '), + ); + } + + /** + * Verify id token. + * + * @param idToken - id_token received from the IdP. + * @param jwk - public key used for signing. + * @param clientID - app identification. + * @param issuer - id_token issuer. + * @param username - Username. + * @param clockTolerance - Allowed leeway for id_tokens (in seconds). + * + * @returns whether the id_token is valid. + * + * @throws + */ + public isValidIdToken( + idToken: string, + jwk: JWKInterface, + clientID: string, + issuer: string, + username: string, + clockTolerance: number | undefined, + validateJwtIssuer: boolean | undefined, + ): Promise { + return this._cryptoUtils + .verifyJwt( + idToken, + jwk, + TokenConstants.SignatureValidation.SUPPORTED_ALGORITHMS as unknown as string[], + clientID, + issuer, + username, + clockTolerance, + validateJwtIssuer, + ) + .then((response: boolean) => { + if (response) { + return Promise.resolve(true); + } + + return Promise.reject( + new AsgardeoAuthException( + 'JS-CRYPTO_HELPER-IVIT-IV01', + 'Invalid ID token.', + 'ID token validation returned false', + ), + ); + }); + } + + /** + * This function decodes the payload of an id token and returns it. + * + * @param idToken - The id token to be decoded. + * + * @returns - The decoded payload of the id token. + * + * @throws + */ + public decodeIDToken(idToken: string): IdTokenPayload { + try { + const utf8String: string = this._cryptoUtils.base64URLDecode(idToken.split('.')[1]); + const payload: IdTokenPayload = JSON.parse(utf8String); + + return payload; + } catch (error: any) { + throw new AsgardeoAuthException('JS-CRYPTO_UTIL-DIT-IV01', 'Decoding ID token failed.', error); + } + } +} diff --git a/packages/javascript/src/__legacy__/client.ts b/packages/javascript/src/__legacy__/client.ts new file mode 100644 index 000000000..044b85e7c --- /dev/null +++ b/packages/javascript/src/__legacy__/client.ts @@ -0,0 +1,682 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {AuthenticationCore} from './core'; +import {DataLayer} from './data'; +import { + AuthClientConfig, + BasicUserInfo, + CustomGrantConfig, + FetchResponse, + GetAuthURLConfig, +} from './models'; +import {Crypto} from '../models/crypto'; +import {TokenResponse} from '../models/token'; +import {IdTokenPayload} from '../models/id-token'; +import {OIDCEndpoints} from '../models/oidc-endpoints'; +import {Store} from '../models/store'; +import {ResponseMode} from '../models/oauth-response'; +import ScopeConstants from '../constants/ScopeConstants'; +import OIDCDiscoveryConstants from '../constants/OIDCDiscoveryConstants'; +import OIDCRequestConstants from '../constants/OIDCRequestConstants'; +import { IsomorphicCrypto } from '../IsomorphicCrypto'; + +/** + * Default configurations. + */ +const DefaultConfig: Partial> = { + clockTolerance: 300, + enablePKCE: true, + responseMode: ResponseMode.Query, + scope: [ScopeConstants.OPENID], + sendCookiesInRequests: true, + validateIDToken: true, + validateIDTokenIssuer: true, +}; + +/** + * This class provides the necessary methods needed to implement authentication. + */ +export class AsgardeoAuthClient { + private _dataLayer!: DataLayer; + private _authenticationCore!: AuthenticationCore; + + private static _instanceID: number; + static _authenticationCore: any; + + /** + * This is the constructor method that returns an instance of the . + * + * @param store - The store object. + * + * @example + * ``` + * const _store: Store = new DataStore(); + * const auth = new AsgardeoAuthClient(_store); + * ``` + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#constructor} + * + * @preserve + */ + public constructor() {} + + /** + * + * This method initializes the SDK with the config data. + * + * @param config - The config object to initialize with. + * + * @example + * const config = \{ + * signInRedirectURL: "http://localhost:3000/sign-in", + * clientID: "client ID", + * baseUrl: "https://localhost:9443" + * \} + * + * await auth.initialize(config); + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#initialize} + * + * @preserve + */ + public async initialize( + config: AuthClientConfig, + store: Store, + cryptoUtils: Crypto, + instanceID?: number, + ): Promise { + const clientId: string = config.clientID; + + if (!AsgardeoAuthClient._instanceID) { + AsgardeoAuthClient._instanceID = 0; + } else { + AsgardeoAuthClient._instanceID += 1; + } + + if (instanceID) { + AsgardeoAuthClient._instanceID = instanceID; + } + + if (!clientId) { + this._dataLayer = new DataLayer(`instance_${AsgardeoAuthClient._instanceID}`, store); + } else { + this._dataLayer = new DataLayer(`instance_${AsgardeoAuthClient._instanceID}-${clientId}`, store); + } + + this._authenticationCore = new AuthenticationCore(this._dataLayer, cryptoUtils); + AsgardeoAuthClient._authenticationCore = new AuthenticationCore(this._dataLayer, cryptoUtils); + + await this._dataLayer.setConfigData({ + ...DefaultConfig, + ...config, + scope: [ + ...(DefaultConfig.scope ?? []), + ...(config.scope?.filter((scope: string) => !DefaultConfig?.scope?.includes(scope)) ?? []), + ], + }); + } + + /** + * This method returns the `DataLayer` object that allows you to access authentication data. + * + * @returns - The `DataLayer` object. + * + * @example + * ``` + * const data = auth.getDataLayer(); + * ``` + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getDataLayer} + * + * @preserve + */ + public getDataLayer(): DataLayer { + return this._dataLayer; + } + + /** + * This method returns the `instanceID` variable of the given instance. + * + * @returns - The `instanceID` number. + * + * @example + * ``` + * const instanceId = auth.getInstanceID(); + * ``` + * + * @preserve + */ + public getInstanceID(): number { + return AsgardeoAuthClient._instanceID; + } + + /** + * This is an async method that returns a Promise that resolves with the authorization URL parameters. + * + * @param config - (Optional) A config object to force initialization and pass + * custom path parameters such as the `fidp` parameter. + * @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user + * scenarios where each user should be uniquely identified. + * + * @returns - A promise that resolves with the authorization URL parameters. + * + * @example + * ``` + * auth.getAuthorizationURLParams().then((params)=>{ + * // console.log(params); + * }).catch((error)=>{ + * // console.error(error); + * }); + * ``` + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getAuthorizationURLParams} + * + * @preserve + */ + public async getAuthorizationURLParams(config?: GetAuthURLConfig, userID?: string): Promise> { + const authRequestConfig: GetAuthURLConfig = {...config}; + + delete authRequestConfig?.forceInit; + + if ( + await this._dataLayer.getTemporaryDataParameter( + OIDCDiscoveryConstants.Storage.StorageKeys.OPENID_PROVIDER_CONFIG_INITIATED, + ) + ) { + return this._authenticationCore.getAuthorizationURLParams(authRequestConfig, userID); + } + + return this._authenticationCore.getOIDCProviderMetaData(config?.forceInit as boolean).then(() => { + return this._authenticationCore.getAuthorizationURLParams(authRequestConfig, userID); + }); + } + + /** + * This is an async method that returns a Promise that resolves with the authorization URL. + * + * @param config - (Optional) A config object to force initialization and pass + * custom path parameters such as the fidp parameter. + * @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user + * scenarios where each user should be uniquely identified. + * + * @returns - A promise that resolves with the authorization URL. + * + * @example + * ``` + * auth.getAuthorizationURL().then((url)=>{ + * // console.log(url); + * }).catch((error)=>{ + * // console.error(error); + * }); + * ``` + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getAuthorizationURL} + * + * @preserve + */ + public async getAuthorizationURL(config?: GetAuthURLConfig, userID?: string): Promise { + const authRequestConfig: GetAuthURLConfig = {...config}; + + delete authRequestConfig?.forceInit; + + if ( + await this._dataLayer.getTemporaryDataParameter( + OIDCDiscoveryConstants.Storage.StorageKeys.OPENID_PROVIDER_CONFIG_INITIATED, + ) + ) { + return this._authenticationCore.getAuthorizationURL(authRequestConfig, userID); + } + + return this._authenticationCore.getOIDCProviderMetaData(config?.forceInit as boolean).then(() => { + return this._authenticationCore.getAuthorizationURL(authRequestConfig, userID); + }); + } + + /** + * This is an async method that sends a request to obtain the access token and returns a Promise + * that resolves with the token and other relevant data. + * + * @param authorizationCode - The authorization code. + * @param sessionState - The session state. + * @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user + * scenarios where each user should be uniquely identified. + * + * @returns - A Promise that resolves with the token response. + * + * @example + * ``` + * auth.requestAccessToken(authCode, sessionState).then((token)=>{ + * // console.log(token); + * }).catch((error)=>{ + * // console.error(error); + * }); + * ``` + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#requestAccessToken} + * + * + * @preserve + */ + public async requestAccessToken( + authorizationCode: string, + sessionState: string, + state: string, + userID?: string, + tokenRequestConfig?: { + params: Record; + }, + ): Promise { + if ( + await this._dataLayer.getTemporaryDataParameter( + OIDCDiscoveryConstants.Storage.StorageKeys.OPENID_PROVIDER_CONFIG_INITIATED, + ) + ) { + return this._authenticationCore.requestAccessToken( + authorizationCode, + sessionState, + state, + userID, + tokenRequestConfig, + ); + } + + return this._authenticationCore.getOIDCProviderMetaData(false).then(() => { + return this._authenticationCore.requestAccessToken( + authorizationCode, + sessionState, + state, + userID, + tokenRequestConfig, + ); + }); + } + + /** + * This method returns the sign-out URL. + * + * @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user + * scenarios where each user should be uniquely identified. + * + * **This doesn't clear the authentication data.** + * + * @returns - A Promise that resolves with the sign-out URL. + * + * @example + * ``` + * const signOutUrl = await auth.getSignOutURL(); + * ``` + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getSignOutURL} + * + * @preserve + */ + public async getSignOutURL(userID?: string): Promise { + return this._authenticationCore.getSignOutURL(userID); + } + + /** + * This method returns OIDC service endpoints that are fetched from the `.well-known` endpoint. + * + * @returns - A Promise that resolves with an object containing the OIDC service endpoints. + * + * @example + * ``` + * const endpoints = await auth.getOIDCServiceEndpoints(); + * ``` + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getOIDCServiceEndpoints} + * + * @preserve + */ + public async getOIDCServiceEndpoints(): Promise> { + return this._authenticationCore.getOIDCServiceEndpoints(); + } + + /** + * This method decodes the payload of the ID token and returns it. + * + * @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user + * scenarios where each user should be uniquely identified. + * + * @returns - A Promise that resolves with the decoded ID token payload. + * + * @example + * ``` + * const decodedIdToken = await auth.getDecodedIDToken(); + * ``` + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getDecodedIDToken} + * + * @preserve + */ + public async getDecodedIDToken(userID?: string): Promise { + return this._authenticationCore.getDecodedIDToken(userID); + } + + /** + * This method returns the ID token. + * + * @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user + * scenarios where each user should be uniquely identified. + * + * @returns - A Promise that resolves with the ID token. + * + * @example + * ``` + * const idToken = await auth.getIDToken(); + * ``` + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getIDToken} + * + * @preserve + */ + public async getIDToken(userID?: string): Promise { + return this._authenticationCore.getIDToken(userID); + } + + /** + * This method returns the basic user information obtained from the ID token. + * + * @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user + * scenarios where each user should be uniquely identified. + * + * @returns - A Promise that resolves with an object containing the basic user information. + * + * @example + * ``` + * const userInfo = await auth.getBasicUserInfo(); + * ``` + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getBasicUserInfo} + * + * @preserve + */ + public async getBasicUserInfo(userID?: string): Promise { + return this._authenticationCore.getBasicUserInfo(userID); + } + + /** + * This method returns the crypto helper object. + * + * @returns - A Promise that resolves with a IsomorphicCrypto object. + * + * @example + * ``` + * const cryptoHelper = await auth.IsomorphicCrypto(); + * ``` + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getCryptoHelper} + * + * @preserve + */ + public async getCryptoHelper(): Promise { + return this._authenticationCore.getCryptoHelper(); + } + + /** + * This method revokes the access token. + * + * @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user + * scenarios where each user should be uniquely identified. + * + * **This method also clears the authentication data.** + * + * @returns - A Promise that returns the response of the revoke-access-token request. + * + * @example + * ``` + * auth.revokeAccessToken().then((response)=>{ + * // console.log(response); + * }).catch((error)=>{ + * // console.error(error); + * }); + * ``` + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#revokeAccessToken} + * + * @preserve + */ + public revokeAccessToken(userID?: string): Promise { + return this._authenticationCore.revokeAccessToken(userID); + } + + /** + * This method refreshes the access token and returns a Promise that resolves with the new access + * token and other relevant data. + * + * @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user + * scenarios where each user should be uniquely identified. + * + * @returns - A Promise that resolves with the token response. + * + * @example + * ``` + * auth.refreshAccessToken().then((response)=>{ + * // console.log(response); + * }).catch((error)=>{ + * // console.error(error); + * }); + * ``` + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#refreshAccessToken} + * + * @preserve + */ + public refreshAccessToken(userID?: string): Promise { + return this._authenticationCore.refreshAccessToken(userID); + } + + /** + * This method returns the access token. + * + * @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user + * scenarios where each user should be uniquely identified. + * + * @returns - A Promise that resolves with the access token. + * + * @example + * ``` + * const accessToken = await auth.getAccessToken(); + * ``` + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getAccessToken} + * + * @preserve + */ + public async getAccessToken(userID?: string): Promise { + return this._authenticationCore.getAccessToken(userID); + } + + /** + * This method sends a custom-grant request and returns a Promise that resolves with the response + * depending on the config passed. + * + * @param config - A config object containing the custom grant configurations. + * @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user + * scenarios where each user should be uniquely identified. + * + * @returns - A Promise that resolves with the response depending + * on your configurations. + * + * @example + * ``` + * const config = { + * attachToken: false, + * data: { + * client_id: "{{clientID}}", + * grant_type: "account_switch", + * scope: "{{scope}}", + * token: "{{token}}", + * }, + * id: "account-switch", + * returnResponse: true, + * returnsSession: true, + * signInRequired: true + * } + * + * auth.requestCustomGrant(config).then((response)=>{ + * // console.log(response); + * }).catch((error)=>{ + * // console.error(error); + * }); + * ``` + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#requestCustomGrant} + * + * @preserve + */ + public requestCustomGrant(config: CustomGrantConfig, userID?: string): Promise { + return this._authenticationCore.requestCustomGrant(config, userID); + } + + /** + * This method returns if the user is authenticated or not. + * + * @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user + * scenarios where each user should be uniquely identified. + * + * @returns - A Promise that resolves with `true` if the user is authenticated, `false` otherwise. + * + * @example + * ``` + * await auth.isAuthenticated(); + * ``` + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#isAuthenticated} + * + * @preserve + */ + public async isAuthenticated(userID?: string): Promise { + return this._authenticationCore.isAuthenticated(userID); + } + + /** + * This method returns the PKCE code generated during the generation of the authentication URL. + * + * @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user + * scenarios where each user should be uniquely identified. + * @param state - The state parameter that was passed in the authentication URL. + * + * @returns - A Promise that resolves with the PKCE code. + * + * @example + * ``` + * const pkce = await getPKCECode(); + * ``` + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getPKCECode} + * + * @preserve + */ + public async getPKCECode(state: string, userID?: string): Promise { + return this._authenticationCore.getPKCECode(state, userID); + } + + /** + * This method sets the PKCE code to the data store. + * + * @param pkce - The PKCE code. + * @param state - The state parameter that was passed in the authentication URL. + * @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user + * scenarios where each user should be uniquely identified. + * + * @example + * ``` + * await auth.setPKCECode("pkce_code") + * ``` + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#setPKCECode} + * + * @preserve + */ + public async setPKCECode(pkce: string, state: string, userID?: string): Promise { + await this._authenticationCore.setPKCECode(pkce, state, userID); + } + + /** + * This method returns if the sign-out is successful or not. + * + * @param signOutRedirectUrl - The URL to which the user has been redirected to after signing-out. + * + * **The server appends path parameters to the `signOutRedirectURL` and these path parameters + * are required for this method to function.** + * + * @returns - `true` if successful, `false` otherwise. + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#isSignOutSuccessful} + * + * @preserve + */ + public static isSignOutSuccessful(signOutRedirectURL: string): boolean { + const url: URL = new URL(signOutRedirectURL); + const stateParam: string | null = url.searchParams.get(OIDCRequestConstants.Params.STATE); + const error: boolean = Boolean(url.searchParams.get('error')); + + return stateParam ? stateParam === OIDCRequestConstants.Params.SIGN_OUT_SUCCESS && !error : false; + } + + /** + * This method returns if the sign-out has failed or not. + * + * @param signOutRedirectUrl - The URL to which the user has been redirected to after signing-out. + * + * **The server appends path parameters to the `signOutRedirectURL` and these path parameters + * are required for this method to function.** + * + * @returns - `true` if successful, `false` otherwise. + * + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#didSignOutFail} + * + * @preserve + */ + public static didSignOutFail(signOutRedirectURL: string): boolean { + const url: URL = new URL(signOutRedirectURL); + const stateParam: string | null = url.searchParams.get(OIDCRequestConstants.Params.STATE); + const error: boolean = Boolean(url.searchParams.get('error')); + + return stateParam ? stateParam === OIDCRequestConstants.Params.SIGN_OUT_SUCCESS && error : false; + } + + /** + * This method updates the configuration that was passed into the constructor when instantiating this class. + * + * @param config - A config object to update the SDK configurations with. + * + * @example + * ``` + * const config = { + * signInRedirectURL: "http://localhost:3000/sign-in", + * clientID: "client ID", + * baseUrl: "https://localhost:9443" + * } + * + * await auth.updateConfig(config); + * ``` + * {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#updateConfig} + * + * @preserve + */ + public async updateConfig(config: Partial>): Promise { + await this._authenticationCore.updateConfig(config); + } + + public static async clearUserSessionData(userID?: string): Promise { + await this._authenticationCore.clearUserSessionData(userID); + } +} diff --git a/packages/javascript/src/__legacy__/core/authentication-core.ts b/packages/javascript/src/__legacy__/core/authentication-core.ts new file mode 100644 index 000000000..ec74a2c5b --- /dev/null +++ b/packages/javascript/src/__legacy__/core/authentication-core.ts @@ -0,0 +1,675 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import extractPkceStorageKeyFromState from '../../utils/extractPkceStorageKeyFromState'; +import generateStateParamForRequestCorrelation from '../../utils/generateStateParamForRequestCorrelation'; +import {DataLayer} from '../data'; +import {AsgardeoAuthException} from '../exception'; +import {AuthenticationHelper} from '../helpers'; +import { + AuthClientConfig, + AuthenticatedUserInfo, + AuthorizationURLParams, + BasicUserInfo, + CustomGrantConfig, + FetchRequestConfig, + FetchResponse, + SessionData, + StrictAuthClientConfig, +} from '../models'; +import {TokenResponse} from '../../models/token'; +import {Crypto} from '../../models/crypto'; +import {IdTokenPayload} from '../../models/id-token'; +import {TemporaryStore} from '../../models/store'; +import {OIDCEndpoints} from '../../models/oidc-endpoints'; +import generatePkceStorageKey from '../../utils/generatePkceStorageKey'; +import ScopeConstants from '../../constants/ScopeConstants'; +import OIDCDiscoveryConstants from '../../constants/OIDCDiscoveryConstants'; +import OIDCRequestConstants from '../../constants/OIDCRequestConstants'; +import {OIDCDiscoveryApiResponse} from '../../models/oidc-discovery'; +import { IsomorphicCrypto } from '../../IsomorphicCrypto'; + +export class AuthenticationCore { + private _dataLayer: DataLayer; + private _config: () => Promise; + private _oidcProviderMetaData: () => Promise; + private _authenticationHelper: AuthenticationHelper; + private _cryptoUtils: Crypto; + private _cryptoHelper: IsomorphicCrypto; + + public constructor(dataLayer: DataLayer, cryptoUtils: Crypto) { + this._cryptoUtils = cryptoUtils; + this._cryptoHelper = new IsomorphicCrypto(cryptoUtils); + this._authenticationHelper = new AuthenticationHelper(dataLayer, this._cryptoHelper); + this._dataLayer = dataLayer; + this._config = async () => await this._dataLayer.getConfigData(); + this._oidcProviderMetaData = async () => await this._dataLayer.getOIDCProviderMetaData(); + } + + public async getAuthorizationURLParams( + config?: AuthorizationURLParams, + userID?: string, + ): Promise> { + const configData: StrictAuthClientConfig = await this._config(); + + const authorizeRequestParams: Map = new Map(); + + authorizeRequestParams.set('response_type', 'code'); + authorizeRequestParams.set('client_id', configData.clientID); + + let scope: string = ScopeConstants.OPENID; + + if (configData.scope && configData.scope.length > 0) { + if (!configData.scope.includes(ScopeConstants.OPENID)) { + configData.scope.push(ScopeConstants.OPENID); + } + scope = configData.scope.join(' '); + } + + authorizeRequestParams.set('scope', scope); + authorizeRequestParams.set('redirect_uri', configData.signInRedirectURL); + + if (configData.responseMode) { + authorizeRequestParams.set('response_mode', configData.responseMode); + } + + const tempStore: TemporaryStore = await this._dataLayer.getTemporaryData(userID); + const pkceKey: string = await generatePkceStorageKey(tempStore); + + if (configData.enablePKCE) { + const codeVerifier: string = this._cryptoHelper?.getCodeVerifier(); + const codeChallenge: string = this._cryptoHelper?.getCodeChallenge(codeVerifier); + + await this._dataLayer.setTemporaryDataParameter(pkceKey, codeVerifier, userID); + authorizeRequestParams.set('code_challenge_method', 'S256'); + authorizeRequestParams.set('code_challenge', codeChallenge); + } + + if (configData.prompt) { + authorizeRequestParams.set('prompt', configData.prompt); + } + + const customParams: AuthorizationURLParams | undefined = config; + + if (customParams) { + for (const [key, value] of Object.entries(customParams)) { + if (key != '' && value != '' && key !== OIDCRequestConstants.Params.STATE) { + authorizeRequestParams.set(key, value.toString()); + } + } + } + + authorizeRequestParams.set( + OIDCRequestConstants.Params.STATE, + generateStateParamForRequestCorrelation( + pkceKey, + customParams ? customParams[OIDCRequestConstants.Params.STATE]?.toString() : '', + ), + ); + + return authorizeRequestParams; + } + + public async getAuthorizationURL(config?: AuthorizationURLParams, userID?: string): Promise { + const authorizeEndpoint: string = (await this._dataLayer.getOIDCProviderMetaDataParameter( + OIDCDiscoveryConstants.Storage.StorageKeys.Endpoints.AUTHORIZATION as keyof OIDCDiscoveryApiResponse, + )) as string; + + if (!authorizeEndpoint || authorizeEndpoint.trim().length === 0) { + throw new AsgardeoAuthException( + 'JS-AUTH_CORE-GAU-NF01', + 'No authorization endpoint found.', + 'No authorization endpoint was found in the OIDC provider meta data from the well-known endpoint ' + + 'or the authorization endpoint passed to the SDK is empty.', + ); + } + + const authorizeRequest: URL = new URL(authorizeEndpoint); + + const authorizeRequestParams: Map = await this.getAuthorizationURLParams(config, userID); + + for (const [key, value] of authorizeRequestParams.entries()) { + authorizeRequest.searchParams.append(key, value); + } + + return authorizeRequest.toString(); + } + + public async requestAccessToken( + authorizationCode: string, + sessionState: string, + state: string, + userID?: string, + tokenRequestConfig?: { + params: Record; + }, + ): Promise { + const tokenEndpoint: string | undefined = (await this._oidcProviderMetaData()).token_endpoint; + const configData: StrictAuthClientConfig = await this._config(); + + if (!tokenEndpoint || tokenEndpoint.trim().length === 0) { + throw new AsgardeoAuthException( + 'JS-AUTH_CORE-RAT1-NF01', + 'Token endpoint not found.', + 'No token endpoint was found in the OIDC provider meta data returned by the well-known endpoint ' + + 'or the token endpoint passed to the SDK is empty.', + ); + } + + sessionState && + (await this._dataLayer.setSessionDataParameter( + OIDCRequestConstants.Params.SESSION_STATE as keyof SessionData, + sessionState, + userID, + )); + + const body: URLSearchParams = new URLSearchParams(); + + body.set('client_id', configData.clientID); + + if (configData.clientSecret && configData.clientSecret.trim().length > 0) { + body.set('client_secret', configData.clientSecret); + } + + const code: string = authorizationCode; + + body.set('code', code); + + body.set('grant_type', 'authorization_code'); + body.set('redirect_uri', configData.signInRedirectURL); + + if (tokenRequestConfig?.params) { + Object.entries(tokenRequestConfig.params).forEach(([key, value]: [key: string, value: unknown]) => { + body.append(key, value as string); + }); + } + + if (configData.enablePKCE) { + body.set( + 'code_verifier', + `${await this._dataLayer.getTemporaryDataParameter(extractPkceStorageKeyFromState(state), userID)}`, + ); + + await this._dataLayer.removeTemporaryDataParameter(extractPkceStorageKeyFromState(state), userID); + } + + let tokenResponse: Response; + + try { + tokenResponse = await fetch(tokenEndpoint, { + body: body, + credentials: configData.sendCookiesInRequests ? 'include' : 'same-origin', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/x-www-form-urlencoded', + }, + method: 'POST', + }); + } catch (error: any) { + throw new AsgardeoAuthException( + 'JS-AUTH_CORE-RAT1-NE02', + 'Requesting access token failed', + error ?? 'The request to get the access token from the server failed.', + ); + } + + if (!tokenResponse.ok) { + throw new AsgardeoAuthException( + 'JS-AUTH_CORE-RAT1-HE03', + `Requesting access token failed with ${tokenResponse.statusText}`, + (await tokenResponse.json()) as string, + ); + } + + return await this._authenticationHelper.handleTokenResponse(tokenResponse, userID); + } + + public async refreshAccessToken(userID?: string): Promise { + const tokenEndpoint: string | undefined = (await this._oidcProviderMetaData()).token_endpoint; + const configData: StrictAuthClientConfig = await this._config(); + const sessionData: SessionData = await this._dataLayer.getSessionData(userID); + + if (!sessionData.refresh_token) { + throw new AsgardeoAuthException( + 'JS-AUTH_CORE-RAT2-NF01', + 'No refresh token found.', + "There was no refresh token found. Asgardeo doesn't return a " + + 'refresh token if the refresh token grant is not enabled.', + ); + } + + if (!tokenEndpoint || tokenEndpoint.trim().length === 0) { + throw new AsgardeoAuthException( + 'JS-AUTH_CORE-RAT2-NF02', + 'No refresh token endpoint found.', + 'No refresh token endpoint was in the OIDC provider meta data returned by the well-known ' + + 'endpoint or the refresh token endpoint passed to the SDK is empty.', + ); + } + + const body: string[] = []; + + body.push(`client_id=${configData.clientID}`); + body.push(`refresh_token=${sessionData.refresh_token}`); + body.push('grant_type=refresh_token'); + + if (configData.clientSecret && configData.clientSecret.trim().length > 0) { + body.push(`client_secret=${configData.clientSecret}`); + } + + let tokenResponse: Response; + + try { + tokenResponse = await fetch(tokenEndpoint, { + body: body.join('&'), + credentials: configData.sendCookiesInRequests ? 'include' : 'same-origin', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/x-www-form-urlencoded', + }, + method: 'POST', + }); + } catch (error: any) { + throw new AsgardeoAuthException( + 'JS-AUTH_CORE-RAT2-NR03', + 'Refresh access token request failed.', + error ?? 'The request to refresh the access token failed.', + ); + } + + if (!tokenResponse.ok) { + throw new AsgardeoAuthException( + 'JS-AUTH_CORE-RAT2-HE04', + `Refreshing access token failed with ${tokenResponse.statusText}`, + (await tokenResponse.json()) as string, + ); + } + + return this._authenticationHelper.handleTokenResponse(tokenResponse, userID); + } + + public async revokeAccessToken(userID?: string): Promise { + const revokeTokenEndpoint: string | undefined = (await this._oidcProviderMetaData()).revocation_endpoint; + const configData: StrictAuthClientConfig = await this._config(); + + if (!revokeTokenEndpoint || revokeTokenEndpoint.trim().length === 0) { + throw new AsgardeoAuthException( + 'JS-AUTH_CORE-RAT3-NF01', + 'No revoke access token endpoint found.', + 'No revoke access token endpoint was found in the OIDC provider meta data returned by ' + + 'the well-known endpoint or the revoke access token endpoint passed to the SDK is empty.', + ); + } + + const body: string[] = []; + + body.push(`client_id=${configData.clientID}`); + body.push(`token=${(await this._dataLayer.getSessionData(userID)).access_token}`); + body.push('token_type_hint=access_token'); + + if (configData.clientSecret && configData.clientSecret.trim().length > 0) { + body.push(`client_secret=${configData.clientSecret}`); + } + + let response: Response; + + try { + response = await fetch(revokeTokenEndpoint, { + body: body.join('&'), + credentials: configData.sendCookiesInRequests ? 'include' : 'same-origin', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/x-www-form-urlencoded', + }, + method: 'POST', + }); + } catch (error: any) { + throw new AsgardeoAuthException( + 'JS-AUTH_CORE-RAT3-NE02', + 'The request to revoke access token failed.', + error ?? 'The request sent to revoke the access token failed.', + ); + } + + if (response.status !== 200 || !response.ok) { + throw new AsgardeoAuthException( + 'JS-AUTH_CORE-RAT3-HE03', + `Invalid response status received for revoke access token request (${response.statusText}).`, + (await response.json()) as string, + ); + } + + this._authenticationHelper.clearUserSessionData(userID); + + return Promise.resolve(response); + } + + public async requestCustomGrant( + customGrantParams: CustomGrantConfig, + userID?: string, + ): Promise { + const oidcProviderMetadata: OIDCDiscoveryApiResponse = await this._oidcProviderMetaData(); + const configData: StrictAuthClientConfig = await this._config(); + + let tokenEndpoint: string | undefined; + + if (customGrantParams.tokenEndpoint && customGrantParams.tokenEndpoint.trim().length !== 0) { + tokenEndpoint = customGrantParams.tokenEndpoint; + } else { + tokenEndpoint = oidcProviderMetadata.token_endpoint; + } + + if (!tokenEndpoint || tokenEndpoint.trim().length === 0) { + throw new AsgardeoAuthException( + 'JS-AUTH_CORE-RCG-NF01', + 'Token endpoint not found.', + 'No token endpoint was found in the OIDC provider meta data returned by the well-known endpoint ' + + 'or the token endpoint passed to the SDK is empty.', + ); + } + + const data: string[] = await Promise.all( + Object.entries(customGrantParams.data).map(async ([key, value]: [key: string, value: any]) => { + const newValue: string = await this._authenticationHelper.replaceCustomGrantTemplateTags( + value as string, + userID, + ); + + return `${key}=${newValue}`; + }), + ); + + let requestHeaders: Record = { + Accept: 'application/json', + 'Content-Type': 'application/x-www-form-urlencoded', + }; + + if (customGrantParams.attachToken) { + requestHeaders = { + ...requestHeaders, + Authorization: `Bearer ${(await this._dataLayer.getSessionData(userID)).access_token}`, + }; + } + + const requestConfig: FetchRequestConfig = { + body: data.join('&'), + credentials: configData.sendCookiesInRequests ? 'include' : 'same-origin', + headers: new Headers(requestHeaders), + method: 'POST', + }; + + let response: Response; + + try { + response = await fetch(tokenEndpoint, requestConfig); + } catch (error: any) { + throw new AsgardeoAuthException( + 'JS-AUTH_CORE-RCG-NE02', + 'The custom grant request failed.', + error ?? 'The request sent to get the custom grant failed.', + ); + } + + if (response.status !== 200 || !response.ok) { + throw new AsgardeoAuthException( + 'JS-AUTH_CORE-RCG-HE03', + `Invalid response status received for the custom grant request. (${response.statusText})`, + (await response.json()) as string, + ); + } + + if (customGrantParams.returnsSession) { + return this._authenticationHelper.handleTokenResponse(response, userID); + } else { + return Promise.resolve((await response.json()) as TokenResponse | FetchResponse); + } + } + + public async getBasicUserInfo(userID?: string): Promise { + const sessionData: SessionData = await this._dataLayer.getSessionData(userID); + const authenticatedUser: AuthenticatedUserInfo = this._authenticationHelper.getAuthenticatedUserInfo( + sessionData?.id_token, + ); + + let basicUserInfo: BasicUserInfo = { + allowedScopes: sessionData.scope, + sessionState: sessionData.session_state, + }; + + Object.keys(authenticatedUser).forEach((key: string) => { + if (authenticatedUser[key] === undefined || authenticatedUser[key] === '' || authenticatedUser[key] === null) { + delete authenticatedUser[key]; + } + }); + + basicUserInfo = {...basicUserInfo, ...authenticatedUser}; + + return basicUserInfo; + } + + public async getDecodedIDToken(userID?: string): Promise { + const idToken: string = (await this._dataLayer.getSessionData(userID)).id_token; + const payload: IdTokenPayload = this._cryptoHelper.decodeIDToken(idToken); + + return payload; + } + + public async getCryptoHelper(): Promise { + return this._cryptoHelper; + } + + public async getIDToken(userID?: string): Promise { + return (await this._dataLayer.getSessionData(userID)).id_token; + } + + public async getOIDCProviderMetaData(forceInit: boolean): Promise { + const configData: StrictAuthClientConfig = await this._config(); + + if ( + !forceInit && + (await this._dataLayer.getTemporaryDataParameter( + OIDCDiscoveryConstants.Storage.StorageKeys.OPENID_PROVIDER_CONFIG_INITIATED, + )) + ) { + return Promise.resolve(); + } + + const wellKnownEndpoint: string = (configData as any).wellKnownEndpoint; + + if (wellKnownEndpoint) { + let response: Response; + + try { + response = await fetch(wellKnownEndpoint); + if (response.status !== 200 || !response.ok) { + throw new Error(); + } + } catch { + throw new AsgardeoAuthException( + 'JS-AUTH_CORE-GOPMD-HE01', + 'Invalid well-known response', + 'The well known endpoint response has been failed with an error.', + ); + } + + await this._dataLayer.setOIDCProviderMetaData( + await this._authenticationHelper.resolveEndpoints(await response.json()), + ); + await this._dataLayer.setTemporaryDataParameter( + OIDCDiscoveryConstants.Storage.StorageKeys.OPENID_PROVIDER_CONFIG_INITIATED, + true, + ); + + return Promise.resolve(); + } else if ((configData as any).baseUrl) { + try { + await this._dataLayer.setOIDCProviderMetaData(await this._authenticationHelper.resolveEndpointsByBaseURL()); + } catch (error: any) { + throw new AsgardeoAuthException( + 'JS-AUTH_CORE-GOPMD-IV02', + 'Resolving endpoints failed.', + error ?? 'Resolving endpoints by base url failed.', + ); + } + await this._dataLayer.setTemporaryDataParameter( + OIDCDiscoveryConstants.Storage.StorageKeys.OPENID_PROVIDER_CONFIG_INITIATED, + true, + ); + + return Promise.resolve(); + } else { + await this._dataLayer.setOIDCProviderMetaData(await this._authenticationHelper.resolveEndpointsExplicitly()); + + await this._dataLayer.setTemporaryDataParameter( + OIDCDiscoveryConstants.Storage.StorageKeys.OPENID_PROVIDER_CONFIG_INITIATED, + true, + ); + + return Promise.resolve(); + } + } + + // TODO: Remove `Partial` once the refactoring is done. + public async getOIDCServiceEndpoints(): Promise> { + const oidcProviderMetaData: OIDCDiscoveryApiResponse = await this._oidcProviderMetaData(); + + return { + authorizationEndpoint: oidcProviderMetaData.authorization_endpoint ?? '', + checkSessionIframe: oidcProviderMetaData.check_session_iframe ?? '', + endSessionEndpoint: oidcProviderMetaData.end_session_endpoint ?? '', + introspectionEndpoint: oidcProviderMetaData.introspection_endpoint ?? '', + issuer: oidcProviderMetaData.issuer ?? '', + jwksUri: oidcProviderMetaData.jwks_uri ?? '', + registrationEndpoint: oidcProviderMetaData.registration_endpoint ?? '', + revocationEndpoint: oidcProviderMetaData.revocation_endpoint ?? '', + tokenEndpoint: oidcProviderMetaData.token_endpoint ?? '', + userinfoEndpoint: oidcProviderMetaData.userinfo_endpoint ?? '', + }; + } + + public async getSignOutURL(userID?: string): Promise { + const logoutEndpoint: string | undefined = (await this._oidcProviderMetaData())?.end_session_endpoint; + const configData: StrictAuthClientConfig = await this._config(); + + if (!logoutEndpoint || logoutEndpoint.trim().length === 0) { + throw new AsgardeoAuthException( + 'JS-AUTH_CORE-GSOU-NF01', + 'Sign-out endpoint not found.', + 'No sign-out endpoint was found in the OIDC provider meta data returned by the well-known endpoint ' + + 'or the sign-out endpoint passed to the SDK is empty.', + ); + } + + const callbackURL: string = configData?.signOutRedirectURL ?? configData?.signInRedirectURL; + + if (!callbackURL || callbackURL.trim().length === 0) { + throw new AsgardeoAuthException( + 'JS-AUTH_CORE-GSOU-NF03', + 'No sign-out redirect URL found.', + 'The sign-out redirect URL cannot be found or the URL passed to the SDK is empty. ' + + 'No sign-in redirect URL has been found either. ', + ); + } + const queryParams: URLSearchParams = new URLSearchParams(); + + queryParams.set('post_logout_redirect_uri', callbackURL); + + if (configData.sendIdTokenInLogoutRequest) { + const idToken: string = (await this._dataLayer.getSessionData(userID))?.id_token; + + if (!idToken || idToken.trim().length === 0) { + throw new AsgardeoAuthException( + 'JS-AUTH_CORE-GSOU-NF02', + 'ID token not found.', + 'No ID token could be found. Either the session information is lost or you have not signed in.', + ); + } + queryParams.set('id_token_hint', idToken); + } else { + queryParams.set('client_id', configData.clientID); + } + + queryParams.set('state', OIDCRequestConstants.Params.SIGN_OUT_SUCCESS); + + return `${logoutEndpoint}?${queryParams.toString()}`; + } + + public async clearUserSessionData(userID?: string): Promise { + await this._authenticationHelper.clearUserSessionData(userID); + } + + public async getAccessToken(userID?: string): Promise { + return (await this._dataLayer.getSessionData(userID))?.access_token; + } + + /** + * The created timestamp of the token response in milliseconds. + * + * @param userID - User ID + * @returns Created at timestamp of the token response in milliseconds. + */ + public async getCreatedAt(userID?: string): Promise { + return (await this._dataLayer.getSessionData(userID))?.created_at; + } + + /** + * The expires timestamp of the token response in seconds. + * + * @param userID - User ID + * @returns Expires in timestamp of the token response in seconds. + */ + public async getExpiresIn(userID?: string): Promise { + return (await this._dataLayer.getSessionData(userID))?.expires_in; + } + + public async isAuthenticated(userID?: string): Promise { + const isAccessTokenAvailable: boolean = Boolean(await this.getAccessToken(userID)); + + // Check if the access token is expired. + const createdAt: number = await this.getCreatedAt(userID); + + // Get the expires in value. + const expiresInString: string = await this.getExpiresIn(userID); + + // If the expires in value is not available, the token is invalid and the user is not authenticated. + if (!expiresInString) { + return false; + } + + // Convert to milliseconds. + const expiresIn: number = parseInt(expiresInString) * 1000; + const currentTime: number = new Date().getTime(); + const isAccessTokenValid: boolean = createdAt + expiresIn > currentTime; + + const isAuthenticated: boolean = isAccessTokenAvailable && isAccessTokenValid; + + return isAuthenticated; + } + + public async getPKCECode(state: string, userID?: string): Promise { + return (await this._dataLayer.getTemporaryDataParameter(extractPkceStorageKeyFromState(state), userID)) as string; + } + + public async setPKCECode(pkce: string, state: string, userID?: string): Promise { + return await this._dataLayer.setTemporaryDataParameter(extractPkceStorageKeyFromState(state), pkce, userID); + } + + public async updateConfig(config: Partial>): Promise { + await this._dataLayer.setConfigData(config); + await this.getOIDCProviderMetaData(true); + } +} diff --git a/packages/javascript/src/__legacy__/core/index.ts b/packages/javascript/src/__legacy__/core/index.ts new file mode 100644 index 000000000..886294844 --- /dev/null +++ b/packages/javascript/src/__legacy__/core/index.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from "./authentication-core"; diff --git a/packages/javascript/src/__legacy__/data/data-layer.ts b/packages/javascript/src/__legacy__/data/data-layer.ts new file mode 100644 index 000000000..c7729255f --- /dev/null +++ b/packages/javascript/src/__legacy__/data/data-layer.ts @@ -0,0 +1,229 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {Stores} from '../../models/store'; +import {Store} from '../../models/store'; +import {AuthClientConfig, SessionData} from '../models'; +import {TemporaryStore, TemporaryStoreValue} from '../../models/store'; +import {OIDCDiscoveryApiResponse} from '../../models/oidc-discovery'; + +type PartialData = Partial | OIDCDiscoveryApiResponse | SessionData | TemporaryStore>; + +export const ASGARDEO_SESSION_ACTIVE: string = 'asgardeo-session-active'; + +export class DataLayer { + protected _id: string; + protected _store: Store; + public constructor(instanceID: string, store: Store) { + this._id = instanceID; + this._store = store; + } + + protected async setDataInBulk(key: string, data: PartialData): Promise { + const existingDataJSON: string = (await this._store.getData(key)) ?? null; + const existingData: PartialData = existingDataJSON && JSON.parse(existingDataJSON); + + const dataToBeSaved: PartialData = {...existingData, ...data}; + const dataToBeSavedJSON: string = JSON.stringify(dataToBeSaved); + + await this._store.setData(key, dataToBeSavedJSON); + } + + protected async setValue( + key: string, + attribute: keyof AuthClientConfig | keyof OIDCDiscoveryApiResponse | keyof SessionData | keyof TemporaryStore, + value: TemporaryStoreValue, + ): Promise { + const existingDataJSON: string = (await this._store.getData(key)) ?? null; + const existingData: PartialData = existingDataJSON && JSON.parse(existingDataJSON); + + const dataToBeSaved: PartialData = {...existingData, [attribute]: value}; + const dataToBeSavedJSON: string = JSON.stringify(dataToBeSaved); + + await this._store.setData(key, dataToBeSavedJSON); + } + + protected async removeValue( + key: string, + attribute: keyof AuthClientConfig | keyof OIDCDiscoveryApiResponse | keyof SessionData | keyof TemporaryStore, + ): Promise { + const existingDataJSON: string = (await this._store.getData(key)) ?? null; + const existingData: PartialData = existingDataJSON && JSON.parse(existingDataJSON); + + const dataToBeSaved: PartialData = {...existingData}; + + delete dataToBeSaved[attribute as string]; + + const dataToBeSavedJSON: string = JSON.stringify(dataToBeSaved); + + await this._store.setData(key, dataToBeSavedJSON); + } + + protected _resolveKey(store: Stores | string, userID?: string): string { + return userID ? `${store}-${this._id}-${userID}` : `${store}-${this._id}`; + } + + protected isLocalStorageAvailable(): boolean { + try { + const testValue: string = '__ASGARDEO_AUTH_CORE_LOCAL_STORAGE_TEST__'; + + localStorage.setItem(testValue, testValue); + localStorage.removeItem(testValue); + + return true; + } catch (error) { + return false; + } + } + + public async setConfigData(config: Partial>): Promise { + await this.setDataInBulk(this._resolveKey(Stores.ConfigData), config); + } + + public async setOIDCProviderMetaData(oidcProviderMetaData: Partial): Promise { + this.setDataInBulk(this._resolveKey(Stores.OIDCProviderMetaData), oidcProviderMetaData); + } + + public async setTemporaryData(temporaryData: Partial, userID?: string): Promise { + this.setDataInBulk(this._resolveKey(Stores.TemporaryData, userID), temporaryData); + } + + public async setSessionData(sessionData: Partial, userID?: string): Promise { + this.setDataInBulk(this._resolveKey(Stores.SessionData, userID), sessionData); + } + + public async setCustomData(key: string, customData: Partial, userID?: string): Promise { + this.setDataInBulk(this._resolveKey(key, userID), customData); + } + + public async getConfigData(): Promise> { + return JSON.parse((await this._store.getData(this._resolveKey(Stores.ConfigData))) ?? null); + } + + public async getOIDCProviderMetaData(): Promise { + return JSON.parse((await this._store.getData(this._resolveKey(Stores.OIDCProviderMetaData))) ?? null); + } + + public async getTemporaryData(userID?: string): Promise { + return JSON.parse((await this._store.getData(this._resolveKey(Stores.TemporaryData, userID))) ?? null); + } + + public async getSessionData(userID?: string): Promise { + return JSON.parse((await this._store.getData(this._resolveKey(Stores.SessionData, userID))) ?? null); + } + + public async getCustomData(key: string, userID?: string): Promise { + return JSON.parse((await this._store.getData(this._resolveKey(key, userID))) ?? null); + } + + public setSessionStatus(status: string): void { + // Using local storage to store the session status as it is required to be available across tabs. + this.isLocalStorageAvailable() && localStorage.setItem(`${ASGARDEO_SESSION_ACTIVE}`, status); + } + + public getSessionStatus(): string { + return this.isLocalStorageAvailable() ? localStorage.getItem(`${ASGARDEO_SESSION_ACTIVE}`) ?? '' : ''; + } + + public removeSessionStatus(): void { + this.isLocalStorageAvailable() && localStorage.removeItem(`${ASGARDEO_SESSION_ACTIVE}`); + } + + public async removeConfigData(): Promise { + await this._store.removeData(this._resolveKey(Stores.ConfigData)); + } + + public async removeOIDCProviderMetaData(): Promise { + await this._store.removeData(this._resolveKey(Stores.OIDCProviderMetaData)); + } + + public async removeTemporaryData(userID?: string): Promise { + await this._store.removeData(this._resolveKey(Stores.TemporaryData, userID)); + } + + public async removeSessionData(userID?: string): Promise { + await this._store.removeData(this._resolveKey(Stores.SessionData, userID)); + } + + public async getConfigDataParameter(key: keyof AuthClientConfig): Promise { + const data: string = await this._store.getData(this._resolveKey(Stores.ConfigData)); + + return data && JSON.parse(data)[key]; + } + + public async getOIDCProviderMetaDataParameter(key: keyof OIDCDiscoveryApiResponse): Promise { + const data: string = await this._store.getData(this._resolveKey(Stores.OIDCProviderMetaData)); + + return data && JSON.parse(data)[key]; + } + + public async getTemporaryDataParameter(key: keyof TemporaryStore, userID?: string): Promise { + const data: string = await this._store.getData(this._resolveKey(Stores.TemporaryData, userID)); + + return data && JSON.parse(data)[key]; + } + + public async getSessionDataParameter(key: keyof SessionData, userID?: string): Promise { + const data: string = await this._store.getData(this._resolveKey(Stores.SessionData, userID)); + + return data && JSON.parse(data)[key]; + } + + public async setConfigDataParameter(key: keyof AuthClientConfig, value: TemporaryStoreValue): Promise { + await this.setValue(this._resolveKey(Stores.ConfigData), key, value); + } + + public async setOIDCProviderMetaDataParameter( + key: keyof OIDCDiscoveryApiResponse, + value: TemporaryStoreValue, + ): Promise { + await this.setValue(this._resolveKey(Stores.OIDCProviderMetaData), key, value); + } + + public async setTemporaryDataParameter( + key: keyof TemporaryStore, + value: TemporaryStoreValue, + userID?: string, + ): Promise { + await this.setValue(this._resolveKey(Stores.TemporaryData, userID), key, value); + } + + public async setSessionDataParameter( + key: keyof SessionData, + value: TemporaryStoreValue, + userID?: string, + ): Promise { + await this.setValue(this._resolveKey(Stores.SessionData, userID), key, value); + } + + public async removeConfigDataParameter(key: keyof AuthClientConfig): Promise { + await this.removeValue(this._resolveKey(Stores.ConfigData), key); + } + + public async removeOIDCProviderMetaDataParameter(key: keyof OIDCDiscoveryApiResponse): Promise { + await this.removeValue(this._resolveKey(Stores.OIDCProviderMetaData), key); + } + + public async removeTemporaryDataParameter(key: keyof TemporaryStore, userID?: string): Promise { + await this.removeValue(this._resolveKey(Stores.TemporaryData, userID), key); + } + + public async removeSessionDataParameter(key: keyof SessionData, userID?: string): Promise { + await this.removeValue(this._resolveKey(Stores.SessionData, userID), key); + } +} diff --git a/packages/javascript/src/__legacy__/data/index.ts b/packages/javascript/src/__legacy__/data/index.ts new file mode 100644 index 000000000..a91c45dc9 --- /dev/null +++ b/packages/javascript/src/__legacy__/data/index.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from "./data-layer"; diff --git a/packages/javascript/src/__legacy__/exception/exception.ts b/packages/javascript/src/__legacy__/exception/exception.ts new file mode 100644 index 000000000..ffb372499 --- /dev/null +++ b/packages/javascript/src/__legacy__/exception/exception.ts @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export class AsgardeoAuthException { + public name: string; + public code: string | undefined; + public message: string; + + public constructor( + code: string, + name: string, + message: string + ) { + this.message = message; + this.name = name; + this.code = code; + Object.setPrototypeOf(this, new.target.prototype); + } +} diff --git a/packages/javascript/src/__legacy__/exception/index.ts b/packages/javascript/src/__legacy__/exception/index.ts new file mode 100644 index 000000000..39dafe583 --- /dev/null +++ b/packages/javascript/src/__legacy__/exception/index.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from "./exception"; diff --git a/packages/javascript/src/__legacy__/helpers/authentication-helper.ts b/packages/javascript/src/__legacy__/helpers/authentication-helper.ts new file mode 100644 index 000000000..30e0e8b94 --- /dev/null +++ b/packages/javascript/src/__legacy__/helpers/authentication-helper.ts @@ -0,0 +1,300 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {IsomorphicCrypto} from '../../IsomorphicCrypto'; +import {DataLayer} from '../data'; +import {AsgardeoAuthException} from '../exception'; +import {AuthClientConfig, AuthenticatedUserInfo, SessionData, StrictAuthClientConfig} from '../models'; +import {JWKInterface} from '../../models/crypto'; +import {TokenResponse, AccessTokenApiResponse} from '../../models/token'; +import {IdTokenPayload} from '../../models/id-token'; +import PKCEConstants from '../../constants/PKCEConstants'; +import extractTenantDomainFromIdTokenPayload from '../../utils/extractTenantDomainFromIdTokenPayload'; +import extractUserClaimsFromIdToken from '../../utils/extractUserClaimsFromIdToken'; +import ScopeConstants from '../../constants/ScopeConstants'; +import OIDCDiscoveryConstants from '../../constants/OIDCDiscoveryConstants'; +import TokenExchangeConstants from '../../constants/TokenExchangeConstants'; +import {OIDCDiscoveryEndpointsApiResponse, OIDCDiscoveryApiResponse} from '../../models/oidc-discovery'; + +export class AuthenticationHelper { + private _dataLayer: DataLayer; + private _config: () => Promise; + private _oidcProviderMetaData: () => Promise; + private _cryptoHelper: IsomorphicCrypto; + + public constructor(dataLayer: DataLayer, cryptoHelper: IsomorphicCrypto) { + this._dataLayer = dataLayer; + this._config = async () => await this._dataLayer.getConfigData(); + this._oidcProviderMetaData = async () => await this._dataLayer.getOIDCProviderMetaData(); + this._cryptoHelper = cryptoHelper; + } + + public async resolveEndpoints(response: OIDCDiscoveryApiResponse): Promise { + const oidcProviderMetaData: OIDCDiscoveryApiResponse = {}; + const configData: StrictAuthClientConfig = await this._config(); + + configData.endpoints && + Object.keys(configData.endpoints).forEach((endpointName: string) => { + const snakeCasedName: string = endpointName.replace(/[A-Z]/g, (letter: string) => `_${letter.toLowerCase()}`); + + oidcProviderMetaData[snakeCasedName] = configData?.endpoints ? configData.endpoints[endpointName] : ''; + }); + + return {...response, ...oidcProviderMetaData}; + } + + public async resolveEndpointsExplicitly(): Promise { + const oidcProviderMetaData: OIDCDiscoveryApiResponse = {}; + const configData: StrictAuthClientConfig = await this._config(); + + const requiredEndpoints: string[] = [ + OIDCDiscoveryConstants.Storage.StorageKeys.Endpoints.AUTHORIZATION, + OIDCDiscoveryConstants.Storage.StorageKeys.Endpoints.END_SESSION, + OIDCDiscoveryConstants.Storage.StorageKeys.Endpoints.JWKS, + OIDCDiscoveryConstants.Storage.StorageKeys.Endpoints.SESSION_IFRAME, + OIDCDiscoveryConstants.Storage.StorageKeys.Endpoints.REVOCATION, + OIDCDiscoveryConstants.Storage.StorageKeys.Endpoints.TOKEN, + OIDCDiscoveryConstants.Storage.StorageKeys.Endpoints.ISSUER, + OIDCDiscoveryConstants.Storage.StorageKeys.Endpoints.USERINFO, + ]; + + const isRequiredEndpointsContains: boolean = configData.endpoints + ? requiredEndpoints.every((reqEndpointName: string) => { + return configData.endpoints + ? Object.keys(configData.endpoints).some((endpointName: string) => { + const snakeCasedName: string = endpointName.replace( + /[A-Z]/g, + (letter: string) => `_${letter.toLowerCase()}`, + ); + + return snakeCasedName === reqEndpointName; + }) + : false; + }) + : false; + + if (!isRequiredEndpointsContains) { + throw new AsgardeoAuthException( + 'JS-AUTH_HELPER-REE-NF01', + 'Required endpoints missing', + 'Some or all of the required endpoints are missing in the object passed to the `endpoints` ' + + 'attribute of the`AuthConfig` object.', + ); + } + + configData.endpoints && + Object.keys(configData.endpoints).forEach((endpointName: string) => { + const snakeCasedName: string = endpointName.replace(/[A-Z]/g, (letter: string) => `_${letter.toLowerCase()}`); + + oidcProviderMetaData[snakeCasedName] = configData?.endpoints ? configData.endpoints[endpointName] : ''; + }); + + return {...oidcProviderMetaData}; + } + + public async resolveEndpointsByBaseURL(): Promise { + const oidcProviderMetaData: OIDCDiscoveryEndpointsApiResponse = {}; + const configData: StrictAuthClientConfig = await this._config(); + + const baseUrl: string = (configData as any).baseUrl; + + if (!baseUrl) { + throw new AsgardeoAuthException( + 'JS-AUTH_HELPER_REBO-NF01', + 'Base URL not defined.', + 'Base URL is not defined in AuthClient config.', + ); + } + + configData.endpoints && + Object.keys(configData.endpoints).forEach((endpointName: string) => { + const snakeCasedName: string = endpointName.replace(/[A-Z]/g, (letter: string) => `_${letter.toLowerCase()}`); + + oidcProviderMetaData[snakeCasedName] = configData?.endpoints ? configData.endpoints[endpointName] : ''; + }); + + const defaultEndpoints: OIDCDiscoveryApiResponse = { + [OIDCDiscoveryConstants.Storage.StorageKeys.Endpoints + .AUTHORIZATION]: `${baseUrl}${OIDCDiscoveryConstants.Endpoints.AUTHORIZATION}`, + [OIDCDiscoveryConstants.Storage.StorageKeys.Endpoints + .END_SESSION]: `${baseUrl}${OIDCDiscoveryConstants.Endpoints.END_SESSION}`, + [OIDCDiscoveryConstants.Storage.StorageKeys.Endpoints + .ISSUER]: `${baseUrl}${OIDCDiscoveryConstants.Endpoints.ISSUER}`, + [OIDCDiscoveryConstants.Storage.StorageKeys.Endpoints.JWKS]: `${baseUrl}${OIDCDiscoveryConstants.Endpoints.JWKS}`, + [OIDCDiscoveryConstants.Storage.StorageKeys.Endpoints + .SESSION_IFRAME]: `${baseUrl}${OIDCDiscoveryConstants.Endpoints.SESSION_IFRAME}`, + [OIDCDiscoveryConstants.Storage.StorageKeys.Endpoints + .REVOCATION]: `${baseUrl}${OIDCDiscoveryConstants.Endpoints.REVOCATION}`, + [OIDCDiscoveryConstants.Storage.StorageKeys.Endpoints + .TOKEN]: `${baseUrl}${OIDCDiscoveryConstants.Endpoints.TOKEN}`, + [OIDCDiscoveryConstants.Storage.StorageKeys.Endpoints + .USERINFO]: `${baseUrl}${OIDCDiscoveryConstants.Endpoints.USERINFO}`, + }; + + return {...defaultEndpoints, ...oidcProviderMetaData}; + } + + public async validateIdToken(idToken: string): Promise { + const jwksEndpoint: string | undefined = (await this._dataLayer.getOIDCProviderMetaData()).jwks_uri; + const configData: StrictAuthClientConfig = await this._config(); + + if (!jwksEndpoint || jwksEndpoint.trim().length === 0) { + throw new AsgardeoAuthException( + 'JS_AUTH_HELPER-VIT-NF01', + 'JWKS endpoint not found.', + 'No JWKS endpoint was found in the OIDC provider meta data returned by the well-known endpoint ' + + 'or the JWKS endpoint passed to the SDK is empty.', + ); + } + + let response: Response; + + try { + response = await fetch(jwksEndpoint, { + credentials: configData.sendCookiesInRequests ? 'include' : 'same-origin', + }); + } catch (error: any) { + throw new AsgardeoAuthException( + 'JS-AUTH_HELPER-VIT-NE02', + 'Request to jwks endpoint failed.', + error ?? 'The request sent to get the jwks from the server failed.', + ); + } + + if (response.status !== 200 || !response.ok) { + throw new AsgardeoAuthException( + 'JS-AUTH_HELPER-VIT-HE03', + `Invalid response status received for jwks request (${response.statusText}).`, + (await response.json()) as string, + ); + } + + const issuer: string | undefined = (await this._oidcProviderMetaData()).issuer; + + const {keys}: {keys: JWKInterface[]} = (await response.json()) as { + keys: JWKInterface[]; + }; + + const jwk: any = await this._cryptoHelper.getJWKForTheIdToken(idToken.split('.')[0], keys); + + return this._cryptoHelper.isValidIdToken( + idToken, + jwk, + (await this._config()).clientID, + issuer ?? '', + this._cryptoHelper.decodeIDToken(idToken).sub, + (await this._config()).clockTolerance, + (await this._config()).validateIDTokenIssuer ?? true, + ); + } + + public getAuthenticatedUserInfo(idToken: string): AuthenticatedUserInfo { + const payload: IdTokenPayload = this._cryptoHelper.decodeIDToken(idToken); + const tenantDomain: string = extractTenantDomainFromIdTokenPayload(payload); + const username: string = payload?.['username'] ?? ''; + const givenName: string = payload?.['given_name'] ?? ''; + const familyName: string = payload?.['family_name'] ?? ''; + const fullName: string = + givenName && familyName ? `${givenName} ${familyName}` : givenName ? givenName : familyName ? familyName : ''; + const displayName: string = payload.preferred_username ?? fullName; + + return { + displayName: displayName, + tenantDomain, + username: username, + ...extractUserClaimsFromIdToken(payload), + }; + } + + public async replaceCustomGrantTemplateTags(text: string, userID?: string): Promise { + let scope: string = ScopeConstants.OPENID; + const configData: StrictAuthClientConfig = await this._config(); + const sessionData: SessionData = await this._dataLayer.getSessionData(userID); + + if (configData.scope && configData.scope.length > 0) { + if (!configData.scope.includes(ScopeConstants.OPENID)) { + configData.scope.push(ScopeConstants.OPENID); + } + scope = configData.scope.join(' '); + } + + return text + .replace(TokenExchangeConstants.Placeholders.TOKEN, sessionData.access_token) + .replace( + TokenExchangeConstants.Placeholders.USERNAME, + this.getAuthenticatedUserInfo(sessionData.id_token).username, + ) + .replace(TokenExchangeConstants.Placeholders.SCOPE, scope) + .replace(TokenExchangeConstants.Placeholders.CLIENT_ID, configData.clientID) + .replace(TokenExchangeConstants.Placeholders.CLIENT_SECRET, configData.clientSecret ?? ''); + } + + public async clearUserSessionData(userID?: string): Promise { + await this._dataLayer.removeTemporaryData(userID); + await this._dataLayer.removeSessionData(userID); + } + + public async handleTokenResponse(response: Response, userID?: string): Promise { + if (response.status !== 200 || !response.ok) { + throw new AsgardeoAuthException( + 'JS-AUTH_HELPER-HTR-NE01', + `Invalid response status received for token request (${response.statusText}).`, + (await response.json()) as string, + ); + } + + //Get the response in JSON + const parsedResponse: AccessTokenApiResponse = (await response.json()) as AccessTokenApiResponse; + + parsedResponse.created_at = new Date().getTime(); + + const shouldValidateIdToken: boolean | undefined = (await this._config()).validateIDToken; + + if (shouldValidateIdToken) { + return this.validateIdToken(parsedResponse.id_token).then(async () => { + await this._dataLayer.setSessionData(parsedResponse, userID); + + const tokenResponse: TokenResponse = { + accessToken: parsedResponse.access_token, + createdAt: parsedResponse.created_at, + expiresIn: parsedResponse.expires_in, + idToken: parsedResponse.id_token, + refreshToken: parsedResponse.refresh_token, + scope: parsedResponse.scope, + tokenType: parsedResponse.token_type, + }; + + return Promise.resolve(tokenResponse); + }); + } else { + const tokenResponse: TokenResponse = { + accessToken: parsedResponse.access_token, + createdAt: parsedResponse.created_at, + expiresIn: parsedResponse.expires_in, + idToken: parsedResponse.id_token, + refreshToken: parsedResponse.refresh_token, + scope: parsedResponse.scope, + tokenType: parsedResponse.token_type, + }; + + await this._dataLayer.setSessionData(parsedResponse, userID); + + return Promise.resolve(tokenResponse); + } + } +} diff --git a/packages/javascript/src/__legacy__/helpers/index.ts b/packages/javascript/src/__legacy__/helpers/index.ts new file mode 100644 index 000000000..cc9eb3414 --- /dev/null +++ b/packages/javascript/src/__legacy__/helpers/index.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from './authentication-helper'; diff --git a/packages/javascript/src/__legacy__/models/authorization-url.ts b/packages/javascript/src/__legacy__/models/authorization-url.ts new file mode 100644 index 000000000..46287f51b --- /dev/null +++ b/packages/javascript/src/__legacy__/models/authorization-url.ts @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export type AuthorizationURLParams = Omit; + +export interface StrictGetAuthURLConfig { + fidp?: string; + forceInit?: boolean; +} + +export type GetAuthURLConfig = StrictGetAuthURLConfig & Record; diff --git a/packages/javascript/src/__legacy__/models/client-config.ts b/packages/javascript/src/__legacy__/models/client-config.ts new file mode 100644 index 000000000..c8478e33d --- /dev/null +++ b/packages/javascript/src/__legacy__/models/client-config.ts @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {ResponseMode} from '../../models/oauth-response'; +import {OIDCEndpoints} from '../../models/oidc-endpoints'; + +export interface DefaultAuthClientConfig { + signInRedirectURL: string; + signOutRedirectURL?: string; + clientHost?: string; + clientID: string; + clientSecret?: string; + enablePKCE?: boolean; + prompt?: string; + responseMode?: ResponseMode; + scope?: string[]; + validateIDToken?: boolean; + validateIDTokenIssuer?: boolean; + /** + * Allowed leeway for id_tokens (in seconds). + */ + clockTolerance?: number; + /** + * Specifies if cookies should be sent with access-token requests, refresh-token requests, + * custom-grant requests, etc. + * + */ + sendCookiesInRequests?: boolean; + sendIdTokenInLogoutRequest?: boolean; +} + +export interface WellKnownAuthClientConfig extends DefaultAuthClientConfig { + wellKnownEndpoint: string; + endpoints?: Partial; + baseUrl?: string; +} + +export interface BaseURLAuthClientConfig extends DefaultAuthClientConfig { + baseUrl: string; + endpoints?: Partial; + wellKnownEndpoint?: string; +} + +export interface ExplicitAuthClientConfig extends DefaultAuthClientConfig { + endpoints: OIDCEndpoints; + baseUrl?: string; + wellKnownEndpoint?: string; +} + +export type StrictAuthClientConfig = WellKnownAuthClientConfig | BaseURLAuthClientConfig | ExplicitAuthClientConfig; + +export type AuthClientConfig = StrictAuthClientConfig & T; diff --git a/packages/javascript/src/__legacy__/models/custom-grant.ts b/packages/javascript/src/__legacy__/models/custom-grant.ts new file mode 100644 index 000000000..aedbf25d4 --- /dev/null +++ b/packages/javascript/src/__legacy__/models/custom-grant.ts @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export interface CustomGrantConfig{ + id: string; + data: any; + signInRequired: boolean; + attachToken: boolean; + returnsSession: boolean; + tokenEndpoint?: string; + shouldReplayAfterRefresh?: boolean; +} diff --git a/packages/javascript/src/__legacy__/models/data.ts b/packages/javascript/src/__legacy__/models/data.ts new file mode 100644 index 000000000..54423225a --- /dev/null +++ b/packages/javascript/src/__legacy__/models/data.ts @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export interface SessionData { + access_token: string; + id_token: string; + expires_in: string; + scope: string; + refresh_token?: string; + token_type: string; + session_state: string; + created_at: number; +} diff --git a/packages/javascript/src/__legacy__/models/fetch.ts b/packages/javascript/src/__legacy__/models/fetch.ts new file mode 100644 index 000000000..ac7cf35d4 --- /dev/null +++ b/packages/javascript/src/__legacy__/models/fetch.ts @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export type Method = + | "get" + | "GET" + | "delete" + | "DELETE" + | "head" + | "HEAD" + | "options" + | "OPTIONS" + | "post" + | "POST" + | "put" + | "PUT" + | "patch" + | "PATCH" + | "purge" + | "PURGE" + | "link" + | "LINK" + | "unlink" + | "UNLINK"; + +export type FetchCredentials = "omit" | "same-origin" | "include"; + +export type FetchRedirect = "follow" | "error" | "manual"; + +export interface FetchRequestConfig extends RequestInit { + method?: Method; + url?: string; + credentials?: FetchCredentials; + body?: any; // FIXME: Add proper type + bodyUsed?: boolean; + cache?: any; // FIXME: Add proper type + destination?: string; + integrity?: string; + mode?: any; // FIXME: Add proper type + redirect?: FetchRedirect; + referrer?: string; + referrerPolicy?: any; +} + +export interface FetchResponse extends ResponseInit { + body: T; + ok: boolean; + bodyUsed?: boolean; + redirected?: boolean; + type: any; // FIXME: Add proper type + url: string; + //TODO: Implement trailer property once the MDN docs are completed + json(); + text(); + formData(); + blob(); + arrayBuffer(); +} + +export interface FetchError extends Error { + config: FetchRequestConfig; + code?: string; + request?: any; + response?: FetchResponse; + isFetchError: boolean; + // eslint-disable-next-line @typescript-eslint/ban-types + toJSON: () => object; +} diff --git a/packages/javascript/src/__legacy__/models/index.ts b/packages/javascript/src/__legacy__/models/index.ts new file mode 100644 index 000000000..90b310ab3 --- /dev/null +++ b/packages/javascript/src/__legacy__/models/index.ts @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from './client-config'; +export * from './data'; +export * from './custom-grant'; +export * from './authorization-url'; +export * from './user'; +export * from './fetch'; diff --git a/packages/javascript/src/__legacy__/models/user.ts b/packages/javascript/src/__legacy__/models/user.ts new file mode 100644 index 000000000..a4b64e0e0 --- /dev/null +++ b/packages/javascript/src/__legacy__/models/user.ts @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Interface containing the basic user information. + */ +export interface BasicUserInfo { + /** + * The email address of the user. + */ + email?: string | undefined; + /** + * The username of the user. + */ + username?: string | undefined; + /** + * The display name of the user. It is the preferred_username in the id token payload or the `sub`. + */ + displayName?: string | undefined; + /** + * The scopes allowed for the user. + */ + allowedScopes: string; + /** + * The tenant domain to which the user belongs. + */ + tenantDomain?: string | undefined; + /** + * The session state. + */ + sessionState: string; + /** + * The `uid` corresponding to the user who the ID token belongs to. + */ + sub?: string; + /** + * Any other attributes retrieved from teh `id_token`. + */ + [ key: string ]: any; +} + +/** + * Interface of the authenticated user. + */ +export interface AuthenticatedUserInfo { + /** + * Authenticated user's display name. + */ + displayName?: string | undefined; + /** + * Authenticated user's display name. + * @deprecated Use `displayName` instead. + */ + display_name?: string | undefined; + /** + * User's email. + */ + email?: string | undefined; + /** + * Available scopes. + */ + scope?: string | undefined; + /** + * Authenticated user's tenant domain. + */ + tenantDomain?: string | undefined; + /** + * Authenticated user's username. + */ + username: string; + [key: string]: any; +} diff --git a/packages/javascript/src/__tests__/.gitkeep b/packages/javascript/src/__tests__/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/packages/javascript/src/api/oidc/__tests__/getUserInfo.test.ts b/packages/javascript/src/api/oidc/__tests__/getUserInfo.test.ts new file mode 100644 index 000000000..6ffa0ce08 --- /dev/null +++ b/packages/javascript/src/api/oidc/__tests__/getUserInfo.test.ts @@ -0,0 +1,143 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {describe, it, expect, vi, beforeEach} from 'vitest'; +import getUserInfo from '../getUserInfo'; +import {User} from '../../../models/user'; +import AsgardeoAPIError from '../../../errors/AsgardeoAPIError'; + +describe('getUserInfo', (): void => { + beforeEach((): void => { + vi.resetAllMocks(); + }); + + it('should fetch user info successfully', async (): void => { + const mockUserInfo: User = { + id: 'test-id', + name: 'Test User', + email: 'test@example.com', + roles: ['user'], + groups: ['group1'], + }; + + global.fetch = vi.fn().mockResolvedValue({ + ok: true, + json: () => Promise.resolve(mockUserInfo), + }); + + const url: string = 'https://api.asgardeo.io/t//oauth2/userinfo'; + const result: User = await getUserInfo({url}); + + expect(fetch).toHaveBeenCalledWith(url, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json', + }, + }); + + expect(result).toEqual({ + id: 'test-id', + name: 'Test User', + email: 'test@example.com', + roles: ['user'], + groups: ['group1'], + }); + }); + + it('should handle missing optional fields', async (): void => { + const mockUserInfo: User = { + id: 'test-id', + name: 'Test User', + email: 'test@example.com', + }; + + global.fetch = vi.fn().mockResolvedValue({ + ok: true, + json: () => Promise.resolve(mockUserInfo), + }); + + const url: string = 'https://api.asgardeo.io/t//oauth2/userinfo'; + const result: User = await getUserInfo({url}); + + expect(result).toEqual({ + id: 'test-id', + name: 'Test User', + email: 'test@example.com', + }); + }); + + it('should throw AsgardeoAPIError on fetch failure', async (): void => { + const errorText: string = 'Failed to fetch'; + + global.fetch = vi.fn().mockResolvedValue({ + ok: false, + text: () => Promise.resolve(errorText), + status: 400, + statusText: 'Bad Request', + }); + + const url: string = 'https://api.asgardeo.io/t//oauth2/userinfo'; + + await expect(getUserInfo({url})).rejects.toThrow(AsgardeoAPIError); + await expect(getUserInfo({url})).rejects.toThrow(`Failed to fetch user info: ${errorText}`); + + const error: AsgardeoAPIError = await getUserInfo({url}).catch(e => e); + + expect(error.code).toBe('getUserInfo-ResponseError-001'); + expect(error.name).toBe('AsgardeoAPIError'); + }); + + it('should throw AsgardeoAPIError for invalid URL', async (): void => { + const invalidUrl: string = 'not-a-valid-url'; + + await expect(getUserInfo({url: invalidUrl})).rejects.toThrow(AsgardeoAPIError); + + const error: AsgardeoAPIError = await getUserInfo({url: invalidUrl}).catch(e => e); + + expect(error.message).toBe( + '🛡️ Asgardeo - @asgardeo/javascript: Invalid endpoint URL provided\n\n(code="getUserInfo-ValidationError-001")\n', + ); + expect(error.code).toBe('getUserInfo-ValidationError-001'); + expect(error.name).toBe('AsgardeoAPIError'); + }); + + it('should throw AsgardeoAPIError for undefined URL', async (): void => { + await expect(getUserInfo({})).rejects.toThrow(AsgardeoAPIError); + + const error: AsgardeoAPIError = await getUserInfo({}).catch(e => e); + + expect(error.message).toBe( + '🛡️ Asgardeo - @asgardeo/javascript: Invalid endpoint URL provided\n\n(code="getUserInfo-ValidationError-001")\n', + ); + expect(error.code).toBe('getUserInfo-ValidationError-001'); + expect(error.name).toBe('AsgardeoAPIError'); + }); + + it('should throw AsgardeoAPIError for empty string URL', async (): void => { + await expect(getUserInfo({url: ''})).rejects.toThrow(AsgardeoAPIError); + + const error: AsgardeoAPIError = await getUserInfo({url: ''}).catch(e => e); + + expect(error.message).toBe( + '🛡️ Asgardeo - @asgardeo/javascript: Invalid endpoint URL provided\n\n(code="getUserInfo-ValidationError-001")\n', + ); + expect(error.code).toBe('getUserInfo-ValidationError-001'); + expect(error.name).toBe('AsgardeoAPIError'); + }); +}); diff --git a/packages/javascript/src/api/oidc/getUserInfo.ts b/packages/javascript/src/api/oidc/getUserInfo.ts new file mode 100644 index 000000000..9d759fe6f --- /dev/null +++ b/packages/javascript/src/api/oidc/getUserInfo.ts @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {User} from '../../models/user'; +import AsgardeoAPIError from '../../errors/AsgardeoAPIError'; + +/** + * Retrieves the user information from the specified OIDC userinfo endpoint. + * + * @param requestConfig - Request configuration object. + * @returns A promise that resolves with the user information. + * @throw + * const userInfo = await getUserInfo({ + * url: "https://api.asgardeo.io/t//oauth2/userinfo", + * }); + * console.log(userInfo); + * } catch (error) { + * if (error instanceof AsgardeoAPIError) { + * console.error('Failed to get user info:', error.message); + * } + * } + * ``` + */ +const getUserInfo = async ({url, ...requestConfig}: Partial): Promise => { + try { + new URL(url); + } catch (error) { + throw new AsgardeoAPIError( + 'Invalid endpoint URL provided', + 'getUserInfo-ValidationError-001', + 'javascript', + 400, + 'Invalid Request', + ); + } + + const response: Response = await fetch(url, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json', + }, + ...requestConfig, + }); + + if (!response.ok) { + const errorText = await response.text(); + + throw new AsgardeoAPIError( + `Failed to fetch user info: ${errorText}`, + 'getUserInfo-ResponseError-001', + 'javascript', + response.status, + response.statusText, + ); + } + + return await response.json() as User; +}; + +export default getUserInfo; diff --git a/packages/javascript/src/constants/OIDCDiscoveryConstants.ts b/packages/javascript/src/constants/OIDCDiscoveryConstants.ts new file mode 100644 index 000000000..fe2919b0a --- /dev/null +++ b/packages/javascript/src/constants/OIDCDiscoveryConstants.ts @@ -0,0 +1,175 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Constants related to OpenID Connect (OIDC) metadata and endpoints. + * This object contains all the standard OIDC endpoints and storage keys + * used throughout the application for authentication and authorization. + * + * @remarks + * The constants are organized into two main sections: + * 1. Endpoints - Contains all OIDC standard endpoint paths + * 2. Storage - Contains keys used for storing OIDC-related data + * + * @example + * ```typescript + * // Using an endpoint + * const authEndpoint = OIDCDiscoveryConstants.Endpoints.AUTHORIZATION; + * + * // Using a storage key + * const tokenKey = OIDCDiscoveryConstants.Storage.StorageKeys.Endpoints.TOKEN; + * ``` + */ +const OIDCDiscoveryConstants = { + /** + * Collection of standard OIDC endpoint paths used for authentication flows. + * These endpoints are relative paths that should be appended to the base URL + * of your identity provider. + */ + + Endpoints: { + /** + * Authorization endpoint for initiating the OAuth2/OIDC flow. + * This endpoint is used to request authorization and receive an authorization code. + */ + AUTHORIZATION: '/oauth2/authorize', + + /** + * Session check iframe endpoint for session management. + * Used to monitor the user's session state through a hidden iframe. + */ + SESSION_IFRAME: '/oidc/checksession', + + /** + * End session endpoint for logout functionality. + * Used to terminate the user's session and perform logout operations. + */ + END_SESSION: '/oidc/logout', + + /** + * Token issuer endpoint. + * The endpoint that issues OAuth2/OIDC tokens. + */ + ISSUER: '/oauth2/token', + + /** + * JSON Web Key Set endpoint for key validation. + * Provides the public keys used to verify token signatures. + */ + JWKS: '/oauth2/jwks', + + /** + * Token revocation endpoint. + * Used to invalidate access or refresh tokens before they expire. + */ + REVOCATION: '/oauth2/revoke', + + /** + * Token endpoint for obtaining access tokens. + * Used to exchange authorization codes for access tokens and refresh tokens. + */ + TOKEN: '/oauth2/token', + + /** + * UserInfo endpoint for obtaining user claims. + * Provides authenticated user information when called with a valid access token. + */ + USERINFO: '/oauth2/userinfo', + }, + + /** + * Storage related constants used for maintaining OIDC state. + * These constants define the keys used to store OIDC-related data + * in the browser's storage mechanisms. + */ + + Storage: { + /** + * Storage keys for various OIDC endpoints and configurations. + * These keys are used to store endpoint URLs and configuration + * states in the browser's storage. + */ + + StorageKeys: { + /** + * Collection of storage keys for OIDC endpoints. + * These keys are used to store the discovered endpoint URLs + * from the OpenID Provider's configuration. + */ + + Endpoints: { + /** + * Storage key for the authorization endpoint URL. + * Used to store the URL where authorization requests should be sent. + */ + AUTHORIZATION: 'authorization_endpoint', + + /** + * Storage key for the token endpoint URL. + * Used to store the URL where token requests should be sent. + */ + TOKEN: 'token_endpoint', + + /** + * Storage key for the revocation endpoint URL. + * Used to store the URL where token revocation requests should be sent. + */ + REVOCATION: 'revocation_endpoint', + + /** + * Storage key for the end session endpoint URL. + * Used to store the URL where logout requests should be sent. + */ + END_SESSION: 'end_session_endpoint', + + /** + * Storage key for the JWKS URI endpoint URL. + * Used to store the URL where JSON Web Key Sets can be retrieved. + */ + JWKS: 'jwks_uri', + + /** + * Storage key for the session check iframe URL. + * Used to store the URL of the iframe used for session state monitoring. + */ + SESSION_IFRAME: 'check_session_iframe', + + /** + * Storage key for the issuer identifier URL. + * Used to store the URL that identifies the OpenID Provider. + */ + ISSUER: 'issuer', + + /** + * Storage key for the userinfo endpoint URL. + * Used to store the URL where user information can be retrieved. + */ + USERINFO: 'userinfo_endpoint', + }, + + /** + * Flag to track if OpenID Provider configuration is initiated. + * Used to determine if the OIDC discovery process has been started. + * This helps prevent duplicate initialization attempts. + */ + OPENID_PROVIDER_CONFIG_INITIATED: 'op_config_initiated', + }, + }, +} as const; + +export default OIDCDiscoveryConstants; diff --git a/packages/javascript/src/constants/OIDCRequestConstants.ts b/packages/javascript/src/constants/OIDCRequestConstants.ts new file mode 100644 index 000000000..652b05e77 --- /dev/null +++ b/packages/javascript/src/constants/OIDCRequestConstants.ts @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Constants representing standard OpenID Connect (OIDC) request and response parameters. + * These parameters are commonly used during authorization, token exchange, and logout flows. + */ +const OIDCRequestConstants = { + Params: { + /** + * The authorization code returned from the authorization endpoint. + * Used in the authorization code flow. + */ + AUTHORIZATION_CODE: 'code', + + /** + * Session state parameter used for session management between the client and the OP. + */ + SESSION_STATE: 'session_state', + + /** + * State parameter used to maintain state between the request and the callback. + * Helps in preventing CSRF attacks. + */ + STATE: 'state', + + /** + * Indicates whether sign-out was successful during the end-session flow. + * May be returned by the OP after a logout request. + */ + SIGN_OUT_SUCCESS: 'sign_out_success', + }, + + /** + * Sign-out related constants for managing the end-session flow in OIDC. + */ + SignOut: { + /** + * Storage-related constants for managing sign-out state. + */ + Storage: { + /** + * Collection of storage keys used in sign-out implementation + */ + StorageKeys: { + /** + * Storage key for the sign-out URL. + * Used to store the complete URL where the user should be redirected after + * completing the OIDC logout process. + */ + SIGN_OUT_URL: 'sign_out_url', + }, + }, + }, +} as const; + +export default OIDCRequestConstants; diff --git a/packages/javascript/src/constants/PKCEConstants.ts b/packages/javascript/src/constants/PKCEConstants.ts new file mode 100644 index 000000000..a70e8adc3 --- /dev/null +++ b/packages/javascript/src/constants/PKCEConstants.ts @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Constants related to Proof Key for Code Exchange (PKCE) implementation. + * This object contains all the necessary constants for implementing PKCE + * flow in the OAuth 2.0 authorization code grant. + * + * @remarks + * PKCE is an extension to the authorization code flow to prevent CSRF and + * authorization code injection attacks. The constants are organized into + * storage-related sections for managing PKCE state. + * + * @example + * ```typescript + * // Using storage keys + * const codeVerifierKey = PKCEConstants.Storage.StorageKeys.CODE_VERIFIER; + * const separator = PKCEConstants.Storage.StorageKeys.SEPARATOR; + * ``` + */ +const PKCEConstants = { + /** + * Storage-related constants for managing PKCE state + */ + Storage: { + /** + * Collection of storage keys used in PKCE implementation + */ + StorageKeys: { + /** + * Key used to store the PKCE code verifier in temporary storage. + * The code verifier is a cryptographically random string that is + * used to generate the code challenge. + */ + CODE_VERIFIER: 'pkce_code_verifier', + + /** + * Separator used in storage keys to create unique identifiers + * by combining different parts of the key. + */ + SEPARATOR: '#', + }, + }, +} as const; + +export default PKCEConstants; diff --git a/packages/javascript/src/constants/ScopeConstants.ts b/packages/javascript/src/constants/ScopeConstants.ts new file mode 100644 index 000000000..5f9daeb9d --- /dev/null +++ b/packages/javascript/src/constants/ScopeConstants.ts @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Constants for OAuth 2.0 and OpenID Connect scopes. + * These scopes define the level of access that the client application + * is requesting from the authorization server. + * + * @remarks + * Scopes are space-separated strings that represent different permissions. + * The 'openid' scope is required for OpenID Connect flows, while other + * scopes provide access to different resources or user information. + * + * @example + * ```typescript + * // Requesting OpenID Connect authentication + * const scope = [ScopeConstants.OPENID]; + * + * // Requesting profile information + * const scopes = [ScopeConstants.OPENID, ScopeConstants.PROFILE]; + * ``` + */ +const ScopeConstants = { + /** + * The base OpenID Connect scope. + * Required for all OpenID Connect flows. Indicates that the client + * is initiating an OpenID Connect authentication request. + */ + OPENID: 'openid', +} as const; + +export default ScopeConstants; diff --git a/packages/javascript/src/constants/TokenConstants.ts b/packages/javascript/src/constants/TokenConstants.ts new file mode 100644 index 000000000..a5ade7e1f --- /dev/null +++ b/packages/javascript/src/constants/TokenConstants.ts @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Constants related to OIDC token management and storage. + * This object contains configuration values and storage keys + * used in token validation and management processes. + * + * @remarks + * The constants are organized into two main sections: + * 1. SignatureValidation - Contains supported algorithms for token validation + * 2. Storage - Contains keys used for storing token-related data + * + * @example + * ```typescript + * // Using signature validation algorithms + * const algorithms = TokenConstants.SignatureValidation.SUPPORTED_ALGORITHMS; + * + * // Using storage keys + * const timerKey = TokenConstants.Storage.StorageKeys.REFRESH_TOKEN_TIMER; + * ``` + */ +const TokenConstants = { + /** + * Token signature validation constants. + * Contains configurations related to token signature verification. + */ + SignatureValidation: { + /** + * Fallback array of supported signature algorithms for OIDC token validation. + * These values are used when the supported algorithms cannot be retrieved from + * the .well-known/openid-configuration endpoint. + * + * Supported algorithms: + * - `RS256` - RSASSA-PKCS1-v1_5 using SHA-256 + * - `RS512` - RSASSA-PKCS1-v1_5 using SHA-512 + * - `RS384` - RSASSA-PKCS1-v1_5 using SHA-384 + * - `PS256` - RSASSA-PSS using SHA-256 and MGF1 with SHA-256 + */ + SUPPORTED_ALGORITHMS: ['RS256', 'RS512', 'RS384', 'PS256'], + }, + + /** + * Storage-related constants for OIDC tokens. + * Contains keys used to store token-related data in browser storage. + */ + Storage: { + /** + * Collection of storage keys used in token management. + * These keys are used to store and retrieve token-related + * information from browser storage. + */ + StorageKeys: { + /** + * Key used to store the refresh token timer identifier. + * This timer is used to schedule token refresh operations + * before the current token expires. + */ + REFRESH_TOKEN_TIMER: 'refresh_token_timer', + }, + }, +} as const; + +export default TokenConstants; diff --git a/packages/javascript/src/constants/TokenExchangeConstants.ts b/packages/javascript/src/constants/TokenExchangeConstants.ts new file mode 100644 index 000000000..a8822564e --- /dev/null +++ b/packages/javascript/src/constants/TokenExchangeConstants.ts @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Constants for OAuth 2.0 Token Exchange operations. + * This object contains placeholders used in token exchange requests + * and responses for dynamic value substitution. + * + * @remarks + * These placeholders are used in token exchange templates and are replaced + * with actual values during request processing. They help in creating + * flexible and reusable token exchange configurations. + * + * @example + * ```typescript + * // Using placeholders in a token exchange template + * const template = `grant_type=urn:ietf:params:oauth:grant-type:token-exchange&subject_token=${TokenExchangeConstants.Placeholders.TOKEN}`; + * ``` + */ +const TokenExchangeConstants = { + /** + * Collection of placeholder strings used in token exchange operations. + * These placeholders are replaced with actual values when processing + * token exchange requests. + */ + Placeholders: { + /** + * Placeholder for the token value in exchange requests. + * Usually replaced with an access token or refresh token. + */ + TOKEN: '{{token}}', + + /** + * Placeholder for the username in token exchange operations. + * Used when user identity needs to be included in the exchange. + */ + USERNAME: '{{username}}', + + /** + * Placeholder for OAuth scopes in token exchange requests. + * Replaced with space-separated scope strings. + */ + SCOPE: '{{scope}}', + + /** + * Placeholder for client ID in token exchange operations. + * Required for client authentication. + */ + CLIENT_ID: '{{clientID}}', + + /** + * Placeholder for client secret in token exchange operations. + * Used for client authentication in confidential client flows. + */ + CLIENT_SECRET: '{{clientSecret}}', + }, +} as const; + +export default TokenExchangeConstants; diff --git a/packages/javascript/src/errors/AsgardeoAPIError.ts b/packages/javascript/src/errors/AsgardeoAPIError.ts new file mode 100644 index 000000000..227498c2e --- /dev/null +++ b/packages/javascript/src/errors/AsgardeoAPIError.ts @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import AsgardeoError from './AsgardeoError'; + +/** + * Base class for all API-related errors in Asgardeo. This class extends AsgardeoError + * and adds support for HTTP status codes and status text. + * + * @example + * ```typescript + * throw new AsgardeoAPIError( + * "Failed to fetch user data", + * "API_FETCH_ERROR", + * 404, + * "Not Found" + * ); + * ``` + */ +export default class AsgardeoAPIError extends AsgardeoError { + /** + * Creates an instance of AsgardeoAPIError. + * + * @param message - Human-readable description of the error + * @param code - A unique error code that identifies the error type + * @param statusCode - HTTP status code of the failed request + * @param statusText - HTTP status text of the failed request + * @param origin - Optional. The SDK origin (e.g. 'react', 'vue'). Defaults to generic 'Asgardeo' + * @constructor + */ + constructor( + message: string, + code: string, + origin: string, + public readonly statusCode?: number, + public readonly statusText?: string, + ) { + super(message, code, origin); + + Object.defineProperty(this, 'name', { + value: 'AsgardeoAPIError', + configurable: true, + writable: true, + }); + } + + /** + * Returns a string representation of the API error + * @returns Formatted error string with name, code, status, and message + */ + public override toString(): string { + const status = this.statusCode ? ` (HTTP ${this.statusCode} - ${this.statusText})` : ''; + return `[${this.name}] (code="${this.code}")${status}\nMessage: ${this.message}`; + } +} diff --git a/packages/javascript/src/errors/AsgardeoError.ts b/packages/javascript/src/errors/AsgardeoError.ts new file mode 100644 index 000000000..5d34f6cb8 --- /dev/null +++ b/packages/javascript/src/errors/AsgardeoError.ts @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Base class for all Asgardeo errors. This class extends the native Error class + * and adds support for error codes and proper stack traces. Each error is prefixed + * with a shield emoji and the SDK name for easy identification. + * + * @example + * ```typescript + * // Create a new error with a message and code + * throw new AsgardeoError( + * "Invalid authentication response", + * "AUTH_ERROR" + * ); + * + * // Or with a specific SDK name + * throw new AsgardeoError( + * "Invalid authentication response", + * "AUTH_ERROR", + * "@asgardeo/react" + * ); + * + * // The error message will be formatted as: + * // 🛡️ Asgardeo React: Invalid authentication response + * // + * // (code="AUTH_ERROR") + */ +export default class AsgardeoError extends Error { + public readonly code: string; + public readonly origin: string; + + private static resolveOrigin(origin: string): string { + if (!origin) { + return '@asgardeo/javascript'; + } + + return `@asgardeo/${origin}`; + } + + constructor(message: string, code: string, origin: string) { + const _origin: string = AsgardeoError.resolveOrigin(origin); + const prefix: string = `🛡️ Asgardeo - ${_origin}:`; + const regex: RegExp = new RegExp(`🛡️\\s*Asgardeo\\s*-\\s*${_origin}:`, 'i'); + const sanitized: string = message.replace(regex, ''); + const _message: string = `${prefix} ${sanitized.trim()}\n\n(code="${code}")\n`; + + super(_message); + + this.name = new.target.name; + this.code = code; + this.origin = _origin; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, new.target); + } + } + + public override toString(): string { + return `[${this.name}]\nMessage: ${this.message}`; + } +} diff --git a/packages/javascript/src/errors/AsgardeoRuntimeError.ts b/packages/javascript/src/errors/AsgardeoRuntimeError.ts new file mode 100644 index 000000000..529a1ee4f --- /dev/null +++ b/packages/javascript/src/errors/AsgardeoRuntimeError.ts @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import AsgardeoError from './AsgardeoError'; + +/** + * Base class for all runtime errors in Asgardeo. This class extends AsgardeoError + * and adds support for additional error details. Use this class for errors that occur + * during runtime execution that are not related to API calls. + * + * @example + * ```typescript + * throw new AsgardeoRuntimeError( + * "Failed to parse configuration", + * "CONFIG_PARSE_ERROR", + * { invalidField: "redirectUri" } + * ); + * ``` + */ +export default class AsgardeoRuntimeError extends AsgardeoError { + /** + * Creates an instance of AsgardeoRuntimeError. + * + * @param message - Human-readable description of the error + * @param code - A unique error code that identifies the error type + * @param details - Additional details about the error that might be helpful for debugging + * @param origin - Optional. The SDK origin (e.g. 'react', 'vue'). Defaults to generic 'Asgardeo' + * @constructor + */ + constructor(message: string, code: string, origin: string, public readonly details?: unknown) { + super(message, code, origin); + + Object.defineProperty(this, 'name', { + value: 'AsgardeoRuntimeError', + configurable: true, + writable: true, + }); + } + + /** + * Returns a string representation of the runtime error + * @returns Formatted error string with name, code, details, and message + */ + public override toString(): string { + const details = this.details ? `\nDetails: ${JSON.stringify(this.details, null, 2)}` : ''; + return `[${this.name}] (code="${this.code}")${details}\nMessage: ${this.message}`; + } +} diff --git a/packages/javascript/src/errors/__tests__/AsgardeoAPIError.test.ts b/packages/javascript/src/errors/__tests__/AsgardeoAPIError.test.ts new file mode 100644 index 000000000..f778aa11f --- /dev/null +++ b/packages/javascript/src/errors/__tests__/AsgardeoAPIError.test.ts @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import AsgardeoAPIError from '../AsgardeoAPIError'; + +describe('AsgardeoAPIError', (): void => { + it('should create an API error with status code and text', (): void => { + const message: string = 'Not Found Error'; + const code: string = 'API_NOT_FOUND'; + const origin: string = 'react'; + const statusCode: number = 404; + const statusText: string = 'Not Found'; + const error = new AsgardeoAPIError(message, code, origin, statusCode, statusText); + + expect(error.message).toBe('🛡️ Asgardeo - @asgardeo/react: Not Found Error\n\n(code="API_NOT_FOUND")\n'); + expect(error.code).toBe(code); + expect(error.statusCode).toBe(statusCode); + expect(error.statusText).toBe(statusText); + }); + + it('should create an API error without status code and text', (): void => { + const message: string = 'Unknown API Error'; + const code: string = 'API_ERROR'; + const origin: string = 'javascript'; + const error = new AsgardeoAPIError(message, code, origin); + + expect(error.message).toBe('🛡️ Asgardeo - @asgardeo/javascript: Unknown API Error\n\n(code="API_ERROR")\n'); + expect(error.statusCode).toBeUndefined(); + expect(error.statusText).toBeUndefined(); + }); + + it('should have correct name and be instance of Error and AsgardeoAPIError', (): void => { + const message: string = 'Test Error'; + const code: string = 'TEST_ERROR'; + const origin: string = 'react'; + const error = new AsgardeoAPIError(message, code, origin); + + expect(error.name).toBe('AsgardeoAPIError'); + expect(error).toBeInstanceOf(Error); + expect(error).toBeInstanceOf(AsgardeoAPIError); + }); + + it('should format toString with status when available', (): void => { + const message: string = 'Bad Request'; + const code: string = 'API_BAD_REQUEST'; + const origin: string = 'react'; + const statusCode: number = 400; + const statusText: string = 'Bad Request'; + const error = new AsgardeoAPIError(message, code, origin, statusCode, statusText); + + const expected: string = + '[AsgardeoAPIError] (code="API_BAD_REQUEST") (HTTP 400 - Bad Request)\n' + + 'Message: 🛡️ Asgardeo - @asgardeo/react: Bad Request\n\n(code="API_BAD_REQUEST")\n'; + + expect(error.toString()).toBe(expected); + }); + + it('should format toString without status when not available', (): void => { + const message: string = 'Test Error'; + const code: string = 'TEST_ERROR'; + const origin: string = 'react'; + const error = new AsgardeoAPIError(message, code, origin); + + const expected: string = + '[AsgardeoAPIError] (code="TEST_ERROR")\n' + + 'Message: 🛡️ Asgardeo - @asgardeo/react: Test Error\n\n(code="TEST_ERROR")\n'; + + expect(error.toString()).toBe(expected); + }); + + it('should default to the agnostic SDK if no origin is provided', (): void => { + const message: string = 'Test message'; + const code: string = 'TEST_ERROR'; + const error: AsgardeoError = new AsgardeoAPIError(message, code, ''); + + expect(error.origin).toBe('@asgardeo/javascript'); + }); +}); diff --git a/packages/javascript/src/errors/__tests__/AsgardeoError.test.ts b/packages/javascript/src/errors/__tests__/AsgardeoError.test.ts new file mode 100644 index 000000000..358fea278 --- /dev/null +++ b/packages/javascript/src/errors/__tests__/AsgardeoError.test.ts @@ -0,0 +1,108 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import AsgardeoError from '../AsgardeoError'; + +describe('AsgardeoError', (): void => { + it('should create an error with javascript SDK origin', (): void => { + const message: string = 'Test error message'; + const code: string = 'TEST_ERROR'; + const origin: string = 'javascript'; + const error = new AsgardeoError(message, code, origin); + + expect(error.message).toBe('🛡️ Asgardeo - @asgardeo/javascript: Test error message\n\n(code="TEST_ERROR")\n'); + expect(error.code).toBe(code); + }); + + it('should create an error with react SDK origin', (): void => { + const message: string = 'Test error message'; + const code: string = 'TEST_ERROR'; + const origin: string = 'react'; + const error = new AsgardeoError(message, code, origin); + + expect(error.message).toBe('🛡️ Asgardeo - @asgardeo/react: Test error message\n\n(code="TEST_ERROR")\n'); + expect(error.code).toBe(code); + }); + + it('should format different SDK origins correctly', (): void => { + const message: string = 'Test error message'; + const code: string = 'TEST_ERROR'; + const origins: string[] = ['react', 'nextjs', 'javascript']; + const expectedNames: string[] = [ + 'Asgardeo - @asgardeo/react', + 'Asgardeo - @asgardeo/nextjs', + 'Asgardeo - @asgardeo/javascript', + ]; + + origins.forEach((origin, index) => { + const error = new AsgardeoError(message, code, origin); + + expect(error.message).toContain(`🛡️ ${expectedNames[index]}:`); + }); + }); + + it('should sanitize message if it already contains the SDK prefix', (): void => { + const message: string = '🛡️ Asgardeo - @asgardeo/react: Already prefixed message'; + const code: string = 'TEST_ERROR'; + const origin: string = 'react'; + const error = new AsgardeoError(message, code, origin); + + expect(error.message).toBe('🛡️ Asgardeo - @asgardeo/react: Already prefixed message\n\n(code="TEST_ERROR")\n'); + expect(error.code).toBe(code); + }); + + it('should have correct name and be instance of Error', (): void => { + const message: string = 'Test message'; + const code: string = 'TEST_ERROR'; + const origin: string = 'javascript'; + const error = new AsgardeoError(message, code, origin); + + expect(error.name).toBe('AsgardeoError'); + expect(error).toBeInstanceOf(Error); + expect(error).toBeInstanceOf(AsgardeoError); + }); + + it('should have a stack trace', (): void => { + const message: string = 'Test message'; + const code: string = 'TEST_ERROR'; + const origin: string = 'javascript'; + const error = new AsgardeoError(message, code, origin); + + expect(error.stack).toBeDefined(); + }); + + it('should format toString output correctly with SDK origin', (): void => { + const message: string = 'Test message'; + const code: string = 'TEST_ERROR'; + const origin: string = 'react'; + const error: AsgardeoError = new AsgardeoError(message, code, origin); + + const expectedString: string = + '[AsgardeoError]\nMessage: 🛡️ Asgardeo - @asgardeo/react: Test message\n\n(code="TEST_ERROR")\n'; + + expect(error.toString()).toBe(expectedString); + }); + + it('should default to the agnostic SDK if no origin is provided', (): void => { + const message: string = 'Test message'; + const code: string = 'TEST_ERROR'; + const error: AsgardeoError = new AsgardeoError(message, code, ''); + + expect(error.origin).toBe('@asgardeo/javascript'); + }); +}); diff --git a/packages/javascript/src/errors/__tests__/AsgardeoRuntimeError.test.ts b/packages/javascript/src/errors/__tests__/AsgardeoRuntimeError.test.ts new file mode 100644 index 000000000..3c99759c7 --- /dev/null +++ b/packages/javascript/src/errors/__tests__/AsgardeoRuntimeError.test.ts @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import AsgardeoRuntimeError from '../AsgardeoRuntimeError'; + +describe('AsgardeoRuntimeError', (): void => { + it('should create a runtime error with details', (): void => { + const message: string = 'Configuration Error'; + const code: string = 'CONFIG_ERROR'; + const origin: string = 'react'; + const details = {invalidField: 'redirectUri', value: null}; + const error = new AsgardeoRuntimeError(message, code, origin, details); + + expect(error.message).toBe('🛡️ Asgardeo - @asgardeo/react: Configuration Error\n\n(code="CONFIG_ERROR")\n'); + expect(error.code).toBe(code); + expect(error.details).toEqual(details); + }); + + it('should create a runtime error without details', (): void => { + const message: string = 'Unknown Runtime Error'; + const code: string = 'RUNTIME_ERROR'; + const origin: string = 'javascript'; + const error = new AsgardeoRuntimeError(message, code, origin); + + expect(error.message).toBe('🛡️ Asgardeo - @asgardeo/javascript: Unknown Runtime Error\n\n(code="RUNTIME_ERROR")\n'); + expect(error.details).toBeUndefined(); + }); + + it('should have correct name and be instance of Error and AsgardeoRuntimeError', (): void => { + const message: string = 'Test Error'; + const code: string = 'TEST_ERROR'; + const origin: string = 'react'; + const error = new AsgardeoRuntimeError(message, code, origin); + + expect(error.name).toBe('AsgardeoRuntimeError'); + expect(error).toBeInstanceOf(Error); + expect(error).toBeInstanceOf(AsgardeoRuntimeError); + }); + + it('should format toString with details when available', (): void => { + const message: string = 'Validation Error'; + const code: string = 'VALIDATION_ERROR'; + const origin: string = 'react'; + const details = {reason: 'invalid_input', field: 'email'}; + const error = new AsgardeoRuntimeError(message, code, origin, details); + + const expected: string = + '[AsgardeoRuntimeError] (code="VALIDATION_ERROR")\n' + + 'Details: {\n "reason": "invalid_input",\n "field": "email"\n}\n' + + 'Message: 🛡️ Asgardeo - @asgardeo/react: Validation Error\n\n(code="VALIDATION_ERROR")\n'; + + expect(error.toString()).toBe(expected); + }); + + it('should format toString without details when not available', (): void => { + const message: string = 'Test Error'; + const code: string = 'TEST_ERROR'; + const origin: string = 'react'; + const error = new AsgardeoRuntimeError(message, code, origin); + + const expected: string = + '[AsgardeoRuntimeError] (code="TEST_ERROR")\n' + + 'Message: 🛡️ Asgardeo - @asgardeo/react: Test Error\n\n(code="TEST_ERROR")\n'; + + expect(error.toString()).toBe(expected); + }); + + it('should default to the agnostic SDK if no origin is provided', (): void => { + const message: string = 'Test message'; + const code: string = 'TEST_ERROR'; + const error: AsgardeoError = new AsgardeoRuntimeError(message, code, ''); + + expect(error.origin).toBe('@asgardeo/javascript'); + }); +}); diff --git a/packages/javascript/src/index.ts b/packages/javascript/src/index.ts new file mode 100644 index 000000000..7a3ec267a --- /dev/null +++ b/packages/javascript/src/index.ts @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from './__legacy__/client'; +export * from './__legacy__/models'; +export * from './models/oauth-response'; +export * from './IsomorphicCrypto'; +export * from './__legacy__/exception'; +export * from './__legacy__/data'; + +export {default as getUserInfo} from './api/oidc/getUserInfo'; + +export {default as TokenConstants} from './constants/TokenConstants'; +export {default as OIDCRequestConstants} from './constants/OIDCRequestConstants'; + +export {default as AsgardeoError} from './errors/AsgardeoError'; +export {default as AsgardeoAPIError} from './errors/AsgardeoAPIError'; +export {default as AsgardeoRuntimeError} from './errors/AsgardeoRuntimeError'; + +export {AsgardeoClient, SignInOptions, SignOutOptions} from './models/client'; +export {BaseConfig, Config, Preferences, ThemePreferences} from './models/config'; +export {TokenResponse} from './models/token'; +export {Crypto, JWKInterface} from './models/crypto'; +export {IdTokenPayload} from './models/id-token'; +export {OIDCEndpoints} from './models/oidc-endpoints'; +export {Store} from './models/store'; +export {User} from './models/user'; +export {Schema, SchemaAttribute, WellKnownSchemaIds} from './models/scim2-schema'; +export {RecursivePartial} from './models/utility-types'; + +export {default as AsgardeoJavaScriptClient} from './AsgardeoJavaScriptClient'; + +export {default as createTheme} from './theme/createTheme'; +export {ThemeColors, ThemeConfig, Theme, ThemeMode} from './theme/types'; + +export {default as extractUserClaimsFromIdToken} from './utils/extractUserClaimsFromIdToken'; +export {default as extractPkceStorageKeyFromState} from './utils/extractPkceStorageKeyFromState'; +export {default as removeTrailingSlash} from './utils/removeTrailingSlash'; diff --git a/packages/javascript/src/models/client.ts b/packages/javascript/src/models/client.ts new file mode 100644 index 000000000..3f06fc087 --- /dev/null +++ b/packages/javascript/src/models/client.ts @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {User} from './user'; + +export type SignInOptions = Record; +export type SignOutOptions = Record; + +/** + * Interface defining the core functionality for Asgardeo authentication clients. + * + * @example + * ```typescript + * class AsgardeoNodeClient implements AsgardeoClient { + * // Implement interface methods + * } + * ``` + */ +export interface AsgardeoClient { + /** + * Gets user information from the session. + * + * @returns User object containing user details. + */ + getUser(): Promise; + + /** + * Initializes the authentication client with provided configuration. + * + * @param config - SDK Client instance configuration options. + * @returns Promise resolving to boolean indicating success. + */ + initialize(config: T): Promise; + + /** + * Checks if the client is currently loading. + * This can be used to determine if the client is in the process of initializing or fetching user data. + * + * @returns Boolean indicating if the client is loading. + */ + isLoading(): boolean; + + /** + * Checks if a user is signed in. + * FIXME: This should be integrated with the existing isAuthenticated method which returns a Promise. + * + * @returns Boolean indicating sign-in status. + */ + isSignedIn(): Promise; + + /** + * Initiates the sign-in process for the user. + * + * @param options - Optional sign-in options like additional parameters to be sent in the authorize request, etc. + * @returns Promise resolving the user upon successful sign in. + */ + signIn(options?: SignInOptions): Promise; + + /** + * Signs out the currently signed-in user. + * + * @param options - Optional sign-out options like additional parameters to be sent in the sign-out request, etc. + * @param afterSignOut - Callback function to be executed after sign-out is complete. + * @returns A promise that resolves to true if sign-out is successful + */ + signOut(options?: SignOutOptions, afterSignOut?: (redirectUrl: string) => void): Promise; + + /** + * Signs out the currently signed-in user with an optional session ID. + * + * @param options - Optional sign-out options like additional parameters to be sent in the sign-out request, etc. + * @param sessionId - Optional session ID to be used for sign-out. + * This can be useful in scenarios where multiple sessions are managed. + * @param afterSignOut - Callback function to be executed after sign-out is complete. + * @returns A promise that resolves to true if sign-out is successful + */ + signOut(options?: SignOutOptions, sessionId?: string, afterSignOut?: (redirectUrl: string) => void): Promise; +} diff --git a/packages/javascript/src/models/config.ts b/packages/javascript/src/models/config.ts new file mode 100644 index 000000000..740065e53 --- /dev/null +++ b/packages/javascript/src/models/config.ts @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {ThemeConfig, ThemeMode} from '../theme/types'; +import { RecursivePartial } from './utility-types'; + +export interface BaseConfig { + /** + * Optional URL where the authorization server should redirect after authentication. + * This must match one of the allowed redirect URIs configured in your IdP. + * If not provided, the framework layer will use the default redirect URL based on the application type. + * + * @example + * For development: "http://localhost:3000/api/auth/callback" + * For production: "https://your-app.com/api/auth/callback" + */ + afterSignInUrl?: string | undefined; + + /** + * The base URL of the Asgardeo identity server. + * Example: "https://api.asgardeo.io/t/{org_name}" + */ + baseUrl: string | undefined; + + /** + * The client ID obtained from the Asgardeo application registration. + * This is used to identify your application during authentication. + */ + clientId: string | undefined; + + /** + * Optional client secret for the application. + * Only required when using confidential client flows. + * Not recommended for public clients like browser applications. + */ + clientSecret?: string | undefined; + + /** + * The scopes to request during authentication. + * Accepts either a space-separated string or an array of strings. + * + * These define what access the token should grant (e.g., openid, profile, email). + * If not provided, defaults to `["openid"]`. + * + * @example + * scopes: "openid profile email" + * @example + * scopes: ["openid", "profile", "email"] + */ + scopes?: string | string[] | undefined; + + /** + * Preferences for customizing the Asgardeo UI components + */ + preferences?: Preferences; +} + +export type Config = BaseConfig; + +export interface ThemePreferences { + /** + * The theme mode to use. Defaults to 'system'. + */ + mode?: ThemeMode; + /** + * Theme overrides to customize the default theme + */ + overrides?: RecursivePartial; +} + +export interface Preferences { + /** + * Theme preferences for the Asgardeo UI components + */ + theme?: ThemePreferences; +} diff --git a/packages/javascript/src/models/crypto.ts b/packages/javascript/src/models/crypto.ts new file mode 100644 index 000000000..85c435570 --- /dev/null +++ b/packages/javascript/src/models/crypto.ts @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * JWK Model + */ +export interface JWKInterface { + kty: string; + e: string; + use: string; + kid: string; + alg: string; + n: string; +} + +/** + * Cryptographic utility interface for OIDC operations. + * Provides methods for encoding, decoding, hashing, and JWT verification + * used in OAuth2/OIDC flows. + * + * @remarks + * This interface abstracts cryptographic operations needed for: + * - PKCE challenge/verifier generation + * - JWT token validation + * - Base64URL encoding/decoding + * - Secure random number generation + * + * @example + * ```typescript + * class MyCrypto implements Crypto { + * base64URLEncode(value: Uint8Array): string { + * // Implementation + * } + * // ... other implementations + * } + * ``` + */ +export interface Crypto { + /** + * Encode the provided data in base64url format. + * + * @param value - Data to be encoded. + * + * @returns Encoded data. + */ + base64URLEncode(value: T): string; + + /** + * Decode the provided data encoded in base64url format. + * + * @param value - Data to be decoded. + * + * @returns Decoded data. + */ + base64URLDecode(value: string): string; + + /** + * Generate random bytes. + * + * @param length - Length of the random bytes to be generated. + * + * @returns Random bytes. + */ + generateRandomBytes(length: number): T; + + /** + * Hash the provided data using SHA-256. + * + * @param data - Data to be hashed. + * + * @returns Hashed data. + */ + hashSha256(data: string): T; + + /** + * Verify the provided JWT. + * + * @param idToken - ID Token to be verified. + * @param jwk - JWK to be used for verification. + * @param algorithms - Algorithms to be used for verification. + * @param clientID - Client ID to be used for verification. + * @param issuer - Issuer to be used for verification. + * @param subject - Subject to be used for verification. + * @param clockTolerance - Clock tolerance to be used for verification. + * + * @returns True if the ID Token is valid. + * + * @throws if the id_token is invalid. + */ + verifyJwt( + idToken: string, + jwk: JWKInterface, + algorithms: string[], + clientID: string, + issuer: string, + subject: string, + clockTolerance?: number, + validateJwtIssuer?: boolean, + ): Promise; +} diff --git a/packages/javascript/src/models/id-token.ts b/packages/javascript/src/models/id-token.ts new file mode 100644 index 000000000..5953b0286 --- /dev/null +++ b/packages/javascript/src/models/id-token.ts @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Interface for the standard (required) claims of an ID Token payload. + */ +export interface IdTokenPayloadStandardClaims { + /** + * The audience for which this token is intended. + */ + aud: string | string[]; + + /** + * The unique identifier of the user to whom the ID token belongs. + */ + sub: string; + + /** + * The issuer identifier for the issuer of the response. + */ + iss: string; + + /** + * The email of the user. + */ + email?: string; + + /** + * The username the user prefers to be called. + */ + preferred_username?: string; + + /** + * The tenant domain of the user. + */ + tenant_domain?: string; +} + +/** + * Interface for ID Token payload including custom claims. + */ +export interface IdTokenPayload extends IdTokenPayloadStandardClaims { + /** + * Other custom claims. + */ + [claim: string]: any; +} diff --git a/packages/javascript/src/models/oauth-response.ts b/packages/javascript/src/models/oauth-response.ts new file mode 100644 index 000000000..593e5c985 --- /dev/null +++ b/packages/javascript/src/models/oauth-response.ts @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Enum representing different OAuth response modes. + */ +export enum ResponseMode { + /** + * Response is returned as POST parameters in an HTML form. + */ + FormPost = 'form_post', + + /** + * Response is returned as query parameters in the URL. + */ + Query = 'query', + + /** + * Response is returned directly to the client. + */ + Direct = 'direct', +} diff --git a/packages/javascript/src/models/oidc-discovery.ts b/packages/javascript/src/models/oidc-discovery.ts new file mode 100644 index 000000000..96440c333 --- /dev/null +++ b/packages/javascript/src/models/oidc-discovery.ts @@ -0,0 +1,435 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Comprehensive OpenID Connect (OIDC) Provider Metadata. + * This interface represents the complete set of configuration metadata + * that an OpenID Provider (OP) may publish at its discovery endpoint. + * + * @remarks + * The metadata is organized into several categories: + * 1. Core Endpoints - Essential URLs for OIDC operations + * 2. Capability Indicators - Supported features and algorithms + * 3. Claims and Scopes - Available user information + * 4. Security Settings - Authentication and encryption options + * 5. UI/UX Configuration - Display and localization preferences + * + * All fields are optional as per the OIDC Discovery specification, + * allowing for flexible provider implementations. + * + * @see {@link https://openid.net/specs/openid-connect-discovery-1_0.html OpenID Connect Discovery Specification} + * + * @example + * ```typescript + * const config: OIDCProviderMetadata = { + * issuer: "https://accounts.example.com", + * authorization_endpoint: "https://accounts.example.com/auth", + * token_endpoint: "https://accounts.example.com/token", + * userinfo_endpoint: "https://accounts.example.com/userinfo", + * jwks_uri: "https://accounts.example.com/jwks.json" + * }; + * ``` + */ +export interface OIDCDiscoveryApiResponse extends OIDCDiscoveryEndpointsApiResponse { + /** + * Supported OAuth 2.0 scope values. + * Lists the permission scopes this server can handle. + * + * @remarks + * Common values include: + * - 'openid' - Required for OIDC flows + * - 'profile' - Basic user information + * - 'email' - User's email address + * - 'address' - User's postal address + * - 'phone' - User's phone number + */ + scopes_supported?: string[]; + + // ==================================== + // Authentication & Response Options + // ==================================== + + /** + * Supported OAuth 2.0 response_type values. + * + * @remarks + * Common values include: + * - 'code' - Authorization Code flow + * - 'token' - Implicit flow + * - 'id_token' - OIDC implicit flow + * - 'code token' - Hybrid flow + */ + response_types_supported?: string[]; + + /** + * Supported OAuth 2.0 response_mode values. + * + * @remarks + * Determines how the authorization response is returned: + * - 'query' - Parameters in URL query string + * - 'fragment' - Parameters in URL fragment + * - 'form_post' - Parameters via POST + */ + response_modes_supported?: string[]; + + /** + * Supported OAuth 2.0 grant type values. + * + * @remarks + * Common values include: + * - 'authorization_code' - Standard OAuth 2.0 auth code flow + * - 'implicit' - Implicit flow + * - 'refresh_token' - Refresh token grant + * - 'client_credentials' - Client credentials grant + */ + grant_types_supported?: string[]; + + // ==================================== + // Security Features + // ==================================== + + /** + * Supported Authentication Context Class References. + * Indicates the OP's ability to satisfy specific authentication requirements. + */ + acr_values_supported?: string[]; + + /** + * Supported Subject Identifier types. + * Defines how the OP identifies users across sessions. + * + * @remarks + * Common values: + * - 'public' - Same sub value for all clients + * - 'pairwise' - Different sub values for different clients + */ + subject_types_supported?: string[]; + + /** + * JSON array containing a list of the JWS signing algorithms (alg values) + * supported by the OP for the ID Token to encode the Claims in a JWT [JWT]. + */ + id_token_signing_alg_values_supported?: string[]; + + /** + * JSON array containing a list of the JWE encryption algorithms (alg values) + * supported by the OP for the ID Token to encode the Claims in a JWT [JWT]. + */ + id_token_encryption_alg_values_supported?: string[]; + + /** + * JSON array containing a list of the JWE encryption algorithms (enc values) + * supported by the OP for the ID Token to encode the Claims in a JWT [JWT]. + */ + id_token_encryption_enc_values_supported?: string[]; + + /** + * JSON array containing a list of the JWS [JWS] signing algorithms (alg values) [JWA] + * supported by the UserInfo Endpoint to encode the Claims in a JWT [JWT]. + */ + userinfo_signing_alg_values_supported?: string[]; + + /** + * JSON array containing a list of the JWE [JWE] encryption algorithms (alg values) + * [JWA] supported by the UserInfo Endpoint to encode the Claims in a JWT [JWT]. + */ + userinfo_encryption_alg_values_supported?: string[]; + + /** + * JSON array containing a list of the JWE encryption algorithms (enc values) [JWA] + * supported by the UserInfo Endpoint to encode the Claims in a JWT [JWT] + */ + userinfo_encryption_enc_values_supported?: string[]; + + /** + * JSON array containing a list of the JWS signing algorithms (alg values) supported by the OP for Request Objects + */ + request_object_signing_alg_values_supported?: string[]; + + /** + * JSON array containing a list of the JWE encryption algorithms (alg values) + * supported by the OP for Request Objects. + */ + request_object_encryption_alg_values_supported?: string[]; + + /** + * JSON array containing a list of the JWE encryption algorithms (enc values) + * supported by the OP for Request Objects. + */ + request_object_encryption_enc_values_supported?: string[]; + + /** + * JSON array containing a list of Client Authentication methods supported by this Token Endpoint. + */ + token_endpoint_auth_methods_supported?: string[]; + + /** + * JSON array containing a list of the JWS signing algorithms (alg values) supported by the Token Endpoint + * for the signature on the JWT [JWT] used to authenticate the Client at the Token Endpoint for the + * private_key_jwt and client_secret_jwt authentication methods. + */ + token_endpoint_auth_signing_alg_values_supported?: string[]; + + /** + * JSON array containing a list of the display parameter values that the OpenID Provider supports. + */ + display_values_supported?: string[]; + + /** + * JSON array containing a list of the Claim Types that the OpenID Provider supports. + */ + claim_types_supported?: string[]; + + /** + * JSON array containing a list of the Claim Names of the Claims that + * the OpenID Provider MAY be able to supply values for. + */ + claims_supported?: string[]; + + /** + * URL of a page containing human-readable information that developers + * might want or need to know when using the OpenID Provider. + */ + service_documentation?: string; + + /** + * Languages and scripts supported for values in Claims being returned, represented as a JSON array + * of BCP47 [RFC5646] language tag values. Not all languages and scripts are necessarily + * supported for all Claim values. + */ + claims_locales_supported?: string[]; + + /** + * Languages and scripts supported for the user interface, + * represented as a JSON array of BCP47 [RFC5646] language tag values. + */ + ui_locales_supported?: string[]; + + /** + * Boolean value specifying whether the OP supports use of the claims parameter, + * with true indicating support. If omitted, the default value is false. + */ + claims_parameter_supported?: boolean; + + /** + * Boolean value specifying whether the OP supports use of the request parameter, + * with true indicating support. If omitted, the default value is false. + */ + request_parameter_supported?: boolean; + + /** + * Boolean value specifying whether the OP supports use of the request_uri parameter, + * with true indicating support. If omitted, the default value is true. + */ + request_uri_parameter_supported?: boolean; + + /** + * Boolean value specifying whether the OP requires any request_uri values used to be + * pre-registered using the request_uris registration parameter. + */ + require_request_uri_registration?: boolean; + + /** + * URL that the OpenID Provider provides to the person registering the Client + * to read about the OP's requirements on how the Relying Party can use the data provided by the OP. + */ + op_policy_uri?: string; + + /** + * URL that the OpenID Provider provides to the person registering the Client + * to read about OpenID Provider's terms of service. + */ + op_tos_uri?: string; + + /** + * JSON array containing a list of client authentication + * methods supported by this revocation endpoint. + */ + revocation_endpoint_auth_methods_supported?: string[]; + + /** + * JSON array containing a list of the JWS signing + * algorithms ("alg" values) supported by the revocation endpoint for + * the signature on the JWT [JWT] used to authenticate the client at + * the revocation endpoint for the "private_key_jwt" and + * "client_secret_jwt" authentication methods. + */ + revocation_endpoint_auth_signing_alg_values_supported?: string[]; + + /** + * JSON array containing a list of client authentication + * methods supported by this introspection endpoint. + */ + introspection_endpoint_auth_methods_supported?: string[]; + + /** + * JSON array containing a list of the JWS signing + * algorithms ("alg" values) supported by the introspection endpoint + * for the signature on the JWT [JWT] used to authenticate the client + * at the introspection endpoint for the "private_key_jwt" and + * "client_secret_jwt" authentication methods. + */ + introspection_endpoint_auth_signing_alg_values_supported?: string[]; + + /** + * JSON array containing a list of Proof Key for Code + * Exchange (PKCE) [RFC7636] code challenge methods supported by this + * authorization server. + */ + code_challenge_methods_supported?: string[]; + + /** + * Boolean value specifying whether the OP supports back-channel logout, with true indicating support. + * If omitted, the default value is false. + */ + backchannel_logout_supported?: boolean; + + /** + * Boolean value specifying whether the OP can pass a sid (session ID) Claim in the Logout Token to + * identify the RP session with the OP. + */ + backchannel_logout_session_supported?: boolean; +} + +/** + * Essential OpenID Connect (OIDC) Provider endpoints configuration. + * This interface represents the core set of endpoints that an OpenID Provider + * must expose for basic OIDC functionality. + * + * @remarks + * These endpoints form the foundation of OIDC operations and are organized into categories: + * 1. Authentication Flow - Authorization and token endpoints + * 2. User Data - UserInfo and session management + * 3. Security - Key management and token operations + * 4. Session Management - Logout and session state + * + * While all fields are optional in the interface, an OIDC Provider typically + * implements most of these endpoints for full OIDC compliance. + * + * @see {@link OIDCDiscoveryApiResponse} For the complete provider metadata + * @see {@link https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata Provider Metadata Specification} + * + * @example + * ```typescript + * const endpoints: OIDCDiscoveryEndpointsApiResponse = { + * issuer: "https://identity.example.com", + * authorization_endpoint: "https://identity.example.com/oauth2/authorize", + * token_endpoint: "https://identity.example.com/oauth2/token", + * userinfo_endpoint: "https://identity.example.com/oauth2/userinfo" + * }; + * ``` + */ +export interface OIDCDiscoveryEndpointsApiResponse { + // ==================================== + // Core Endpoints + // ==================================== + + /** + * HTTPS URL that the OP asserts as its Issuer Identifier. + * Must not contain query or fragment components. + * + * @remarks + * This is a crucial identifier for the OpenID Provider and should + * match the iss claim in issued JWT tokens. + */ + issuer?: string; + + /** + * OAuth 2.0 Authorization Endpoint URL. + * Used to initiate the authentication and authorization process. + * + * @remarks + * The client redirects the user to this endpoint to begin the auth flow. + * Supports various response_type values for different OAuth 2.0 flows. + */ + authorization_endpoint?: string; + + /** + * OAuth 2.0 Token Endpoint URL. + * Used to obtain tokens using various grant types. + * + * @remarks + * Clients use this endpoint to exchange authorization codes for tokens + * and to refresh expired access tokens. + */ + token_endpoint?: string; + + // ==================================== + // User Information & Key Management + // ==================================== + + /** + * UserInfo Endpoint URL. + * Returns claims about the authenticated end-user. + * + * @remarks + * Requires a valid access token with appropriate scope. + * May return claims in JWT format if signing/encryption is configured. + */ + userinfo_endpoint?: string; + + /** + * JSON Web Key Set (JWKS) document URL. + * Contains the cryptographic keys used to secure communications. + * + * @remarks + * Used by clients to: + * - Validate signatures on JWT tokens + * - Encrypt requests to the OP + * - Establish secure communications + */ + jwks_uri?: string; + + // ==================================== + // Registration & Dynamic Configuration + // ==================================== + + /** + * Dynamic Client Registration Endpoint URL. + * Allows automated registration of OAuth 2.0 clients. + * + * @remarks + * If supported, enables automated client setup and configuration. + * May require initial authentication or access tokens. + */ + registration_endpoint?: string; + + /** + * URL at the OP to which an RP can perform a redirect to request that the End-User be logged out at the + * OP. + */ + end_session_endpoint?: string; + + /** + * URL of an OP iframe that supports cross-origin communications for session state information with the RP + * Client, using the HTML5 postMessage API. + */ + check_session_iframe?: string; + + /** + * URL of the authorization server's OAuth 2.0 + * introspection endpoint. + */ + introspection_endpoint?: string; + + /** + * URL of the authorization server's OAuth 2.0 revocation + * endpoint. + */ + revocation_endpoint?: string; +} diff --git a/packages/javascript/src/models/oidc-endpoints.ts b/packages/javascript/src/models/oidc-endpoints.ts new file mode 100644 index 000000000..963f52006 --- /dev/null +++ b/packages/javascript/src/models/oidc-endpoints.ts @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * @deprecated Use the properties defined in the new `OIDCEndpoints` at the `/models/oidc-endpoints.ts` instead. + * FIXME: Remove this once the final refactoring is done. + */ +export interface LegacyOIDCEndpoints { + authorizationEndpoint: string; + tokenEndpoint: string; + userinfoEndpoint: string; + jwksUri: string; + registrationEndpoint?: string; + revocationEndpoint: string; + introspectionEndpoint?: string; + checkSessionIframe: string; + endSessionEndpoint: string; +} + +/** + * Interface representing OpenID Connect endpoints configuration. + * FIXME: Remove the temporary extends of legacy OIDC endpoints. + */ +export interface OIDCEndpoints extends Partial { + /** + * The issuer identifier URL for the OpenID Provider + */ + issuer: string; + + /** + * The OpenID Provider's discovery endpoint URL + */ + discovery: string; + + /** + * The authorization endpoint URL where the authentication request is sent + */ + authorization: string; + + /** + * The userinfo endpoint URL that returns claims about the authenticated user + */ + userinfo: string; + + /** + * The introspection endpoint URL used to validate tokens + */ + introspection: string; + + /** + * The JSON Web Key Set endpoint URL that provides the public keys to verify tokens + */ + jwks: string; + + /** + * The revocation endpoint URL used to revoke access or refresh tokens + */ + revocation: string; + + /** + * The end session endpoint URL used to terminate the user's session + */ + endSession: string; +} diff --git a/packages/javascript/src/models/scim2-schema.ts b/packages/javascript/src/models/scim2-schema.ts new file mode 100644 index 000000000..697debd54 --- /dev/null +++ b/packages/javascript/src/models/scim2-schema.ts @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export interface SchemaAttribute { + name: string; + type: string; + multiValued: boolean; + description?: string; + required?: boolean; + caseExact: boolean; + mutability: string; + returned: string; + uniqueness: string; + displayName?: string; + displayOrder?: string; + regEx?: string; + supportedByDefault?: string; + sharedProfileValueResolvingMethod?: string; + subAttributes?: SchemaAttribute[]; +} + +/** + * Represents a SCIM2 schema definition + */ +export interface Schema { + /** Schema identifier */ + id: string; + /** Schema name */ + name: string; + /** Schema description */ + description: string; + /** Schema attributes */ + attributes: SchemaAttribute[]; +} + +/** + * Well-known SCIM2 schema IDs + */ +export enum WellKnownSchemaIds { + /** Core Schema */ + Core = 'urn:ietf:params:scim:schemas:core:2.0', + /** User Schema */ + User = 'urn:ietf:params:scim:schemas:core:2.0:User', + /** Enterprise User Schema */ + EnterpriseUser = 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User', + /** System User Schema */ + SystemUser = 'urn:scim:wso2:schema', + /** Custom User Schema */ + CustomUser = 'urn:scim:schemas:extension:custom:User', +} diff --git a/packages/javascript/src/models/store.ts b/packages/javascript/src/models/store.ts new file mode 100644 index 000000000..986b83767 --- /dev/null +++ b/packages/javascript/src/models/store.ts @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {OIDCEndpoints} from './oidc-endpoints'; + +/** + * Interface representing a key-value storage mechanism. + * Implementations can include various storage backends like browser storage, + * memory cache, or distributed caches like Redis or Memcached. + */ +export interface Store { + /** + * Stores a value with the specified key. + * + * @param key - The unique identifier for the stored value + * @param value - The string value to store + * @returns A promise that resolves when the value is successfully stored + * @throws Error if storage operation fails + */ + setData(key: string, value: string): Promise; + + /** + * Retrieves a value by its key. + * + * @param key - The key of the value to retrieve + * @returns A promise that resolves with the stored value + * @throws Error if the key doesn't exist or retrieval fails + */ + getData(key: string): Promise; + + /** + * Removes a value from the store. + * + * @param key - The key of the value to remove + * @returns A promise that resolves when the value is successfully removed + * @throws Error if removal fails or the key doesn't exist + */ + removeData(key: string): Promise; +} + +/** + * Represents the possible value types that can be stored in the temporary data storage. + */ +export type TemporaryStoreValue = string | string[] | boolean | number | OIDCEndpoints; + +/** + * Represents a key-value store for temporary data storage. + */ +export type TemporaryStore = {[key: string]: TemporaryStoreValue}; + +/** + * Enum representing different types of data stores used in the application. + */ +export enum Stores { + /** + * Store for configuration data that defines the application's behavior and settings. + */ + ConfigData = 'config_data', + + /** + * Store for OpenID Connect provider metadata, including endpoints and configuration. + */ + OIDCProviderMetaData = 'oidc_provider_meta_data', + + /** + * Store for user session-related data like tokens and authentication state. + */ + SessionData = 'session_data', + + /** + * Store for temporary data that needs to persist only for a short duration. + */ + TemporaryData = 'temporary_data', +} diff --git a/packages/javascript/src/models/token.ts b/packages/javascript/src/models/token.ts new file mode 100644 index 000000000..10ffc0b54 --- /dev/null +++ b/packages/javascript/src/models/token.ts @@ -0,0 +1,135 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Represents a processed token response with standardized camelCase properties. + * This interface provides a clean, normalized structure for token data after + * processing the raw response from the authentication server. + * + * The properties in this interface follow JavaScript/TypeScript naming conventions + * and provide a more ergonomic API for client applications. + */ +export interface TokenResponse { + /** + * The bearer token used for authenticating API requests. + * This token should be included in the Authorization header + * of subsequent API requests. + */ + accessToken: string; + + /** + * JSON Web Token (JWT) containing user identity information. + * This token can be decoded to access user claims and metadata + * without additional server requests. + */ + idToken: string; + + /** + * Duration in seconds until the access token expires. + * Applications should refresh the token before this time + * to maintain uninterrupted access. + */ + expiresIn: string; + + /** + * Space-separated list of OAuth scopes granted to the application. + * These scopes determine what resources and actions the application + * has permission to access. + */ + scope: string; + + /** + * Token used to obtain new access tokens without re-authentication. + * Store this securely as it enables long-term access to the user's + * account through the refresh flow. + */ + refreshToken: string; + + /** + * The type of token issued, typically "Bearer". + * This indicates how the token should be used in + * API request Authorization headers. + */ + tokenType: string; + + /** + * Unix timestamp (in seconds) when the token was created. + * Used in combination with expiresIn to determine when + * the token needs to be refreshed. + */ + createdAt: number; +} + +/** + * Represents the raw token response received directly from the authentication server. + * This interface maintains the original snake_case property names as received in + * the server response before processing into the standardized TokenResponse format. + * + * The properties in this interface exactly match the OAuth2/OIDC server response + * format before any transformation or normalization is applied. + */ +export interface AccessTokenApiResponse { + /** + * Raw access token string from the server. + * This is the bearer token in its original format + * before any processing or validation. + */ + access_token: string; + + /** + * Raw expiration time in seconds. + * Indicates how long the access token will be valid + * from the time it was issued. + */ + expires_in: string; + + /** + * Server-provided creation timestamp in Unix seconds. + * Used to track when the token was originally issued + * and calculate absolute expiration time. + */ + created_at: number; + + /** + * Raw ID token string containing encoded user information. + * This JWT can be decoded to access standardized claims + * about the authenticated user. + */ + id_token: string; + + /** + * Raw refresh token string from the server. + * Used in its original format to request new access tokens + * when they expire. + */ + refresh_token: string; + + /** + * Raw space-separated scope string defining access permissions. + * Lists the OAuth scopes that were granted during the + * authorization process. + */ + scope: string; + + /** + * Raw token type identifier from the server. + * Typically "Bearer", indicating how the token should + * be used in API requests. + */ + token_type: string; +} diff --git a/packages/javascript/src/models/user.ts b/packages/javascript/src/models/user.ts new file mode 100644 index 000000000..ee1f0222c --- /dev/null +++ b/packages/javascript/src/models/user.ts @@ -0,0 +1,117 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {Schema} from './scim2-schema'; + +/** + * Type for the Meta object in SCIM2 responses + */ +export interface UserMeta { + created: string; + location: string; + lastModified: string; + resourceType: string; +} + +/** + * Type for the Role object in SCIM2 responses + */ +export interface UserRole { + audienceValue: string; + display: string; + audienceType: string; + value: string; + $ref: string; + audienceDisplay: string; +} + +/** + * Type for the Name object in SCIM2 responses + */ +export interface UserName { + formatted: string; + givenName: string; + familyName: string; +} + +/** + * Represents a user in the Asgardeo system. + * + * @remarks + * This interface defines the user properties based on the SCIM2 schema. + * WSO2 specific properties are flattened to the root level for easier access. + * + * @example + * ```typescript + * const user: User = { + * emails: ["user@example.com"], + * profileUrl: "https://gravatar.com/avatar/123", + * meta: { + * created: "2021-06-21T11:28:21.800618Z", + * location: "https://api.asgardeo.io/scim2/Users/123", + * lastModified: "2025-04-30T06:46:48.520896Z", + * resourceType: "User" + * }, + * name: { + * formatted: "John Smith", + * givenName: "John", + * familyName: "Smith" + * }, + * userName: "john@example.com", + * id: "123", + * // Flattened WSO2 schema properties + * accountState: "UNLOCKED", + * accountLocked: "false", + * photoUrl: "https://gravatar.com/avatar/123", + * emailVerified: "true", + * lastLogonTime: "1749098996152" + * }; + * ``` + */ +export interface User { + // Base SCIM2 properties + emails: string[]; + profileUrl?: string; + meta: UserMeta; + schemas: Schema[]; + roles?: UserRole[]; + name: UserName; + id: string; + userName: string; + + // Flattened WSO2 schema properties + accountState?: string; + accountLocked?: string; + failedLoginLockoutCount?: string; + failedTOTPAttempts?: string; + failedLoginAttempts?: string; + totpEnabled?: string; + photoUrl?: string; + emailVerified?: string; + backupCodeEnabled?: string; + lastLogonTime?: string; + signedUpRegion?: string; + unlockTime?: string; + isReadOnlyUser?: string; + failedLoginAttemptsBeforeSuccess?: string; + + // Allow additional properties + [key: string]: any; +} + +export default User; diff --git a/packages/javascript/src/models/utility-types.ts b/packages/javascript/src/models/utility-types.ts new file mode 100644 index 000000000..fe00fb606 --- /dev/null +++ b/packages/javascript/src/models/utility-types.ts @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export type RecursivePartial = { + [P in keyof T]?: RecursivePartial; +}; diff --git a/packages/javascript/src/theme/createTheme.ts b/packages/javascript/src/theme/createTheme.ts new file mode 100644 index 000000000..cfce1a218 --- /dev/null +++ b/packages/javascript/src/theme/createTheme.ts @@ -0,0 +1,156 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { RecursivePartial } from '../models/utility-types'; +import {Theme, ThemeConfig} from './types'; + +const lightTheme: ThemeConfig = { + colors: { + primary: { + main: '#1a73e8', + contrastText: '#ffffff', + }, + secondary: { + main: '#424242', + contrastText: '#ffffff', + }, + background: { + surface: '#f5f5f5', + disabled: '#f0f0f0', + body: { + main: '#1a1a1a', + }, + }, + error: { + main: '#d32f2f', + contrastText: '#ffffff', + }, + surface: '#f5f5f5', + text: { + primary: '#1a1a1a', + secondary: '#666666', + }, + border: '#e0e0e0', + }, + spacing: { + unit: 8, + }, + borderRadius: { + small: '4px', + medium: '8px', + large: '16px', + }, +}; + +const darkTheme: ThemeConfig = { + colors: { + primary: { + main: '#1a73e8', + contrastText: '#ffffff', + }, + secondary: { + main: '#424242', + contrastText: '#ffffff', + }, + background: { + surface: '#121212', + disabled: '#1f1f1f', + body: { + main: '#ffffff', + }, + }, + error: { + main: '#d32f2f', + contrastText: '#ffffff', + }, + surface: '#2d2d2d', + text: { + primary: '#ffffff', + secondary: '#b3b3b3', + }, + border: '#404040', + }, + spacing: { + unit: 8, + }, + borderRadius: { + small: '4px', + medium: '8px', + large: '16px', + }, +}; + +const toCssVariables = (theme: RecursivePartial): Record => { + const cssVars: Record = {}; + + // Colors + cssVars['--asgardeo-color-primary-main'] = theme.colors.primary.main; + cssVars['--asgardeo-color-primary-contrastText'] = theme.colors.primary.contrastText; + cssVars['--asgardeo-color-secondary-main'] = theme.colors.secondary.main; + cssVars['--asgardeo-color-secondary-contrastText'] = theme.colors.secondary.contrastText; + cssVars['--asgardeo-color-background-surface'] = theme.colors.background.surface; + cssVars['--asgardeo-color-background-disabled'] = theme.colors.background.disabled; + cssVars['--asgardeo-color-background-body-main'] = theme.colors.background.body.main; + cssVars['--asgardeo-color-error-main'] = theme.colors.error.main; + cssVars['--asgardeo-color-error-contrastText'] = theme.colors.error.contrastText; + cssVars['--asgardeo-color-surface'] = theme.colors.surface; + cssVars['--asgardeo-color-text-primary'] = theme.colors.text.primary; + cssVars['--asgardeo-color-text-secondary'] = theme.colors.text.secondary; + cssVars['--asgardeo-color-border'] = theme.colors.border; + + // Spacing + cssVars['--asgardeo-spacing-unit'] = `${theme.spacing.unit}px`; + + // Border Radius + cssVars['--asgardeo-border-radius-small'] = theme.borderRadius.small; + cssVars['--asgardeo-border-radius-medium'] = theme.borderRadius.medium; + cssVars['--asgardeo-border-radius-large'] = theme.borderRadius.large; + + return cssVars; +}; + +const createTheme = (config: RecursivePartial = {}, isDark = false): Theme => { + const baseTheme = isDark ? darkTheme : lightTheme; + const mergedConfig = { + ...baseTheme, + ...config, + colors: { + ...baseTheme.colors, + ...config.colors, + secondary: { + ...baseTheme.colors.secondary, + ...(config.colors?.secondary || {}), + }, + }, + spacing: { + ...baseTheme.spacing, + ...config.spacing, + }, + borderRadius: { + ...baseTheme.borderRadius, + ...config.borderRadius, + }, + } as ThemeConfig; + + return { + ...mergedConfig, + cssVariables: toCssVariables(mergedConfig), + }; +}; + +export default createTheme; diff --git a/packages/javascript/src/theme/types.ts b/packages/javascript/src/theme/types.ts new file mode 100644 index 000000000..9010026fe --- /dev/null +++ b/packages/javascript/src/theme/types.ts @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export interface ThemeColors { + primary: { + main: string; + contrastText: string; + }; + secondary: { + main: string; + contrastText: string; + }; + background: { + surface: string; + disabled: string; + body: { + main: string; + }; + }; + surface: string; + text: { + primary: string; + secondary: string; + }; + border: string; + error: { + main: string; + contrastText: string; + }; +} + +export interface ThemeConfig { + colors: ThemeColors; + spacing: { + unit: number; + }; + borderRadius: { + small: string; + medium: string; + large: string; + }; +} + +export interface Theme extends ThemeConfig { + cssVariables: Record; +} + +export type ThemeMode = 'light' | 'dark' | 'system'; diff --git a/packages/javascript/src/utils/__tests__/extractPkceStorageKeyFromState.test.ts b/packages/javascript/src/utils/__tests__/extractPkceStorageKeyFromState.test.ts new file mode 100644 index 000000000..cdcee348d --- /dev/null +++ b/packages/javascript/src/utils/__tests__/extractPkceStorageKeyFromState.test.ts @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {describe, expect, it} from 'vitest'; +import extractPkceStorageKeyFromState from '../extractPkceStorageKeyFromState'; +import PKCEConstants from '../../constants/PKCEConstants'; + +describe('extractPkceStorageKeyFromState', (): void => { + it('should extract PKCE key from state parameter', (): void => { + const state: string = 'request_1'; + const expectedKey: string = `${PKCEConstants.Storage.StorageKeys.CODE_VERIFIER}${PKCEConstants.Storage.StorageKeys.SEPARATOR}1`; + + expect(extractPkceStorageKeyFromState(state)).toBe(expectedKey); + }); + + it('should handle state with prefix', (): void => { + const state: string = 'myState_request_2'; + const expectedKey: string = `${PKCEConstants.Storage.StorageKeys.CODE_VERIFIER}${PKCEConstants.Storage.StorageKeys.SEPARATOR}2`; + + expect(extractPkceStorageKeyFromState(state)).toBe(expectedKey); + }); + + it('should extract index from complex state string', (): void => { + const state: string = 'custom_state_with_request_3'; + const expectedKey: string = `${PKCEConstants.Storage.StorageKeys.CODE_VERIFIER}${PKCEConstants.Storage.StorageKeys.SEPARATOR}3`; + + expect(extractPkceStorageKeyFromState(state)).toBe(expectedKey); + }); +}); diff --git a/packages/javascript/src/utils/__tests__/extractTenantDomainFromIdTokenPayload.test.ts b/packages/javascript/src/utils/__tests__/extractTenantDomainFromIdTokenPayload.test.ts new file mode 100644 index 000000000..ce0096da1 --- /dev/null +++ b/packages/javascript/src/utils/__tests__/extractTenantDomainFromIdTokenPayload.test.ts @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {describe, expect, it} from 'vitest'; +import extractTenantDomainFromIdTokenPayload from '../extractTenantDomainFromIdTokenPayload'; +import {IdTokenPayload} from '../../models/id-token'; + +describe('extractTenantDomainFromIdTokenPayload', (): void => { + it('should extract tenant domain from sub claim with default separator', (): void => { + const payload: IdTokenPayload = { + sub: 'user@foo@tenant.com', + }; + + expect(extractTenantDomainFromIdTokenPayload(payload)).toBe('tenant.com'); + }); + + it('should extract tenant domain with custom separator', (): void => { + const payload: IdTokenPayload = { + sub: 'user#foo#custom-tenant', + }; + + expect(extractTenantDomainFromIdTokenPayload(payload, '#')).toBe('custom-tenant'); + }); + + it('should return empty string when sub claim is missing', (): void => { + const payload = {} as IdTokenPayload; + + expect(extractTenantDomainFromIdTokenPayload(payload)).toBe(''); + }); + + it('should return empty string when sub claim has insufficient parts', (): void => { + const payload: IdTokenPayload = { + sub: 'user@tenant', + }; + + expect(extractTenantDomainFromIdTokenPayload(payload)).toBe(''); + }); +}); diff --git a/packages/javascript/src/utils/__tests__/extractUserClaimsFromIdToken.test.ts b/packages/javascript/src/utils/__tests__/extractUserClaimsFromIdToken.test.ts new file mode 100644 index 000000000..ac60be223 --- /dev/null +++ b/packages/javascript/src/utils/__tests__/extractUserClaimsFromIdToken.test.ts @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {describe, expect, it} from 'vitest'; +import extractUserClaimsFromIdToken from '../extractUserClaimsFromIdToken'; +import {IdTokenPayload} from '../../models/id-token'; + +describe('extractUserClaimsFromIdToken', (): void => { + it('should remove protocol claims and keep user claims', (): void => { + const payload: IdTokenPayload = { + iss: 'https://example.com', + aud: 'client_id', + exp: 1712345678, + iat: 1712345670, + email: 'user@example.com', + given_name: 'John', + family_name: 'Doe', + }; + + const expected: { + email: string; + givenName: string; + familyName: string; + } = { + email: 'user@example.com', + givenName: 'John', + familyName: 'Doe', + }; + + expect(extractUserClaimsFromIdToken(payload)).toEqual(expected); + }); + + it('should handle empty payload', (): void => { + const payload = {} as IdTokenPayload; + + expect(extractUserClaimsFromIdToken(payload)).toEqual({}); + }); + + it('should convert snake_case to camelCase', (): void => { + const payload: IdTokenPayload = { + phone_number: '+1234567890', + custom_claim_value: 'test', + normalClaim: 'value', + } as IdTokenPayload; + + const expected: { + phoneNumber: string; + customClaimValue: string; + normalClaim: string; + } = { + phoneNumber: '+1234567890', + customClaimValue: 'test', + normalClaim: 'value', + }; + + expect(extractUserClaimsFromIdToken(payload)).toEqual(expected); + }); + + it('should remove all protocol claims', (): void => { + const payload: IdTokenPayload = { + iss: 'https://example.com', + aud: 'client_id', + exp: 1712345678, + iat: 1712345670, + acr: '1', + amr: ['pwd'], + azp: 'client_1', + auth_time: 1712345670, + nonce: 'abc123', + c_hash: 'hash1', + at_hash: 'hash2', + nbf: 1712345670, + isk: 'key1', + sid: 'session1', + custom_claim: 'value', + } as IdTokenPayload; + + expect(extractUserClaimsFromIdToken(payload)).toEqual({ + customClaim: 'value', + }); + }); +}); diff --git a/packages/javascript/src/utils/__tests__/generatePkceStorageKey.test.ts b/packages/javascript/src/utils/__tests__/generatePkceStorageKey.test.ts new file mode 100644 index 000000000..f32d7acb6 --- /dev/null +++ b/packages/javascript/src/utils/__tests__/generatePkceStorageKey.test.ts @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import PKCEConstants from '../../constants/PKCEConstants'; +import {TemporaryStore} from '../../models/store'; +import generatePkceStorageKey from '../generatePkceStorageKey'; + +describe('generatePkceStorageKey', (): void => { + it('should generate PKCE key with index 0 for empty temporary data', (): void => { + const tempData: TemporaryStore = {}; + const expectedKey: string = `${PKCEConstants.Storage.StorageKeys.CODE_VERIFIER}${PKCEConstants.Storage.StorageKeys.SEPARATOR}0`; + + expect(generatePkceStorageKey(tempData)).toBe(expectedKey); + }); + + it('should generate PKCE key with incremented index for existing PKCE keys', (): void => { + const tempData: TemporaryStore = { + [`${PKCEConstants.Storage.StorageKeys.CODE_VERIFIER}${PKCEConstants.Storage.StorageKeys.SEPARATOR}1`]: 'value1', + [`${PKCEConstants.Storage.StorageKeys.CODE_VERIFIER}${PKCEConstants.Storage.StorageKeys.SEPARATOR}2`]: 'value2', + }; + const expectedKey: string = `${PKCEConstants.Storage.StorageKeys.CODE_VERIFIER}${PKCEConstants.Storage.StorageKeys.SEPARATOR}3`; + + expect(generatePkceStorageKey(tempData)).toBe(expectedKey); + }); + + it('should handle non-sequential PKCE keys', (): void => { + const tempData: TemporaryStore = { + [`${PKCEConstants.Storage.StorageKeys.CODE_VERIFIER}${PKCEConstants.Storage.StorageKeys.SEPARATOR}1`]: 'value1', + [`${PKCEConstants.Storage.StorageKeys.CODE_VERIFIER}${PKCEConstants.Storage.StorageKeys.SEPARATOR}5`]: 'value5', + }; + const expectedKey: string = `${PKCEConstants.Storage.StorageKeys.CODE_VERIFIER}${PKCEConstants.Storage.StorageKeys.SEPARATOR}6`; + + expect(generatePkceStorageKey(tempData)).toBe(expectedKey); + }); + + it('should ignore non-PKCE keys in temporary data', (): void => { + const tempData: TemporaryStore = { + [`${PKCEConstants.Storage.StorageKeys.CODE_VERIFIER}${PKCEConstants.Storage.StorageKeys.SEPARATOR}1`]: 'value1', + 'other-key': 'other-value', + }; + const expectedKey: string = `${PKCEConstants.Storage.StorageKeys.CODE_VERIFIER}${PKCEConstants.Storage.StorageKeys.SEPARATOR}2`; + + expect(generatePkceStorageKey(tempData)).toBe(expectedKey); + }); +}); diff --git a/packages/javascript/src/utils/__tests__/generateStateParamForRequestCorrelation.test.ts b/packages/javascript/src/utils/__tests__/generateStateParamForRequestCorrelation.test.ts new file mode 100644 index 000000000..46242513a --- /dev/null +++ b/packages/javascript/src/utils/__tests__/generateStateParamForRequestCorrelation.test.ts @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {describe, expect, it} from 'vitest'; +import generateStateParamForRequestCorrelation from '../generateStateParamForRequestCorrelation'; +import PKCEConstants from '../../constants/PKCEConstants'; + +describe('generateStateParamForRequestCorrelation', (): void => { + it('should generate state parameter with custom state', (): void => { + const pkceKey: string = `${PKCEConstants.Storage.StorageKeys.CODE_VERIFIER}${PKCEConstants.Storage.StorageKeys.SEPARATOR}1`; + const customState: string = 'myState'; + + expect(generateStateParamForRequestCorrelation(pkceKey, customState)).toBe('myState_request_1'); + }); + + it('should generate state parameter without custom state', (): void => { + const pkceKey: string = `${PKCEConstants.Storage.StorageKeys.CODE_VERIFIER}${PKCEConstants.Storage.StorageKeys.SEPARATOR}2`; + + expect(generateStateParamForRequestCorrelation(pkceKey)).toBe('request_2'); + }); + + it('should handle different index values', (): void => { + const pkceKey: string = `${PKCEConstants.Storage.StorageKeys.CODE_VERIFIER}${PKCEConstants.Storage.StorageKeys.SEPARATOR}999`; + + expect(generateStateParamForRequestCorrelation(pkceKey)).toBe('request_999'); + }); + + it('should combine custom state with request index correctly', (): void => { + const pkceKey: string = `${PKCEConstants.Storage.StorageKeys.CODE_VERIFIER}${PKCEConstants.Storage.StorageKeys.SEPARATOR}5`; + const customState: string = 'complex_state_123'; + + expect(generateStateParamForRequestCorrelation(pkceKey, customState)).toBe('complex_state_123_request_5'); + }); +}); diff --git a/packages/javascript/src/utils/__tests__/removeTrailingSlash.test.ts b/packages/javascript/src/utils/__tests__/removeTrailingSlash.test.ts new file mode 100644 index 000000000..c5bf1ff90 --- /dev/null +++ b/packages/javascript/src/utils/__tests__/removeTrailingSlash.test.ts @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {describe, expect, it} from 'vitest'; +import removeTrailingSlash from '../removeTrailingSlash'; + +describe('removeTrailingSlash', (): void => { + it('should remove trailing slash from a path', (): void => { + expect(removeTrailingSlash('https://example.com/')).toBe('https://example.com'); + }); + + it('should not modify path without trailing slash', (): void => { + expect(removeTrailingSlash('https://example.com')).toBe('https://example.com'); + }); + + it('should handle root path with just a slash', (): void => { + expect(removeTrailingSlash('/')).toBe(''); + }); + + it('should handle empty string', (): void => { + expect(removeTrailingSlash('')).toBe(''); + }); + + it('should remove only one trailing slash when multiple exist', (): void => { + expect(removeTrailingSlash('https://example.com//')).toBe('https://example.com/'); + }); +}); diff --git a/packages/javascript/src/utils/cryptoUtils.ts b/packages/javascript/src/utils/cryptoUtils.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/javascript/src/utils/extractPkceStorageKeyFromState.ts b/packages/javascript/src/utils/extractPkceStorageKeyFromState.ts new file mode 100644 index 000000000..25a420cd9 --- /dev/null +++ b/packages/javascript/src/utils/extractPkceStorageKeyFromState.ts @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import PKCEConstants from '../constants/PKCEConstants'; + +/** + * Extracts the PKCE key from a state parameter string. + * + * @param state - The state parameter string containing the request index. + * @returns The PKCE key string in the format `pkce_code_verifier_${index}`. + * + * @example + * ```typescript + * const state = "request_1"; + * const pkceKey = extractPkceStorageKeyFromState(state); + * // Returns: "pkce_code_verifier_1" + * ``` + */ +const extractPkceStorageKeyFromState = (state: string): string => { + const index: number = parseInt(state.split('request_')[1]); + + return `${PKCEConstants.Storage.StorageKeys.CODE_VERIFIER}${PKCEConstants.Storage.StorageKeys.SEPARATOR}${index}`; +}; + +export default extractPkceStorageKeyFromState; diff --git a/packages/javascript/src/utils/extractTenantDomainFromIdTokenPayload.ts b/packages/javascript/src/utils/extractTenantDomainFromIdTokenPayload.ts new file mode 100644 index 000000000..e2018d3e5 --- /dev/null +++ b/packages/javascript/src/utils/extractTenantDomainFromIdTokenPayload.ts @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {IdTokenPayload} from '../models/id-token'; + +/** + * Extracts the tenant domain from the ID token payload. + * + * @deprecated since v1.0.6 — This utility assumes a legacy tenant extraction pattern from the `sub` claim, + * which may not be reliable. Will be removed in a future version. + * + * @param payload - The ID token payload containing the `sub` claim. + * @param subjectSeparator - The separator used in the `sub` claim to split the user identifier and tenant domain. + * + * Consider extracting the tenant domain using a dedicated claim (e.g., `tenant_domain`) when available. + */ +const extractTenantDomainFromIdTokenPayload = (payload: IdTokenPayload, subjectSeparator: string = '@'): string => { + const uid: string = payload.sub; + + if (!uid) return ''; + + const tokens: string[] = uid.split(subjectSeparator); + + // This pattern assumes a format like: `@@` + return tokens.length > 2 ? tokens[tokens.length - 1] : ''; +}; + +export default extractTenantDomainFromIdTokenPayload; diff --git a/packages/javascript/src/utils/extractUserClaimsFromIdToken.ts b/packages/javascript/src/utils/extractUserClaimsFromIdToken.ts new file mode 100644 index 000000000..998941b93 --- /dev/null +++ b/packages/javascript/src/utils/extractUserClaimsFromIdToken.ts @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {IdTokenPayload} from '../models/id-token'; + +/** + * Removes standard protocol-specific claims from the ID token payload + * and returns a camelCased object of user-specific claims. + * + * @param payload The raw ID token payload. + * @returns A cleaned-up, camelCased object containing only user-specific claims. + * + * @example + * ````typescript + * const idTokenPayload = { + * iss: 'https://example.com', + * aud: 'client_id', + * exp: 1712345678, + * iat: 1712345670, + * email: 'user@example.com' + * }; + * + * const userClaims = extractUserClaimsFromIdToken(idTokenPayload); + * // // userClaims will be: + * // { + * // email: 'user@example.com' + * // } + * ``` + */ +const extractUserClaimsFromIdToken = (payload: IdTokenPayload): Record => { + const filteredPayload: Partial = {...payload}; + + const protocolClaims = [ + 'iss', + 'aud', + 'exp', + 'iat', + 'acr', + 'amr', + 'azp', + 'auth_time', + 'nonce', + 'c_hash', + 'at_hash', + 'nbf', + 'isk', + 'sid', + 'jti', + 'sub', + ]; + + protocolClaims.forEach(claim => { + delete filteredPayload[claim as keyof IdTokenPayload]; + }); + + const userClaims: Record = {}; + + Object.entries(filteredPayload).forEach(([key, value]) => { + const camelCasedKey = key + .split('_') + .map((part, i) => (i === 0 ? part : part[0].toUpperCase() + part.slice(1))) + .join(''); + + userClaims[camelCasedKey] = value; + }); + + return userClaims; +}; + +export default extractUserClaimsFromIdToken; diff --git a/packages/javascript/src/utils/generatePkceStorageKey.ts b/packages/javascript/src/utils/generatePkceStorageKey.ts new file mode 100644 index 000000000..809482b21 --- /dev/null +++ b/packages/javascript/src/utils/generatePkceStorageKey.ts @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import PKCEConstants from '../constants/PKCEConstants'; +import {TemporaryStore} from '../models/store'; + +/** + * Generates the next available PKCE storage key based on the current temporary data. + * + * The generated key will follow the format: `pkce_code_verifier_`, where `` is incremented + * based on the highest existing index in the provided storage object. + * + * @param tempStore - The object that holds temporary PKCE-related data (e.g., sessionStorage). + * + * @returns A new unique PKCE storage key to store the next `code_verifier`. + * + * @example + * const key = generatePkceStorageKey(sessionStorage); + * // Returns: "pkce_code_verifier_3" (if existing keys are pkce_code_verifier_0 to _2) + */ +const generatePkceStorageKey = (tempStore: TemporaryStore): string => { + const keys: string[] = []; + + Object.keys(tempStore).forEach((key: string) => { + if (key.startsWith(PKCEConstants.Storage.StorageKeys.CODE_VERIFIER)) { + keys.push(key); + } + }); + + const lastKey: string | undefined = keys.sort().pop(); + const index: number = parseInt(lastKey?.split(PKCEConstants.Storage.StorageKeys.SEPARATOR)[1] ?? '-1'); + + return `${PKCEConstants.Storage.StorageKeys.CODE_VERIFIER}${PKCEConstants.Storage.StorageKeys.SEPARATOR}${index + 1}`; +}; + +export default generatePkceStorageKey; diff --git a/packages/javascript/src/utils/generateStateParamForRequestCorrelation.ts b/packages/javascript/src/utils/generateStateParamForRequestCorrelation.ts new file mode 100644 index 000000000..eaa024479 --- /dev/null +++ b/packages/javascript/src/utils/generateStateParamForRequestCorrelation.ts @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import PKCEConstants from '../constants/PKCEConstants'; + +/** + * Generates a state parameter for request correlation by combining an optional state string with a request index. + * + * @param pkceKey - The PKCE key containing the index (format: 'pkce_code_verifier_[index]'). + * @param state - Optional state string to prepend to the request correlation. + * @returns A state parameter string in the format '[state_]request_[index]'. + * + * @example + * const pkceKey = "pkce_code_verifier_1"; + * const result = generateStateParamForRequestCorrelation(pkceKey, "myState"); + * // Returns: "myState_request_1" + * + * const resultNoState = generateStateParamForRequestCorrelation(pkceKey); + * // Returns: "request_1" + */ +const generateStateParamForRequestCorrelation = (pkceKey: string, state?: string): string => { + const index: number = parseInt(pkceKey.split(PKCEConstants.Storage.StorageKeys.SEPARATOR)[1]); + + return state ? `${state}_request_${index}` : `request_${index}`; +}; + +export default generateStateParamForRequestCorrelation; diff --git a/packages/javascript/src/utils/removeTrailingSlash.ts b/packages/javascript/src/utils/removeTrailingSlash.ts new file mode 100644 index 000000000..5f30ddcfa --- /dev/null +++ b/packages/javascript/src/utils/removeTrailingSlash.ts @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Removes a trailing slash from a path string if it exists. + * + * @param path - The string path to process + * @returns The path without a trailing slash + * + * @example + * ```typescript + * removeTrailingSlash('/path/to/something/') // returns '/path/to/something' + * removeTrailingSlash('/path/to/something') // returns '/path/to/something' + * ``` + */ +const removeTrailingSlash = (path: string): string => (path.endsWith('/') ? path.slice(0, -1) : path); + +export default removeTrailingSlash; diff --git a/packages/javascript/tsconfig.eslint.json b/packages/javascript/tsconfig.eslint.json new file mode 100644 index 000000000..23fadc266 --- /dev/null +++ b/packages/javascript/tsconfig.eslint.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "include": [ + "**/.*.js", + "**/.*.cjs", + "**/.*.ts", + "**/*.js", + "**/*.cjs", + "**/*.ts", + ] +} diff --git a/packages/javascript/tsconfig.json b/packages/javascript/tsconfig.json new file mode 100644 index 000000000..848c27067 --- /dev/null +++ b/packages/javascript/tsconfig.json @@ -0,0 +1,34 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "declaration": false, + "emitDecoratorMetadata": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "importHelpers": true, + "lib": ["ESNext"], + "module": "ESNext", + "moduleResolution": "node", + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "sourceMap": true, + "target": "ESNext", + "forceConsistentCasingInFileNames": true, + "strict": false, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "exclude": ["node_modules", "tmp", "dist"], + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/packages/javascript/tsconfig.lib.json b/packages/javascript/tsconfig.lib.json new file mode 100644 index 000000000..c05b615f7 --- /dev/null +++ b/packages/javascript/tsconfig.lib.json @@ -0,0 +1,20 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "declaration": true, + "outDir": "dist", + "declarationDir": "dist", + "types": ["node"] + }, + "exclude": [ + "**/*.spec.ts", + "**/*.test.ts", + "**/*.spec.tsx", + "**/*.test.tsx", + "**/*.spec.js", + "**/*.test.js", + "**/*.spec.jsx", + "**/*.test.jsx" + ], + "include": ["src/**/*.js", "src/**/*.ts", "types/**/*.d.ts", "../react/src/getUserProfile.ts"] +} diff --git a/packages/javascript/tsconfig.spec.json b/packages/javascript/tsconfig.spec.json new file mode 100644 index 000000000..3f9daf174 --- /dev/null +++ b/packages/javascript/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "module": "commonjs", + "types": ["vitest/globals"] + }, + "include": [ + "test-configs", + "vitest.config.ts", + "**/*.test.ts", + "**/*.spec.ts", + "**/*.test.js", + "**/*.spec.js", + "**/*.d.ts" + ] +} diff --git a/packages/javascript/vitest.config.ts b/packages/javascript/vitest.config.ts new file mode 100644 index 000000000..dbdd537b3 --- /dev/null +++ b/packages/javascript/vitest.config.ts @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {defineConfig} from 'vitest/config'; + +export default defineConfig({ + test: { + globals: true, + }, +}); diff --git a/packages/nextjs/.editorconfig b/packages/nextjs/.editorconfig new file mode 100644 index 000000000..1b3ce07de --- /dev/null +++ b/packages/nextjs/.editorconfig @@ -0,0 +1 @@ +../../.editorconfig \ No newline at end of file diff --git a/packages/nextjs/.eslintignore b/packages/nextjs/.eslintignore new file mode 100644 index 000000000..177586b6b --- /dev/null +++ b/packages/nextjs/.eslintignore @@ -0,0 +1,4 @@ +/dist +/build +/node_modules +/coverage \ No newline at end of file diff --git a/packages/nextjs/.eslintrc.cjs b/packages/nextjs/.eslintrc.cjs new file mode 100644 index 000000000..a835778cd --- /dev/null +++ b/packages/nextjs/.eslintrc.cjs @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const path = require('path'); + +module.exports = { + env: { + es6: true, + node: true, + }, + extends: [ + 'plugin:@wso2/typescript', + 'plugin:@wso2/next', + 'plugin:@wso2/strict', + 'plugin:@wso2/internal', + 'plugin:@wso2/jest', + 'plugin:@wso2/prettier', + ], + parserOptions: { + ecmaVersion: 2018, + project: [path.resolve(__dirname, 'tsconfig.eslint.json')], + }, + plugins: ['@wso2'], +}; diff --git a/packages/nextjs/.gitignore b/packages/nextjs/.gitignore new file mode 100644 index 000000000..c6bba5913 --- /dev/null +++ b/packages/nextjs/.gitignore @@ -0,0 +1,130 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* diff --git a/packages/nextjs/.prettierignore b/packages/nextjs/.prettierignore new file mode 100644 index 000000000..99b0b518a --- /dev/null +++ b/packages/nextjs/.prettierignore @@ -0,0 +1,4 @@ +/dist +/build +/node_modules +/coverage diff --git a/packages/nextjs/LICENSE b/packages/nextjs/LICENSE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/packages/nextjs/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/nextjs/README.md b/packages/nextjs/README.md new file mode 100644 index 000000000..159e96272 --- /dev/null +++ b/packages/nextjs/README.md @@ -0,0 +1,87 @@ +

+

@asgardeo/nextjs

+

+

Next.js SDK for Asgardeo

+
+ npm (scoped) + npm + License +
+ +## Installation + +```bash +# Using npm +npm install @asgardeo/nextjs + +# or using pnpm +pnpm add @asgardeo/nextjs + +# or using yarn +yarn add @asgardeo/nextjs +``` + +## Quick Start + +1. Create a `.env.local` file with your Asgardeo configuration: + +```bash +NEXT_PUBLIC_ASGARDEO_BASE_URL=https://api.asgardeo.io/t/ +NEXT_PUBLIC_ASGARDEO_CLIENT_ID= +NEXT_PUBLIC_ASGARDEO_CLIENT_SECRET= +``` + +2. Then create a `middleware.ts` file in your project root to handle authentication: + +```typescript +import { AsgardeoNext } from '@asgardeo/nextjs'; +import { NextRequest } from 'next/server'; + +const asgardeo = new AsgardeoNext(); + +asgardeo.initialize({ + baseUrl: process.env.NEXT_PUBLIC_ASGARDEO_BASE_URL, + clientId: process.env.NEXT_PUBLIC_ASGARDEO_CLIENT_ID, + clientSecret: process.env.NEXT_PUBLIC_ASGARDEO_CLIENT_SECRET, + afterSignInUrl: 'http://localhost:3000', +}); + +export async function middleware(request: NextRequest) { + return await asgardeo.middleware(request); +} + +export const config = { + matcher: [ + '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', + '/(api|trpc)(.*)', + ], +}; +``` + +3. Add `SignInButton` and `SignOutButton` buttons to your app + +```tsx +import styles from './page.module.css'; +import {SignInButton, SignedIn, SignOutButton, SignedOut} from '@asgardeo/nextjs'; + +export default function Home() { + return ( +
+
+
+ + Sign In + + + Sign Out + +
+
+
+ ); +} +``` + +## License + +Apache-2.0 diff --git a/packages/nextjs/esbuild.config.mjs b/packages/nextjs/esbuild.config.mjs new file mode 100644 index 000000000..291307624 --- /dev/null +++ b/packages/nextjs/esbuild.config.mjs @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {build} from 'esbuild'; + +const commonOptions = { + bundle: false, + entryPoints: ['src/index.ts'], + platform: 'node', + target: ['node18'], +}; + +await build({ + ...commonOptions, + format: 'esm', + outfile: 'dist/index.js', + sourcemap: true, +}); + +await build({ + ...commonOptions, + format: 'cjs', + outfile: 'dist/cjs/index.js', + sourcemap: true, +}); diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json new file mode 100644 index 000000000..b633568db --- /dev/null +++ b/packages/nextjs/package.json @@ -0,0 +1,70 @@ +{ + "name": "@asgardeo/nextjs", + "version": "0.0.0", + "description": "Next.js implementation of Asgardeo JavaScript SDK.", + "keywords": [ + "asgardeo", + "next.js", + "react", + "ssr" + ], + "homepage": "https://github.com/asgardeo/javascript/tree/main/packages/next#readme", + "bugs": { + "url": "https://github.com/asgardeo/javascript/issues" + }, + "author": "WSO2", + "license": "Apache-2.0", + "type": "module", + "main": "dist/index.js", + "module": "dist/index.js", + "commonjs": "dist/cjs/index.js", + "exports": { + "import": "./dist/index.js", + "require": "./dist/cjs/index.js" + }, + "files": [ + "dist", + "README.md", + "LICENSE" + ], + "types": "dist/index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/asgardeo/javascript", + "directory": "packages/next" + }, + "scripts": { + "build": "pnpm clean && node esbuild.config.mjs && tsc -p tsconfig.lib.json --outDir dist", + "clean": "rimraf dist", + "fix:lint": "eslint . --ext .js,.jsx,.ts,.tsx,.cjs,.mjs", + "lint": "eslint . --ext .js,.jsx,.ts,.tsx,.cjs,.mjs", + "test": "vitest" + }, + "dependencies": { + "@asgardeo/node": "workspace:^", + "@asgardeo/react": "workspace:^", + "@types/react": "^19.1.4", + "tslib": "^2.8.1" + }, + "devDependencies": { + "@types/node": "^22.15.3", + "@wso2/eslint-plugin": "catalog:", + "@wso2/prettier-config": "catalog:", + "esbuild": "^0.25.4", + "esbuild-plugin-preserve-directives": "^0.0.11", + "eslint": "8.57.0", + "next": "^15.3.2", + "prettier": "^2.6.2", + "rimraf": "^6.0.1", + "react": "^19.1.0", + "typescript": "~5.7.2", + "vitest": "^3.1.3" + }, + "peerDependencies": { + "next": ">=13", + "react": ">=16.8.0" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/packages/nextjs/prettier.config.cjs b/packages/nextjs/prettier.config.cjs new file mode 100644 index 000000000..929b9b15f --- /dev/null +++ b/packages/nextjs/prettier.config.cjs @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +module.exports = require('@wso2/prettier-config'); diff --git a/packages/nextjs/src/AsgardeoNextClient.ts b/packages/nextjs/src/AsgardeoNextClient.ts new file mode 100644 index 000000000..491268a2e --- /dev/null +++ b/packages/nextjs/src/AsgardeoNextClient.ts @@ -0,0 +1,199 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + AsgardeoNodeClient, + LegacyAsgardeoNodeClient, + SignInOptions, + SignOutOptions, + User, + // removeTrailingSlash, +} from '@asgardeo/node'; +import {NextRequest, NextResponse} from 'next/server'; +import {AsgardeoNextConfig} from './models/config'; +import deleteSessionId from './server/actions/deleteSessionId'; +import getSessionId from './server/actions/getSessionId'; +import setSessionId from './server/actions/setSessionId'; +import decorateConfigWithNextEnv from './utils/decorateConfigWithNextEnv'; +import InternalAuthAPIRoutesConfig from './configs/InternalAuthAPIRoutesConfig'; + +const removeTrailingSlash = (path: string): string => (path.endsWith('/') ? path.slice(0, -1) : path); +/** + * Client for mplementing Asgardeo in Next.js applications. + * This class provides the core functionality for managing user authentication and sessions. + * + * @typeParam T - Configuration type that extends AsgardeoNextConfig. + */ +class AsgardeoNextClient extends AsgardeoNodeClient { + private asgardeo: LegacyAsgardeoNodeClient; + + constructor() { + super(); + + this.asgardeo = new LegacyAsgardeoNodeClient(); + } + + override initialize(config: T): Promise { + const {baseUrl, clientId, clientSecret, afterSignInUrl} = decorateConfigWithNextEnv({ + afterSignInUrl: config.afterSignInUrl, + baseUrl: config.baseUrl, + clientId: config.clientId, + clientSecret: config.clientSecret, + }); + + return this.asgardeo.initialize({ + baseUrl, + clientID: clientId, + clientSecret, + signInRedirectURL: afterSignInUrl, + } as any); + } + + override getUser(): Promise { + throw new Error('Method not implemented.'); + } + + override isLoading(): boolean { + return false; + } + + override isSignedIn(sessionId?: string): Promise { + return this.asgardeo.isAuthenticated(sessionId as string); + } + + override async signIn( + options?: SignInOptions, + sessionId?: string, + beforeSignIn?: (redirectUrl: string) => NextResponse, + authorizationCode?: string, + sessionState?: string, + state?: string, + ): Promise { + let resolvedSessionId: string = sessionId || ((await getSessionId()) as string); + + if (!resolvedSessionId) { + resolvedSessionId = await setSessionId(sessionId); + } + + return this.asgardeo.signIn( + beforeSignIn as any, + resolvedSessionId, + authorizationCode, + sessionState, + state, + ) as unknown as User; + } + + override signOut(options?: SignOutOptions, afterSignOut?: (redirectUrl: string) => void): Promise; + override signOut( + options?: SignOutOptions, + sessionId?: string, + afterSignOut?: (redirectUrl: string) => void, + ): Promise; + override async signOut(...args: any[]): Promise { + if (args[1] && typeof args[1] !== 'string') { + throw new Error('The second argument must be a string.'); + } + + const resolvedSessionId: string = args[1] || ((await getSessionId()) as string); + + return Promise.resolve(await this.asgardeo.signOut(resolvedSessionId)); + } + + async handler(req: NextRequest): Promise { + const {pathname, searchParams} = req.nextUrl; + const sanitizedPathname: string = removeTrailingSlash(pathname); + const {method} = req; + + if ((method === 'GET' && sanitizedPathname === InternalAuthAPIRoutesConfig.signIn) || searchParams.get('code')) { + let response: NextResponse | undefined; + + await this.signIn( + {}, + undefined, + (redirectUrl: string) => { + return response = NextResponse.redirect(redirectUrl, 302); + }, + searchParams.get('code') as string, + searchParams.get('session_state')as string, + searchParams.get('state')as string, + ); + + // If we already redirected via the callback, return that + if (response) { + return response; + } + + if (searchParams.get('code')) { + const cleanUrl: URL = new URL(req.url); + cleanUrl.searchParams.delete('code'); + cleanUrl.searchParams.delete('state'); + cleanUrl.searchParams.delete('session_state'); + + return NextResponse.redirect(cleanUrl.toString()); + } + + return NextResponse.next(); + } + + if (method === 'GET' && sanitizedPathname === InternalAuthAPIRoutesConfig.session) { + try { + const isAuthenticated: boolean = await this.isSignedIn(); + + return NextResponse.json({isSignedIn: isAuthenticated}); + } catch (error) { + return NextResponse.json({error: 'Failed to check session'}, {status: 500}); + } + } + + if (method === 'GET' && sanitizedPathname === InternalAuthAPIRoutesConfig.signOut) { + try { + const afterSignOutUrl: string = await this.signOut(); + + await deleteSessionId(); + + return NextResponse.redirect(afterSignOutUrl, 302); + } catch (error) { + console.error('[AsgardeoNextClient] Sign-out failed:', error); + return NextResponse.json({error: 'Failed to sign out'}, {status: 500}); + } + } + + // no auth handler found, simply touch the sessions + // TODO: this should only happen if rolling sessions are enabled. Also, we should + // try to avoid reading from the DB (for stateful sessions) on every request if possible. + // const res = NextResponse.next(); + // const session = await this.sessionStore.get(req.cookies); + + // if (session) { + // // we pass the existing session (containing an `createdAt` timestamp) to the set method + // // which will update the cookie's `maxAge` property based on the `createdAt` time + // await this.sessionStore.set(req.cookies, res.cookies, { + // ...session, + // }); + // } + + return NextResponse.next(); + } + + middleware(req: NextRequest): Promise { + return this.handler(req); + } +} + +export default AsgardeoNextClient; diff --git a/packages/nextjs/src/__tests__/greet.test.ts b/packages/nextjs/src/__tests__/greet.test.ts new file mode 100644 index 000000000..c3ad90eef --- /dev/null +++ b/packages/nextjs/src/__tests__/greet.test.ts @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {describe, expect, it} from 'vitest'; +import greet from '../greet'; + +describe('greet', () => { + it('should return the proper greeting', () => { + expect(greet('World')).toBe('Hello, World!'); + }); +}); diff --git a/packages/nextjs/src/client/components/actions/SignInButton.tsx b/packages/nextjs/src/client/components/actions/SignInButton.tsx new file mode 100644 index 000000000..8dbec9340 --- /dev/null +++ b/packages/nextjs/src/client/components/actions/SignInButton.tsx @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +'use client'; + +import {FC, forwardRef, HTMLAttributes, PropsWithChildren, ReactElement, Ref} from 'react'; +import InternalAuthAPIRoutesConfig from '../../../configs/InternalAuthAPIRoutesConfig'; +import {BaseSignInButton} from '@asgardeo/react'; + +/** + * Props interface of {@link SignInButton} + */ +export type SignInButtonProps = HTMLAttributes; + +/** + * SignInButton component. This button initiates the sign-in process when clicked. + * + * @example + * ```tsx + * import { SignInButton } from '@asgardeo/auth-react'; + * + * const App = () => { + * const buttonRef = useRef(null); + * return ( + * + * Sign In + * + * ); + * } + * ``` + */ +const SignInButton: FC> = forwardRef< + HTMLButtonElement, + PropsWithChildren +>( + ( + {children = 'Sign In', className, style, ...rest}: PropsWithChildren, + ref: Ref, + ): ReactElement => ( +
+ + {children} + +
+ ), +); + +export default SignInButton; diff --git a/packages/nextjs/src/client/components/actions/SignOutButton.tsx b/packages/nextjs/src/client/components/actions/SignOutButton.tsx new file mode 100644 index 000000000..e234971bb --- /dev/null +++ b/packages/nextjs/src/client/components/actions/SignOutButton.tsx @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +'use client'; + +import {FC, forwardRef, HTMLAttributes, PropsWithChildren, ReactElement, Ref} from 'react'; +import InternalAuthAPIRoutesConfig from '../../../configs/InternalAuthAPIRoutesConfig'; +import {BaseSignOutButton} from '@asgardeo/react'; + +/** + * Interface for SignInButton component props. + */ +export type SignOutButtonProps = HTMLAttributes; + +/** + * SignInButton component. This button initiates the sign-in process when clicked. + * + * @example + * ```tsx + * import { SignInButton } from '@asgardeo/auth-react'; + * + * const App = () => { + * const buttonRef = useRef(null); + * return ( + * + * Sign In + * + * ); + * } + * ``` + */ +const SignOutButton: FC> = forwardRef< + HTMLButtonElement, + PropsWithChildren +>( + ( + {children = 'Sign Out', className, style, ...rest}: PropsWithChildren, + ref: Ref, + ): ReactElement => ( +
+ + {children} + +
+ ), +); + +export default SignOutButton; diff --git a/packages/nextjs/src/client/components/actions/SignUpButton.tsx b/packages/nextjs/src/client/components/actions/SignUpButton.tsx new file mode 100644 index 000000000..d14d26a9d --- /dev/null +++ b/packages/nextjs/src/client/components/actions/SignUpButton.tsx @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +'use client'; + +import {FC, forwardRef, HTMLAttributes, PropsWithChildren, ReactElement, Ref} from 'react'; +import InternalAuthAPIRoutesConfig from '../../../configs/InternalAuthAPIRoutesConfig'; +import {BaseSignUpButton} from '@asgardeo/react'; + +/** + * Interface for SignInButton component props. + */ +export type SignUpButtonProps = HTMLAttributes; + +/** + * SignInButton component. This button initiates the sign-in process when clicked. + * + * @example + * ```tsx + * import { SignInButton } from '@asgardeo/auth-react'; + * + * const App = () => { + * const buttonRef = useRef(null); + * return ( + * + * Sign In + * + * ); + * } + * ``` + */ +const SignUpButton: FC> = forwardRef< + HTMLButtonElement, + PropsWithChildren +>( + ( + {children = 'Sign Up', className, style, ...rest}: PropsWithChildren, + ref: Ref, + ): ReactElement => ( +
+ + {children} + +
+ ), +); + +export default SignUpButton; diff --git a/packages/nextjs/src/client/components/control/SignedIn.tsx b/packages/nextjs/src/client/components/control/SignedIn.tsx new file mode 100644 index 000000000..1c3db7870 --- /dev/null +++ b/packages/nextjs/src/client/components/control/SignedIn.tsx @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +'use client'; + +import {FC, PropsWithChildren, ReactNode, useEffect, useState} from 'react'; +import isSignedIn from '../../../server/actions/isSignedIn'; + +/** + * Props interface of {@link SignedIn} + */ +export interface SignedInProps { + /** + * Content to show when the user is not signed in. + */ + fallback?: ReactNode; +} + +/** + * A component that only renders its children when the user is signed in. + * + * @example + * ```tsx + * import { SignedIn } from '@asgardeo/auth-next'; + * + * const App = () => { + * return ( + * Please sign in to continue

}> + *

Welcome! You are signed in.

+ *
+ * ); + * } + * ``` + */ +const SignedIn: FC> = ({ + children, + fallback = null, +}: PropsWithChildren) => { + const [isSignedInSync, setIsSignedInSync] = useState(null); + + useEffect(() => { + (async (): Promise => { + try { + const result: boolean = await isSignedIn(); + + setIsSignedInSync(result); + } catch (error) { + setIsSignedInSync(false); + } + })(); + }, []); + + if (isSignedInSync === null) return null; + + return <>{isSignedInSync ? children : fallback}; +}; + +export default SignedIn; diff --git a/packages/nextjs/src/client/components/control/SignedOut.tsx b/packages/nextjs/src/client/components/control/SignedOut.tsx new file mode 100644 index 000000000..b83b75926 --- /dev/null +++ b/packages/nextjs/src/client/components/control/SignedOut.tsx @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +'use client'; + +import {FC, PropsWithChildren, ReactNode, useEffect, useState} from 'react'; +import isSignedIn from '../../../server/actions/isSignedIn'; + +/** + * Props interface of {@link SignedOut} + */ +export interface SignedOutProps { + /** + * Content to show when the user is not signed-out. + */ + fallback?: ReactNode; +} + +/** + * A component that only renders its children when the user is signed out. + * + * @example + * ```tsx + * import { SignedOut } from '@asgardeo/auth-next'; + * + * const App = () => { + * return ( + * Please sign out to continue

}> + *

Welcome! You are signed out.

+ *
+ * ); + * } + * ``` + */ +const SignedOut: FC> = ({ + children, + fallback = null, +}: PropsWithChildren) => { + const [isSignedInSync, setIsSignedInSync] = useState(null); + + useEffect(() => { + (async (): Promise => { + try { + const result: boolean = await isSignedIn(); + + setIsSignedInSync(result); + } catch (error) { + setIsSignedInSync(false); + } + })(); + }, []); + + if (isSignedInSync === null) return null; + + return <>{!isSignedInSync ? children : fallback}; +}; + +export default SignedOut; diff --git a/packages/nextjs/src/client/contexts/AsgardeoContext.ts b/packages/nextjs/src/client/contexts/AsgardeoContext.ts new file mode 100644 index 000000000..d4c27b6c2 --- /dev/null +++ b/packages/nextjs/src/client/contexts/AsgardeoContext.ts @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +'use client'; + +import {AsgardeoContextProps as AsgardeoReactContextProps} from '@asgardeo/react'; +import {Context, createContext} from 'react'; + +/** + * Props interface of {@link AsgardeoContext} + */ +export type AsgardeoContextProps = Partial; + +/** + * Context object for managing the Authentication flow builder core context. + */ +const AsgardeoContext: Context = createContext({}); + +AsgardeoContext.displayName = 'AsgardeoContext'; + +export default AsgardeoContext; diff --git a/packages/nextjs/src/client/hooks/useAsgardeo.ts b/packages/nextjs/src/client/hooks/useAsgardeo.ts new file mode 100644 index 000000000..b21b1e6a6 --- /dev/null +++ b/packages/nextjs/src/client/hooks/useAsgardeo.ts @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +'use client'; + +import {useContext} from 'react'; +import AsgardeoContext, {AsgardeoContextProps} from '../contexts/AsgardeoContext'; + +const useAsgardeo = (): AsgardeoContextProps => { + const context: AsgardeoContextProps | null = useContext(AsgardeoContext); + + if (!context) { + throw new Error('useAsgardeo must be used within an AsgardeoProvider'); + } + + return context; +}; + +export default useAsgardeo; diff --git a/packages/nextjs/src/client/providers/AsgardeoProvider.tsx b/packages/nextjs/src/client/providers/AsgardeoProvider.tsx new file mode 100644 index 000000000..f904bbf44 --- /dev/null +++ b/packages/nextjs/src/client/providers/AsgardeoProvider.tsx @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +'use client'; + +import {FC, PropsWithChildren} from 'react'; +import AsgardeoContext from '../contexts/AsgardeoContext'; + +/** + * Props interface of {@link AsgardeoClientProvider} + */ +export type AsgardeoClientProviderProps = {}; + +const AsgardeoClientProvider: FC> = ({ + children, +}: PropsWithChildren) => ( + {children} +); + +export default AsgardeoClientProvider; diff --git a/packages/nextjs/src/configs/InternalAuthAPIRoutesConfig.ts b/packages/nextjs/src/configs/InternalAuthAPIRoutesConfig.ts new file mode 100644 index 000000000..e36514673 --- /dev/null +++ b/packages/nextjs/src/configs/InternalAuthAPIRoutesConfig.ts @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {InternalAuthAPIRoutes} from '../models/api'; + +const InternalAuthAPIRoutesConfig: InternalAuthAPIRoutes = { + session: '/api/auth/session', + signIn: '/api/auth/signin', + signOut: '/api/auth/signout', + signUp: undefined +}; + +export default InternalAuthAPIRoutesConfig; diff --git a/packages/nextjs/src/index.ts b/packages/nextjs/src/index.ts new file mode 100644 index 000000000..a31906498 --- /dev/null +++ b/packages/nextjs/src/index.ts @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export {default as AsgardeoProvider} from './server/AsgardeoProvider'; +export * from './server/AsgardeoProvider'; + +export {default as isSignedIn} from './server/actions/isSignedIn'; + +export {default as SignedIn} from './client/components/control/SignedIn'; +export * from './client/components/control/SignedIn'; + +export {default as SignedOut} from './client/components/control/SignedOut'; +export * from './client/components/control/SignedOut'; + +export {default as SignInButton} from './client/components/actions/SignInButton'; +export type {SignInButtonProps} from './client/components/actions/SignInButton'; + +export {default as SignOutButton} from './client/components/actions/SignOutButton'; +export type {SignOutButtonProps} from './client/components/actions/SignOutButton'; + +export {default as AsgardeoContext} from './client/contexts/AsgardeoContext'; +export type {AsgardeoContextProps} from './client/contexts/AsgardeoContext'; + +export {default as AsgardeoNext} from './AsgardeoNextClient'; diff --git a/packages/nextjs/src/models/api.ts b/packages/nextjs/src/models/api.ts new file mode 100644 index 000000000..7242edb3b --- /dev/null +++ b/packages/nextjs/src/models/api.ts @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Interface defining the internal API routes for authentication. + * These routes are used internally by the Asgardeo Next.js SDK for handling authentication flows. + */ +export interface InternalAuthAPIRoutes { + /** + * Route for handling session management. + * This route should return the current signed-in status. + */ + session: string; + + /** + * Route for handling sign-in requests. + * This route should handle the sign-in flow and redirect users to the appropriate authentication endpoint. + */ + signIn: string; + + /** + * Route for handling sign-out requests. + * This route should handle the sign-out flow and clean up any authentication state. + */ + signOut: string; + + /** + * Route for handling sign-up requests. + * This route should handle the sign-up flow and redirect users to the appropriate registration endpoint. + */ + signUp?: string; +} diff --git a/packages/nextjs/src/models/config.ts b/packages/nextjs/src/models/config.ts new file mode 100644 index 000000000..b36602f8b --- /dev/null +++ b/packages/nextjs/src/models/config.ts @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {AsgardeoNodeConfig} from '@asgardeo/node'; + +/** + * Configuration type for the Asgardeo Next.js SDK. + * Extends AsgardeoNodeConfig to provide Next.js-specific authentication configuration. + * + * @remarks + * Configuration options include: + * - Authentication endpoints and parameters + * - Next.js specific redirects and middleware settings + * - Session configuration for Next.js apps + * - Environment variable integration + */ +export type AsgardeoNextConfig = AsgardeoNodeConfig; diff --git a/packages/nextjs/src/server/AsgardeoProvider.tsx b/packages/nextjs/src/server/AsgardeoProvider.tsx new file mode 100644 index 000000000..8ffc15074 --- /dev/null +++ b/packages/nextjs/src/server/AsgardeoProvider.tsx @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {FC, PropsWithChildren, ReactElement} from 'react'; +import AsgardeoClientProvider, {AsgardeoClientProviderProps} from '../client/providers/AsgardeoProvider'; + +/** + * Props interface of {@link AsgardeoServerProvider} + */ +export type AsgardeoServerProviderProps = AsgardeoClientProviderProps; + +/** + * Server-side provider component for Asgardeo authentication. + * Wraps the client-side provider and handles server-side authentication logic. + * + * @param props - Props injected into the component. + * + * @example + * ```tsx + * + * + * + * ``` + * + * @returns AsgardeoServerProvider component. + */ +const AsgardeoServerProvider: FC> = ({ + children, +}: PropsWithChildren): ReactElement => ( + {children} +); + +export default AsgardeoServerProvider; diff --git a/packages/nextjs/src/server/actions/deleteSessionId.ts b/packages/nextjs/src/server/actions/deleteSessionId.ts new file mode 100644 index 000000000..d6e56b82b --- /dev/null +++ b/packages/nextjs/src/server/actions/deleteSessionId.ts @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +'use server'; + +import {CookieConfig} from '@asgardeo/node'; +import {ReadonlyRequestCookies} from 'next/dist/server/web/spec-extension/adapters/request-cookies'; +import {cookies} from 'next/headers'; + +const deleteSessionId = async (): Promise => { + const cookieStore: ReadonlyRequestCookies = await cookies(); + + await cookieStore.delete(CookieConfig.SESSION_COOKIE_NAME); +}; + +export default deleteSessionId; diff --git a/packages/nextjs/src/server/actions/getSessionId.ts b/packages/nextjs/src/server/actions/getSessionId.ts new file mode 100644 index 000000000..3d21dc49f --- /dev/null +++ b/packages/nextjs/src/server/actions/getSessionId.ts @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +'use server'; + +import {CookieConfig} from '@asgardeo/node'; +import {ReadonlyRequestCookies} from 'next/dist/server/web/spec-extension/adapters/request-cookies'; +import {cookies} from 'next/headers'; + +const getSessionId = async (): Promise => { + const cookieStore: ReadonlyRequestCookies = await cookies(); + + return cookieStore.get(CookieConfig.SESSION_COOKIE_NAME)?.value; +}; + +export default getSessionId; diff --git a/packages/nextjs/src/server/actions/isSignedIn.ts b/packages/nextjs/src/server/actions/isSignedIn.ts new file mode 100644 index 000000000..46f5a153a --- /dev/null +++ b/packages/nextjs/src/server/actions/isSignedIn.ts @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +'use server'; + +import {CookieConfig} from '@asgardeo/node'; +import {ReadonlyRequestCookies} from 'next/dist/server/web/spec-extension/adapters/request-cookies'; +import {cookies} from 'next/headers'; + +const isSignedIn = async (): Promise => { + const cookieStore: ReadonlyRequestCookies = await cookies(); + + return !!cookieStore.get(CookieConfig.SESSION_COOKIE_NAME)?.value; +}; + +export default isSignedIn; diff --git a/packages/nextjs/src/server/actions/setSessionId.ts b/packages/nextjs/src/server/actions/setSessionId.ts new file mode 100644 index 000000000..5d21cefdd --- /dev/null +++ b/packages/nextjs/src/server/actions/setSessionId.ts @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +'use server'; + +import {CookieConfig, generateSessionId} from '@asgardeo/node'; +import {RequestCookie} from 'next/dist/compiled/@edge-runtime/cookies'; +import {ReadonlyRequestCookies} from 'next/dist/server/web/spec-extension/adapters/request-cookies'; +import {cookies} from 'next/headers'; + +const setSessionId = async (sessionId?: string): Promise => { + const cookieStore: ReadonlyRequestCookies = await cookies(); + + const sessionCookie: RequestCookie | undefined = cookieStore.get(CookieConfig.SESSION_COOKIE_NAME); + let sessionCookieValue: string | undefined = sessionId; + + if (!sessionCookieValue && sessionCookie) { + sessionCookieValue = sessionCookie.value; + } else if (sessionCookie) { + sessionCookieValue = sessionCookie.value; + } else { + sessionCookieValue = generateSessionId(); + } + + cookieStore.set(CookieConfig.SESSION_COOKIE_NAME, sessionCookieValue as string, { + httpOnly: CookieConfig?.DEFAULT_HTTP_ONLY, + maxAge: CookieConfig?.DEFAULT_MAX_AGE, + sameSite: CookieConfig?.DEFAULT_SAME_SITE, + secure: CookieConfig?.DEFAULT_SECURE, + }); + + return Promise.resolve(sessionCookieValue); +}; + +export default setSessionId; diff --git a/packages/nextjs/src/utils/decorateConfigWithNextEnv.ts b/packages/nextjs/src/utils/decorateConfigWithNextEnv.ts new file mode 100644 index 000000000..1eeff1532 --- /dev/null +++ b/packages/nextjs/src/utils/decorateConfigWithNextEnv.ts @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {AsgardeoNextConfig} from '../models/config'; + +const decorateConfigWithNextEnv = (config: AsgardeoNextConfig): AsgardeoNextConfig => { + const {baseUrl, clientId, clientSecret, ...rest} = config; + + return { + ...rest, + baseUrl: baseUrl || (process.env['NEXT_PUBLIC_ASGARDEO_BASE_URL'] as string), + clientId: clientId || (process.env['NEXT_PUBLIC_ASGARDEO_CLIENT_ID'] as string), + clientSecret: clientSecret || (process.env['ASGARDEO_CLIENT_SECRET'] as string), + }; +}; + +export default decorateConfigWithNextEnv; diff --git a/packages/nextjs/tsconfig.eslint.json b/packages/nextjs/tsconfig.eslint.json new file mode 100644 index 000000000..23fadc266 --- /dev/null +++ b/packages/nextjs/tsconfig.eslint.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "include": [ + "**/.*.js", + "**/.*.cjs", + "**/.*.ts", + "**/*.js", + "**/*.cjs", + "**/*.ts", + ] +} diff --git a/packages/nextjs/tsconfig.json b/packages/nextjs/tsconfig.json new file mode 100644 index 000000000..65129c482 --- /dev/null +++ b/packages/nextjs/tsconfig.json @@ -0,0 +1,35 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "declaration": false, + "emitDecoratorMetadata": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "importHelpers": true, + "jsx": "react-jsx", + "lib": ["DOM", "ESNext"], + "module": "ESNext", + "moduleResolution": "node", + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "sourceMap": true, + "target": "ESNext", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "exclude": ["node_modules", "tmp", "dist"], + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/packages/nextjs/tsconfig.lib.json b/packages/nextjs/tsconfig.lib.json new file mode 100644 index 000000000..8d37e00df --- /dev/null +++ b/packages/nextjs/tsconfig.lib.json @@ -0,0 +1,20 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "declaration": true, + "outDir": "dist", + "declarationDir": "dist", + "types": ["node"] + }, + "exclude": [ + "**/*.spec.ts", + "**/*.test.ts", + "**/*.spec.tsx", + "**/*.test.tsx", + "**/*.spec.js", + "**/*.test.js", + "**/*.spec.jsx", + "**/*.test.jsx" + ], + "include": ["src/**/*.js", "src/**/*.ts", "src/**/*.jsx", "src/**/*.tsx", "types/**/*.d.ts"] +} diff --git a/packages/nextjs/tsconfig.spec.json b/packages/nextjs/tsconfig.spec.json new file mode 100644 index 000000000..46a76e285 --- /dev/null +++ b/packages/nextjs/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "test-configs", + "jest.config.js", + "**/*.test.ts", + "**/*.spec.ts", + "**/*.test.js", + "**/*.spec.js", + "**/*.d.ts" + ] +} diff --git a/packages/nextjs/vitest.config.ts b/packages/nextjs/vitest.config.ts new file mode 100644 index 000000000..29a917d10 --- /dev/null +++ b/packages/nextjs/vitest.config.ts @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {defineConfig} from 'vitest/config'; + +export default defineConfig({ + test: {}, +}); diff --git a/packages/node/.editorconfig b/packages/node/.editorconfig new file mode 100644 index 000000000..1b3ce07de --- /dev/null +++ b/packages/node/.editorconfig @@ -0,0 +1 @@ +../../.editorconfig \ No newline at end of file diff --git a/packages/node/.eslintignore b/packages/node/.eslintignore new file mode 100644 index 000000000..177586b6b --- /dev/null +++ b/packages/node/.eslintignore @@ -0,0 +1,4 @@ +/dist +/build +/node_modules +/coverage \ No newline at end of file diff --git a/packages/node/.eslintrc.cjs b/packages/node/.eslintrc.cjs new file mode 100644 index 000000000..2676ca816 --- /dev/null +++ b/packages/node/.eslintrc.cjs @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const path = require('path'); + +module.exports = { + env: { + es6: true, + node: true, + }, + extends: [ + 'plugin:@wso2/typescript', + 'plugin:@wso2/strict', + 'plugin:@wso2/internal', + 'plugin:@wso2/jest', + 'plugin:@wso2/prettier', + ], + parserOptions: { + ecmaVersion: 2018, + project: [path.resolve(__dirname, 'tsconfig.eslint.json')], + }, + plugins: ['@wso2'], +}; diff --git a/packages/node/.gitignore b/packages/node/.gitignore new file mode 100644 index 000000000..c6bba5913 --- /dev/null +++ b/packages/node/.gitignore @@ -0,0 +1,130 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* diff --git a/packages/node/.prettierignore b/packages/node/.prettierignore new file mode 100644 index 000000000..99b0b518a --- /dev/null +++ b/packages/node/.prettierignore @@ -0,0 +1,4 @@ +/dist +/build +/node_modules +/coverage diff --git a/packages/node/README.md b/packages/node/README.md new file mode 100644 index 000000000..500d505e9 --- /dev/null +++ b/packages/node/README.md @@ -0,0 +1,72 @@ +

+

@asgardeo/node

+

+

Node.js SDK for Asgardeo

+
+ npm (scoped) + npm + License +
+ +## Installation + +```bash +# Using npm +npm install @asgardeo/node + +# or using pnpm +pnpm add @asgardeo/node + +# or using yarn +yarn add @asgardeo/node +``` + +## Quick Start + +```javascript +import { AsgardeoNodeClient } from "@asgardeo/node"; + +// Initialize the client +const authClient = new AsgardeoNodeClient({ + clientID: "", + clientSecret: "", + baseUrl: "https://api.asgardeo.io/t/", + callbackURL: "http://localhost:3000/callback" +}); + +// Example Express.js integration +import express from "express"; +const app = express(); + +// Login endpoint +app.get("/login", (req, res) => { + const authUrl = authClient.getAuthorizationURL(); + res.redirect(authUrl); +}); + +// Callback handler +app.get("/callback", async (req, res) => { + try { + const { code } = req.query; + const tokens = await authClient.exchangeAuthorizationCode(code); + // Store tokens and redirect to home page + res.redirect("/"); + } catch (error) { + res.status(500).send("Authentication failed"); + } +}); + +// Get user info +app.get("/userinfo", async (req, res) => { + try { + const userInfo = await authClient.getUserInfo(); + res.json(userInfo); + } catch (error) { + res.status(401).send("Unauthorized"); + } +}); +``` + +## License + +Apache-2.0 diff --git a/packages/node/esbuild.config.mjs b/packages/node/esbuild.config.mjs new file mode 100644 index 000000000..75bd11607 --- /dev/null +++ b/packages/node/esbuild.config.mjs @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {readFileSync} from 'fs'; +import * as esbuild from 'esbuild'; + +const pkg = JSON.parse(readFileSync('./package.json', 'utf8')); + +const commonOptions = { + bundle: true, + entryPoints: ['src/index.ts'], + external: [...Object.keys(pkg.dependencies || {}), ...Object.keys(pkg.peerDependencies || {})], + platform: 'node', + target: ['es2020'], +}; + +await esbuild.build({ + ...commonOptions, + format: 'esm', + outfile: 'dist/index.js', + sourcemap: true, +}); + +await esbuild.build({ + ...commonOptions, + format: 'cjs', + outfile: 'dist/cjs/index.js', + sourcemap: true, +}); diff --git a/packages/node/package.json b/packages/node/package.json new file mode 100644 index 000000000..6cda86ed6 --- /dev/null +++ b/packages/node/package.json @@ -0,0 +1,68 @@ +{ + "name": "@asgardeo/node", + "version": "0.0.0", + "description": "Node.js runtime specific implementation of Asgardeo JavaScript SDK.", + "keywords": [ + "asgardeo", + "node.js", + "node", + "server" + ], + "homepage": "https://github.com/asgardeo/javascript/tree/main/packages/node#readme", + "bugs": { + "url": "https://github.com/asgardeo/javascript/issues" + }, + "author": "WSO2", + "license": "Apache-2.0", + "type": "module", + "main": "dist/cjs/index.js", + "module": "dist/index.js", + "exports": { + "import": "./dist/index.js", + "require": "./dist/cjs/index.js" + }, + "files": [ + "dist", + "README.md", + "LICENSE" + ], + "types": "dist/index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/asgardeo/javascript", + "directory": "packages/node" + }, + "scripts": { + "build": "pnpm clean && node esbuild.config.mjs && tsc -p tsconfig.lib.json --emitDeclarationOnly --outDir dist", + "clean": "rimraf dist", + "fix:lint": "eslint . --ext .js,.jsx,.ts,.tsx,.cjs,.mjs", + "lint": "eslint . --ext .js,.jsx,.ts,.tsx,.cjs,.mjs", + "test": "vitest", + "typecheck": "tsc -p tsconfig.lib.json" + }, + "devDependencies": { + "@types/node": "^22.15.3", + "@wso2/eslint-plugin": "catalog:", + "@wso2/prettier-config": "catalog:", + "esbuild": "^0.25.4", + "eslint": "8.57.0", + "prettier": "^2.6.2", + "rimraf": "^6.0.1", + "typescript": "~5.7.2", + "vitest": "^3.1.3" + }, + "dependencies": { + "@asgardeo/javascript": "workspace:^", + "base64url": "^3.0.1", + "cross-fetch": "^4.1.0", + "fast-sha256": "^1.3.0", + "jose": "^6.0.11", + "memory-cache": "^0.2.0", + "secure-random-bytes": "^5.0.1", + "tslib": "^2.8.1", + "uuid": "^11.1.0" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/packages/node/prettier.config.cjs b/packages/node/prettier.config.cjs new file mode 100644 index 000000000..929b9b15f --- /dev/null +++ b/packages/node/prettier.config.cjs @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +module.exports = require('@wso2/prettier-config'); diff --git a/packages/node/src/AsgardeoNodeClient.ts b/packages/node/src/AsgardeoNodeClient.ts new file mode 100644 index 000000000..470eefb34 --- /dev/null +++ b/packages/node/src/AsgardeoNodeClient.ts @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {AsgardeoJavaScriptClient} from '@asgardeo/javascript'; +import {AsgardeoNodeConfig} from './models/config'; +import {SignOutOptions} from '@asgardeo/javascript/dist/models/client'; + +/** + * Base class for implementing Asgardeo in Node.js based applications. + * This class provides the core functionality for managing user authentication and sessions. + * + * @typeParam T - Configuration type that extends AsgardeoNodeConfig. + */ +abstract class AsgardeoNodeClient extends AsgardeoJavaScriptClient {} + +export default AsgardeoNodeClient; diff --git a/packages/node/src/__legacy__/client.ts b/packages/node/src/__legacy__/client.ts new file mode 100644 index 000000000..11733cc7f --- /dev/null +++ b/packages/node/src/__legacy__/client.ts @@ -0,0 +1,417 @@ +/** + * Copyright (c) 2022, WSO2 Inc. (http://www.wso2.com) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + AuthClientConfig, + BasicUserInfo, + CustomGrantConfig, + DataLayer, + IdTokenPayload, + FetchResponse, + OIDCEndpoints, + Store, + TokenResponse, +} from '@asgardeo/javascript'; +import {AsgardeoNodeCore} from './core'; +import {AuthURLCallback} from './models'; + +/** + * This class provides the necessary methods needed to implement authentication. + * + * @export + * @class AsgardeoNodeClient + */ +export class AsgardeoNodeClient { + private _authCore: AsgardeoNodeCore; + + /** + * This is the constructor method that returns an instance of the `AsgardeoNodeClient` class. + * + * @param {AuthClientConfig} config - The configuration object. + * @param {Store} store - The store object. + * + * @example + * ``` + * const _store: Store = new DataStore(); + * const _config = { + signInRedirectURL: "http://localhost:3000/sign-in", + signOutRedirectURL: "http://localhost:3000/dashboard", + clientID: "client ID", + serverOrigin: "https://api.asgardeo.io/t/" + }; + * const auth = new AsgardeoNodeClient(_config,_store); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#constructor + * @preserve + */ + constructor() {} + + public async initialize(config: AuthClientConfig, store?: Store): Promise { + this._authCore = new AsgardeoNodeCore(config, store); + + return Promise.resolve(true); + } + + /** + * This method logs in a user. If the authorization code is not available it will resolve with the + * authorization URL to authorize the user. + * @param {string} authorizationCode - The authorization code obtained from Asgardeo after a user signs in. + * @param {String} sessionState - The session state obtained from Asgardeo after a user signs in. + * @param {string} userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user + * scenarios where each user should be uniquely identified. + * @param {string} state - The state parameter in the redirect URL. + * + * @return {Promise} - A Promise that resolves with the + * [`URLResponse`](#URLResponse) object or a Promise that resolves with + * the [`NodeTokenResponse`](#NodeTokenResponse) object. + * + * @example + * ``` + * authClient.signIn(req.query.code, req.query.session_state).then(response => { + * //URL property will available if the user has not been authenticated already + * if (response.hasOwnProperty('url')) { + * res.redirect(response.url) + * } else { + * //Set the cookie + * res.cookie('ASGARDEO_SESSION_ID', response.session, { maxAge: 900000, httpOnly: true, SameSite: true }); + * res.status(200).send(response) + * } + *}); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#signIn + * + * @memberof AsgardeoNodeClient + * + */ + public async signIn( + authURLCallback: AuthURLCallback, + userId: string, + authorizationCode?: string, + sessionState?: string, + state?: string, + signInConfig?: Record, + ): Promise { + return this._authCore.signIn(authURLCallback, userId, authorizationCode, sessionState, state, signInConfig); + } + + /** + * This method clears all session data and returns the sign-out URL. + * @param {string} userId - The userId of the user. (If you are using ExpressJS, + * you may get this from the request cookies) + * + * @return {Promise} - A Promise that resolves with the sign-out URL. + * + * @example + * ``` + * const signOutUrl = await auth.signOut(userId); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#signOut + * + * @memberof AsgardeoNodeClient + * + */ + public async signOut(userId: string): Promise { + return this._authCore.signOut(userId); + } + + /** + * This method returns a boolean value indicating if the user is authenticated or not. + * @param {string} userId - The userId of the user. + * (If you are using ExpressJS, you may get this from the request cookies) + * + * @return { Promise} -A boolean value that indicates of the user is authenticated or not. + * + * @example + * ``` + * const isAuth = await authClient.isAuthenticated("a2a2972c-51cd-5e9d-a9ae-058fae9f7927"); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#isAuthenticated + * + * @memberof AsgardeoNodeClient + * + */ + public async isAuthenticated(userId: string): Promise { + return this._authCore.isAuthenticated(userId); + } + + /** + * This method returns the id token. + * @param {string} userId - The userId of the user. + * (If you are using ExpressJS, you may get this from the request cookies) + * + * @return {Promise} -A Promise that resolves with the ID Token. + * + * @example + * ``` + * const isAuth = await authClient.getIDToken("a2a2972c-51cd-5e9d-a9ae-058fae9f7927"); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getIDToken + * + * @memberof AsgardeoNodeClient + * + */ + public async getIDToken(userId: string): Promise { + return this._authCore.getIDToken(userId); + } + + /** + * This method returns an object containing basic user information obtained from the id token. + * @param {string} userId - The userId of the user. + * (If you are using ExpressJS, you may get this from the request cookies) + * + * @return {Promise} -A Promise that resolves with the + * An object containing basic user information obtained from the id token. + * + * @example + * ``` + * const basicInfo = await authClient.getBasicUserInfo("a2a2972c-51cd-5e9d-a9ae-058fae9f7927"); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getBasicUserInfo + * + * @memberof AsgardeoNodeClient + * + */ + public async getBasicUserInfo(userId: string): Promise { + return this._authCore.getBasicUserInfo(userId); + } + + /** + * This method returns an object containing the OIDC service endpoints returned by the `.well-known` endpoint. + * @return {Promise} -A Promise that resolves with + * an object containing the OIDC service endpoints returned by the `.well-known` endpoint. + * + * @example + * ``` + * const oidcEndpoints = await auth.getOIDCServiceEndpoints(); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getOIDCServiceEndpoints + * + * @memberof AsgardeoNodeClient + * + */ + public async getOIDCServiceEndpoints(): Promise { + return this._authCore.getOIDCServiceEndpoints(); + } + + /** + * This method returns the decoded ID token payload. + * @param {string} userId - The userId of the user. + * (If you are using ExpressJS, you may get this from the request cookies) + * + * @return {Promise} -A Promise that resolves with + * an object containing the decoded ID token payload. + * + * @example + * ``` + * const decodedIDTokenPayload = await auth.getDecodedIDToken("a2a2972c-51cd-5e9d-a9ae-058fae9f7927"); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getDecodedIDToken + * + * @memberof AsgardeoNodeClient + * + */ + public async getDecodedIDToken(userId?: string): Promise { + return this._authCore.getDecodedIDToken(userId); + } + + /** + * This method returns the access token. + * @param {string} userId - The userId of the user. + * (If you are using ExpressJS, you may get this from the request cookies) + * + * @return {Promise} -A Promise that resolves with + * the access token stored in the store + * + * @example + * ``` + *const accessToken = await auth.getAccessToken("a2a2972c-51cd-5e9d-a9ae-058fae9f7927"); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getAccessToken + * + * @memberof AsgardeoNodeClient + * + */ + public async getAccessToken(userId?: string): Promise { + return this._authCore.getAccessToken(userId); + } + + /** + * This method returns Promise that resolves with the token information + * or the response returned by the server depending on the configuration passed. + * @param {CustomGrantConfig} config - The config object contains attributes that would be used + * to configure the custom grant request. + * + * @param {string} userId - The userId of the user. + * (If you are using ExpressJS, you may get this from the request cookies) + * + * @return {Promise} -A Promise that resolves with the token information + * or the response returned by the server depending on the configuration passed. + * + * @example + * ``` + * const config = { + * attachToken: false, + * data: { + * client_id: "{{clientID}}", + * grant_type: "account_switch", + * scope: "{{scope}}", + * token: "{{token}}", + * }, + * id: "account-switch", + * returnResponse: true, + * returnsSession: true, + * signInRequired: true + * } + + * auth.requestCustomGrant(config).then((response)=>{ + * console.log(response); + * }).catch((error)=>{ + * console.error(error); + * }); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#requestCustomGrant + * + * @memberof AsgardeoNodeClient + * + */ + public async requestCustomGrant(config: CustomGrantConfig, userId?: string): Promise { + return this._authCore.requestCustomGrant(config, userId); + } + + /** + * This method can be used to update the configurations passed into the constructor of the AsgardeoAuthClient. + * @param {AuthClientConfig} config - The config object containing the attributes + * that can be used to configure the SDK + * + * @return {Promise} -A Promise that resolves with a void. + * + * @example + * ``` + * const updateConfig = await auth.updateConfig({ + * signOutRedirectURL: "http://localhost:3000/sign-out" + * }); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#updateConfig + * + * @memberof AsgardeoNodeClient + * + */ + public async updateConfig(config: Partial>): Promise { + return this._authCore.updateConfig(config); + } + + /** + * This method returns a Promise that resolves with the response returned by the server. + * @param {string} userId - The userId of the user. + * (If you are using ExpressJS, you may get this from the request cookies) + * + * @return {Promise} -A Promise that resolves with the response returned by the server. + * + * @example + * ``` + * const revokeToken = await auth.revokeAccessToken("a2a2972c-51cd-5e9d-a9ae-058fae9f7927"); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#revokeAccessToken + * + * @memberof AsgardeoNodeClient + * + */ + public async revokeAccessToken(userId?: string): Promise { + return this._authCore.revokeAccessToken(userId); + } + + /** + * This method refreshes the access token and returns a Promise that resolves with the new access + * token and other relevant data. + * + * @param {string} userId - A unique ID of the user to be authenticated. This is useful in multi-user + * scenarios where each user should be uniquely identified. + * + * @returns {Promise} - A Promise that resolves with the token response. + * + * @example + * ``` + * const tokenResponse = await auth.refreshAccessToken("a2a2972c-51cd-5e9d-a9ae-058fae9f7927") + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#refreshAccessToken + * + * @memberof AsgardeoNodeClient + */ + public refreshAccessToken(userId?: string): Promise { + return this._authCore.refreshAccessToken(userId); + } + + /** + * This method returns if the user has been successfully signed out or not. + * @param {string} signOutRedirectURL - The URL to which the user is redirected to + * after signing out from the server. + * + * @return {boolean} - A boolean value indicating if the user has been signed out or not. + * + * @example + * ``` + * const isSignedOut = auth.isSignOutSuccessful();; + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#isSignOutSuccessful + * + * @memberof AsgardeoNodeClient + * + */ + public static isSignOutSuccessful(signOutRedirectURL: string): boolean { + return AsgardeoNodeClient.isSignOutSuccessful(signOutRedirectURL); + } + + /** + * This method returns if sign-out failed or not + * @param {string} signOutRedirectURL - The URL to which the user is redirected to + * after signing out from the server. + * + * @return {boolean} - A boolean value indicating if sign-out failed or not. + * + * @example + * ``` + * const isSignedOut = auth.isSignOutSuccessful(); + * ``` + * + * @link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#didSignOutFail + * + * @memberof AsgardeoNodeClient + * + */ + public static didSignOutFail(signOutRedirectURL: string): boolean { + return AsgardeoNodeClient.didSignOutFail(signOutRedirectURL); + } + + public async getDataLayer(): Promise> { + return this._authCore.getDataLayer(); + } +} diff --git a/packages/node/src/__legacy__/constants/index.ts b/packages/node/src/__legacy__/constants/index.ts new file mode 100644 index 000000000..4bb03a317 --- /dev/null +++ b/packages/node/src/__legacy__/constants/index.ts @@ -0,0 +1,20 @@ +/** +* Copyright (c) 2022, WSO2 Inc. (http://www.wso2.com) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +export * from "./uuid-config"; +export * from "./logger-config"; diff --git a/packages/node/src/__legacy__/constants/logger-config.ts b/packages/node/src/__legacy__/constants/logger-config.ts new file mode 100644 index 000000000..3c4e1691f --- /dev/null +++ b/packages/node/src/__legacy__/constants/logger-config.ts @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2022, WSO2 Inc. (http://www.wso2.com) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const LOGGER_CONFIG = { + bgGreen: "\x1b[42m", + bgRed: "\x1b[41m", + bgWhite: "\x1b[47m", + bgYellow: "\x1b[43m", + fgBlack: "\x1b[30m", + fgGreen: "\x1b[32m", + fgRed: "\x1b[31m", + fgWhite: "\x1b[37m", + fgYellow: "\x1b[33m", + reset: "\x1b[0m" +} diff --git a/packages/node/src/__legacy__/constants/uuid-config.ts b/packages/node/src/__legacy__/constants/uuid-config.ts new file mode 100644 index 000000000..f807f2558 --- /dev/null +++ b/packages/node/src/__legacy__/constants/uuid-config.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2022, WSO2 Inc. (http://www.wso2.com) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const UUID_VERSION = 4; diff --git a/packages/node/src/__legacy__/core/authentication.ts b/packages/node/src/__legacy__/core/authentication.ts new file mode 100644 index 000000000..fe5cf0e47 --- /dev/null +++ b/packages/node/src/__legacy__/core/authentication.ts @@ -0,0 +1,254 @@ +/** + * Copyright (c) 2022, WSO2 Inc. (http://www.wso2.com) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + AsgardeoAuthClient, + AsgardeoAuthException, + AuthClientConfig, + BasicUserInfo, + Crypto, + CustomGrantConfig, + DataLayer, + IdTokenPayload, + FetchResponse, + OIDCEndpoints, + SessionData, + Store, + TokenResponse, +} from '@asgardeo/javascript'; +import {AuthURLCallback} from '../models'; +import {MemoryCacheStore} from '../stores'; +import {Logger, SessionUtils} from '../utils'; +import {NodeCryptoUtils} from '../utils/crypto-utils'; + +export class AsgardeoNodeCore { + private _auth: AsgardeoAuthClient; + private _cryptoUtils: Crypto; + private _store: Store; + private _dataLayer: DataLayer; + + constructor(config: AuthClientConfig, store?: Store) { + //Initialize the default memory cache store if an external store is not passed. + if (!store) { + this._store = new MemoryCacheStore(); + } else { + this._store = store; + } + this._cryptoUtils = new NodeCryptoUtils(); + this._auth = new AsgardeoAuthClient(); + this._auth.initialize(config, this._store, this._cryptoUtils); + this._dataLayer = this._auth.getDataLayer(); + Logger.debug('Initialized AsgardeoAuthClient successfully'); + } + + public async signIn( + authURLCallback: AuthURLCallback, + userID: string, + authorizationCode?: string, + sessionState?: string, + state?: string, + signInConfig?: Record, + ): Promise { + if (!userID) { + return Promise.reject( + new AsgardeoAuthException( + 'NODE-AUTH_CORE-SI-NF01', + 'No user ID was provided.', + 'Unable to sign in the user as no user ID was provided.', + ), + ); + } + + if (await this.isAuthenticated(userID)) { + const sessionData: SessionData = await this._dataLayer.getSessionData(userID); + + return Promise.resolve({ + accessToken: sessionData.access_token, + createdAt: sessionData.created_at, + expiresIn: sessionData.expires_in, + idToken: sessionData.id_token, + refreshToken: sessionData.refresh_token ?? '', + scope: sessionData.scope, + tokenType: sessionData.token_type, + }); + } + + //Check if the authorization code or session state is there. + //If so, generate the access token, otherwise generate the auth URL and return with callback function. + if (!authorizationCode || !state) { + if (!authURLCallback || typeof authURLCallback !== 'function') { + return Promise.reject( + new AsgardeoAuthException( + 'NODE-AUTH_CORE-SI-NF02', + 'Invalid AuthURLCallback function.', + 'The AuthURLCallback is not defined or is not a function.', + ), + ); + } + const authURL = await this.getAuthURL(userID, signInConfig); + authURLCallback(authURL); + + return Promise.resolve({ + accessToken: '', + createdAt: 0, + expiresIn: '', + idToken: '', + refreshToken: '', + scope: '', + session: '', + tokenType: '', + }); + } + + return this.requestAccessToken(authorizationCode, sessionState ?? '', userID, state); + } + + public async getAuthURL(userId: string, signInConfig?: Record): Promise { + const authURL = await this._auth.getAuthorizationURL(signInConfig, userId); + + if (authURL) { + return Promise.resolve(authURL.toString()); + } else { + return Promise.reject( + new AsgardeoAuthException( + 'NODE-AUTH_CORE-GAU-NF01', + 'Getting Authorization URL failed.', + 'No authorization URL was returned by the Asgardeo Auth JS SDK.', + ), + ); + } + } + + public async requestAccessToken( + authorizationCode: string, + sessionState: string, + userId: string, + state: string, + ): Promise { + return this._auth.requestAccessToken(authorizationCode, sessionState, state, userId); + } + + public async getIDToken(userId: string): Promise { + const is_logged_in = await this.isAuthenticated(userId); + if (!is_logged_in) { + return Promise.reject( + new AsgardeoAuthException( + 'NODE-AUTH_CORE-GIT-NF01', + 'The user is not logged in.', + 'No session ID was found for the requested user. User is not logged in.', + ), + ); + } + const idToken = await this._auth.getIDToken(userId); + if (idToken) { + return Promise.resolve(idToken); + } else { + return Promise.reject( + new AsgardeoAuthException( + 'NODE-AUTH_CORE-GIT-NF02', + 'Requesting ID Token Failed', + 'No ID Token was returned by the Asgardeo Auth JS SDK.', + ), + ); + } + } + + public async refreshAccessToken(userId?: string): Promise { + return this._auth.refreshAccessToken(userId); + } + + public async isAuthenticated(userId: string): Promise { + try { + if (!(await this._auth.isAuthenticated(userId))) { + return Promise.resolve(false); + } + + if (await SessionUtils.validateSession(await this._dataLayer.getSessionData(userId))) { + return Promise.resolve(true); + } + + const refreshed_token = await this.refreshAccessToken(userId); + + if (refreshed_token) { + return Promise.resolve(true); + } + + this._dataLayer.removeSessionData(userId); + this._dataLayer.getTemporaryData(userId); + return Promise.resolve(false); + } catch (error) { + return Promise.reject(error); + } + } + + public async signOut(userId: string): Promise { + const signOutURL = await this._auth.getSignOutURL(userId); + + if (!signOutURL) { + return Promise.reject( + new AsgardeoAuthException( + 'NODE-AUTH_CORE-SO-NF01', + 'Signing out the user failed.', + 'Could not obtain the sign-out URL from the server.', + ), + ); + } + + return Promise.resolve(signOutURL); + } + + public async getBasicUserInfo(userId: string): Promise { + return this._auth.getBasicUserInfo(userId); + } + + public async getOIDCServiceEndpoints(): Promise { + return this._auth.getOIDCServiceEndpoints() as Promise; + } + + public async getDecodedIDToken(userId?: string): Promise { + return this._auth.getDecodedIDToken(userId); + } + + public async getAccessToken(userId?: string): Promise { + return this._auth.getAccessToken(userId); + } + + public async requestCustomGrant(config: CustomGrantConfig, userId?: string): Promise { + return this._auth.requestCustomGrant(config, userId); + } + + public async updateConfig(config: Partial>): Promise { + return this._auth.updateConfig(config); + } + + public async revokeAccessToken(userId?: string): Promise { + return this._auth.revokeAccessToken(userId); + } + + public static didSignOutFail(signOutRedirectURL: string): boolean { + return AsgardeoNodeCore.didSignOutFail(signOutRedirectURL); + } + + public static isSignOutSuccessful(signOutRedirectURL: string): boolean { + return AsgardeoNodeCore.isSignOutSuccessful(signOutRedirectURL); + } + + public getDataLayer(): DataLayer { + return this._dataLayer; + } +} diff --git a/packages/node/src/__legacy__/core/index.ts b/packages/node/src/__legacy__/core/index.ts new file mode 100644 index 000000000..96eda8f71 --- /dev/null +++ b/packages/node/src/__legacy__/core/index.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2022, WSO2 Inc. (http://www.wso2.com) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from "./authentication"; diff --git a/packages/node/src/__legacy__/models/index.ts b/packages/node/src/__legacy__/models/index.ts new file mode 100644 index 000000000..bffb144d0 --- /dev/null +++ b/packages/node/src/__legacy__/models/index.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2022, WSO2 Inc. (http://www.wso2.com) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from "./url-callback"; +export * from "./session-data"; diff --git a/packages/node/src/__legacy__/models/session-data.ts b/packages/node/src/__legacy__/models/session-data.ts new file mode 100644 index 000000000..3ed2f3c19 --- /dev/null +++ b/packages/node/src/__legacy__/models/session-data.ts @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2022, WSO2 Inc. (http://www.wso2.com) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {TokenResponse} from '@asgardeo/javascript'; + +export interface NodeSessionData extends TokenResponse { + createdAt: number; + expired?: boolean; +} diff --git a/packages/node/src/__legacy__/models/url-callback.ts b/packages/node/src/__legacy__/models/url-callback.ts new file mode 100644 index 000000000..43383a28a --- /dev/null +++ b/packages/node/src/__legacy__/models/url-callback.ts @@ -0,0 +1,20 @@ +/** +* Copyright (c) 2022, WSO2 Inc. (http://www.wso2.com) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ +export interface AuthURLCallback { + (url: string): void; +} diff --git a/packages/node/src/__legacy__/stores/index.ts b/packages/node/src/__legacy__/stores/index.ts new file mode 100644 index 000000000..c3c419131 --- /dev/null +++ b/packages/node/src/__legacy__/stores/index.ts @@ -0,0 +1,19 @@ +/** +* Copyright (c) 2022, WSO2 Inc. (http://www.wso2.com) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +export * from "./memory-cache-store"; diff --git a/packages/node/src/__legacy__/stores/memory-cache-store.ts b/packages/node/src/__legacy__/stores/memory-cache-store.ts new file mode 100644 index 000000000..eec15371e --- /dev/null +++ b/packages/node/src/__legacy__/stores/memory-cache-store.ts @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2022, WSO2 Inc. (http://www.wso2.com) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {Store} from '@asgardeo/javascript'; +import cache from 'memory-cache'; + +export class MemoryCacheStore implements Store { + public async setData(key: string, value: string): Promise { + cache.put(key, value); + } + + public async getData(key: string): Promise { + return cache.get(key) ?? '{}'; + } + + public async removeData(key: string): Promise { + cache.del(key); + } +} diff --git a/packages/node/src/__legacy__/utils/crypto-utils.ts b/packages/node/src/__legacy__/utils/crypto-utils.ts new file mode 100644 index 000000000..fef425ada --- /dev/null +++ b/packages/node/src/__legacy__/utils/crypto-utils.ts @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2022, WSO2 Inc. (http://www.wso2.com) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {Crypto, JWKInterface} from '@asgardeo/javascript'; +import base64url from 'base64url'; +import sha256 from 'fast-sha256'; +import * as jose from 'jose'; +import randombytes from 'secure-random-bytes'; + +export class NodeCryptoUtils implements Crypto { + // eslint-disable-next-line @typescript-eslint/no-empty-function + public constructor() {} + + /** + * Get URL encoded string. + * + * @returns {string} base 64 url encoded value. + */ + public base64URLEncode(value: Buffer | string): string { + return base64url.encode(value).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); + } + + public base64URLDecode(value: string): string { + return base64url.decode(value).toString(); + } + + public hashSha256(data: string): string | Buffer { + return Buffer.from(sha256(new TextEncoder().encode(data))); + } + + public generateRandomBytes(length: number): string | Buffer { + return randombytes(length); + } + + public async verifyJwt( + idToken: string, + jwk: Partial, + algorithms: string[], + clientID: string, + issuer: string, + subject: string, + clockTolerance?: number, + ): Promise { + const key = await jose.importJWK(jwk); + return jose + .jwtVerify(idToken, key, { + algorithms: algorithms, + audience: clientID, + clockTolerance: clockTolerance, + issuer: issuer, + subject: subject, + }) + .then(() => { + return Promise.resolve(true); + }); + } +} diff --git a/packages/node/src/__legacy__/utils/index.ts b/packages/node/src/__legacy__/utils/index.ts new file mode 100644 index 000000000..5ef455db0 --- /dev/null +++ b/packages/node/src/__legacy__/utils/index.ts @@ -0,0 +1,20 @@ +/** +* Copyright (c) 2022, WSO2 Inc. (http://www.wso2.com) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +export * from "./session-utils"; +export * from "./logger-utils"; diff --git a/packages/node/src/__legacy__/utils/logger-utils.ts b/packages/node/src/__legacy__/utils/logger-utils.ts new file mode 100644 index 000000000..0225d53d3 --- /dev/null +++ b/packages/node/src/__legacy__/utils/logger-utils.ts @@ -0,0 +1,88 @@ +/** +* Copyright (c) 2022, WSO2 Inc. (http://www.wso2.com) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +/* eslint-disable no-console */ + +import { LOGGER_CONFIG } from "../constants"; + +enum LogLevel { + DEBUG, + INFO, + WARN, + ERROR, + OFF +} + +export class Logger { + static LOG_LEVEL = process.env["LOG_LEVEL"] ?? LogLevel[LogLevel.OFF]; + + // eslint-disable-next-line @typescript-eslint/no-empty-function + private constructor() { } + + public static debug(message: string): void { + if (LogLevel[this.LOG_LEVEL] <= LogLevel.DEBUG) + console.log( + LOGGER_CONFIG.bgGreen, + LOGGER_CONFIG.fgBlack, + "DEBUG", + LOGGER_CONFIG.reset, + LOGGER_CONFIG.fgGreen, + message, + LOGGER_CONFIG.reset + ); + } + + public static info(message: string): void { + if (LogLevel[this.LOG_LEVEL] <= LogLevel.INFO) + console.log( + LOGGER_CONFIG.bgWhite, + LOGGER_CONFIG.fgBlack, + "INFO", + LOGGER_CONFIG.reset, + LOGGER_CONFIG.fgWhite, + message, + LOGGER_CONFIG.reset + ); + } + + public static warn(message: string): void { + if (LogLevel[this.LOG_LEVEL] <= LogLevel.WARN) + console.log( + LOGGER_CONFIG.bgYellow, + LOGGER_CONFIG.fgBlack, + "WARNING", + LOGGER_CONFIG.reset, + LOGGER_CONFIG.fgYellow, + message, + LOGGER_CONFIG.reset + ); + } + + public static error(message: string): void { + if (LogLevel[this.LOG_LEVEL] <= LogLevel.ERROR) + console.log( + LOGGER_CONFIG.bgRed, + LOGGER_CONFIG.fgBlack, + "ERROR", + LOGGER_CONFIG.reset, + LOGGER_CONFIG.fgRed, + message, + LOGGER_CONFIG.reset + ); + } +} diff --git a/packages/node/src/__legacy__/utils/session-utils.ts b/packages/node/src/__legacy__/utils/session-utils.ts new file mode 100644 index 000000000..16dae8fed --- /dev/null +++ b/packages/node/src/__legacy__/utils/session-utils.ts @@ -0,0 +1,56 @@ +/** +* Copyright (c) 2022, WSO2 Inc. (http://www.wso2.com) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +import { validate as uuidValidate, version as uuidVersion, v4 as uuidv4 } from "uuid"; +import { Logger } from "."; +import { SessionData } from "@asgardeo/javascript"; +import { NodeSessionData } from "../models"; +import { UUID_VERSION } from "../constants"; + +export class SessionUtils { + + // eslint-disable-next-line @typescript-eslint/no-empty-function + private constructor() { } + + public static createUUID(): string { + const generated_uuid = uuidv4(); + return generated_uuid; + } + + public static validateUUID(uuid: string): Promise { + if (uuidValidate(uuid) && uuidVersion(uuid) === UUID_VERSION) { + return Promise.resolve(true) + } else { + return Promise.resolve(false); + } + } + + public static validateSession(sessionData: SessionData): Promise { + const currentTime = Date.now(); + const expiryTimeStamp : number = sessionData.created_at + parseInt(sessionData.expires_in) * 60 * 1000; + //If the expiry time is greater than the current time, then the cookie is still valid + if (currentTime < expiryTimeStamp) { + return Promise.resolve(true); + } else { + Logger.warn("Expired Session"); + + return Promise.resolve(false); + } + } + +} diff --git a/packages/node/src/__tests__/greet.test.ts b/packages/node/src/__tests__/greet.test.ts new file mode 100644 index 000000000..c3ad90eef --- /dev/null +++ b/packages/node/src/__tests__/greet.test.ts @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {describe, expect, it} from 'vitest'; +import greet from '../greet'; + +describe('greet', () => { + it('should return the proper greeting', () => { + expect(greet('World')).toBe('Hello, World!'); + }); +}); diff --git a/packages/node/src/constants/CookieConfig.ts b/packages/node/src/constants/CookieConfig.ts new file mode 100644 index 000000000..56be52eda --- /dev/null +++ b/packages/node/src/constants/CookieConfig.ts @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +class CookieConfig { + static readonly SESSION_COOKIE_NAME: string = 'ASGARDEO_SESSION_ID'; + + static readonly DEFAULT_MAX_AGE: number = 3600; + + static readonly DEFAULT_HTTP_ONLY: boolean = true; + + static readonly DEFAULT_SAME_SITE: 'lax' | 'strict' | 'none' = 'lax'; + + static readonly DEFAULT_SECURE: boolean = true; + + // eslint-disable-next-line @typescript-eslint/no-empty-function + private constructor() {} +} + +export default CookieConfig; diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts new file mode 100644 index 000000000..8fb53beb8 --- /dev/null +++ b/packages/node/src/index.ts @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2022, WSO2 Inc. (http://www.wso2.com) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +//Add Ponyfills for Fetch API +import fetch, { Headers, Request, Response } from "cross-fetch"; + +if (!globalThis.fetch) { + globalThis.fetch = fetch; + globalThis.Headers = Headers; + globalThis.Request = Request; + globalThis.Response = Response; +} + +export {AsgardeoNodeClient as LegacyAsgardeoNodeClient} from './__legacy__/client'; +export * from './__legacy__/models'; +export * from './__legacy__/utils/logger-utils'; + +export {default as CookieConfig} from './constants/CookieConfig'; + +export {AsgardeoNodeConfig} from './models/config'; +export {CookieOptions} from './models/cookies'; + +export {default as generateSessionId} from './utils/generateSessionId'; +export {default as getSessionCookieOptions} from './utils/getSessionCookieOptions'; + +export {default as AsgardeoNodeClient} from './AsgardeoNodeClient'; + +export * from '@asgardeo/javascript'; diff --git a/packages/node/src/models/config.ts b/packages/node/src/models/config.ts new file mode 100644 index 000000000..3e72be224 --- /dev/null +++ b/packages/node/src/models/config.ts @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {Config} from '@asgardeo/javascript'; + +/** + * Configuration type for the Asgardeo Node.js SDK. + * Extends the base Config type from @asgardeo/javascript with Node.js specific settings. + * + * @remarks + * This type is used to configure the Node.js SDK with settings like: + * - Server endpoints + * - Authentication parameters + * - Session management options + */ +export type AsgardeoNodeConfig = Config; diff --git a/packages/node/src/models/cookies.ts b/packages/node/src/models/cookies.ts new file mode 100644 index 000000000..2f8bf9937 --- /dev/null +++ b/packages/node/src/models/cookies.ts @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Configuration options for cookie settings + * + * @typeParam CookieOptions - Interface for cookie configuration options + * + * @remarks + * These options control how cookies are set and handled by the browser: + * - Use `httpOnly` to prevent JavaScript access + * - Set `secure` to true for HTTPS-only cookies + * - Configure `sameSite` for cross-origin request handling + * - Set `maxAge` to control cookie expiration + * + * @example + * Setting secure cookie options: + * ```ts + * const options: CookieOptions = { + * httpOnly: true, + * secure: true, + * sameSite: 'strict', + * maxAge: 3600 // 1 hour + * }; + * ``` + */ +export interface CookieOptions { + /** + * When true, makes the cookie inaccessible through JavaScript + */ + httpOnly?: boolean; + /** + * Maximum age of the cookie in seconds + */ + maxAge?: number; + /** + * Controls how the cookie behaves with cross-site requests + */ + sameSite?: boolean | 'lax' | 'strict' | 'none'; + /** + * When true, cookie will only be sent over HTTPS + */ + secure?: boolean; +} diff --git a/packages/node/src/utils/generateSessionId.ts b/packages/node/src/utils/generateSessionId.ts new file mode 100644 index 000000000..044a206fe --- /dev/null +++ b/packages/node/src/utils/generateSessionId.ts @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const generateSessionId = (): string => new Date().getTime().toString(36) + Math.random().toString(36).substring(2); + +export default generateSessionId; diff --git a/packages/node/src/utils/getSessionCookieOptions.ts b/packages/node/src/utils/getSessionCookieOptions.ts new file mode 100644 index 000000000..9dcfdcefa --- /dev/null +++ b/packages/node/src/utils/getSessionCookieOptions.ts @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import CookieConfig from '../constants/CookieConfig'; +import {CookieOptions} from '../models/cookies'; + +/** + * Creates a complete set of cookie options by merging provided options with defaults + * + * @param options - Partial cookie options to override defaults + * + * @returns Complete cookie options with all required fields + * + * @example + * ```ts + * // Use defaults with only maxAge override + * const options = getSessionCookieOptions({ maxAge: 3600 }); + * + * // Override multiple defaults + * const options = getSessionCookieOptions({ + * maxAge: 3600, + * secure: true, + * sameSite: 'strict' + * }); + * ``` + */ +const getSessionCookieOptions = (options: Partial): CookieOptions => ({ + ...options, + httpOnly: options.httpOnly ?? CookieConfig.DEFAULT_HTTP_ONLY, + maxAge: options.maxAge ?? CookieConfig.DEFAULT_MAX_AGE, + sameSite: options.sameSite ?? CookieConfig.DEFAULT_SAME_SITE, + secure: options.secure ?? CookieConfig.DEFAULT_SECURE, +}); + +export default getSessionCookieOptions; diff --git a/packages/node/tsconfig.eslint.json b/packages/node/tsconfig.eslint.json new file mode 100644 index 000000000..23fadc266 --- /dev/null +++ b/packages/node/tsconfig.eslint.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "include": [ + "**/.*.js", + "**/.*.cjs", + "**/.*.ts", + "**/*.js", + "**/*.cjs", + "**/*.ts", + ] +} diff --git a/packages/node/tsconfig.json b/packages/node/tsconfig.json new file mode 100644 index 000000000..848c27067 --- /dev/null +++ b/packages/node/tsconfig.json @@ -0,0 +1,34 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "declaration": false, + "emitDecoratorMetadata": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "importHelpers": true, + "lib": ["ESNext"], + "module": "ESNext", + "moduleResolution": "node", + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "sourceMap": true, + "target": "ESNext", + "forceConsistentCasingInFileNames": true, + "strict": false, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "exclude": ["node_modules", "tmp", "dist"], + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/packages/node/tsconfig.lib.json b/packages/node/tsconfig.lib.json new file mode 100644 index 000000000..b2c9c1aef --- /dev/null +++ b/packages/node/tsconfig.lib.json @@ -0,0 +1,20 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "declaration": true, + "outDir": "dist", + "declarationDir": "dist", + "types": ["node"] + }, + "exclude": [ + "**/*.spec.ts", + "**/*.test.ts", + "**/*.spec.tsx", + "**/*.test.tsx", + "**/*.spec.js", + "**/*.test.js", + "**/*.spec.jsx", + "**/*.test.jsx" + ], + "include": ["src/**/*.js", "src/**/*.ts", "types/**/*.d.ts"] +} diff --git a/packages/node/tsconfig.spec.json b/packages/node/tsconfig.spec.json new file mode 100644 index 000000000..46a76e285 --- /dev/null +++ b/packages/node/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "test-configs", + "jest.config.js", + "**/*.test.ts", + "**/*.spec.ts", + "**/*.test.js", + "**/*.spec.js", + "**/*.d.ts" + ] +} diff --git a/packages/node/vitest.config.ts b/packages/node/vitest.config.ts new file mode 100644 index 000000000..29a917d10 --- /dev/null +++ b/packages/node/vitest.config.ts @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {defineConfig} from 'vitest/config'; + +export default defineConfig({ + test: {}, +}); diff --git a/packages/nuxt/README.md b/packages/nuxt/README.md index 8b8998fa2..956364b33 100644 --- a/packages/nuxt/README.md +++ b/packages/nuxt/README.md @@ -1,206 +1,26 @@ -# Asgardeo Auth for Nuxt - -[![npm version][npm-version-src]][npm-version-href] -[![npm downloads][npm-downloads-src]][npm-downloads-href] -[![License][license-src]][license-href] -[![Nuxt][nuxt-src]][nuxt-href] - -Nuxt module for Asgardeo - Authentication and Identity Management. Seamlessly integrate Asgardeo authentication into your Nuxt applications. - -- [✨  Release Notes](/CHANGELOG.md) -- [📄  License](LICENSE) -- [🏀  Online Demo](https://github.com/asgardeo/web-ui-sdks/tree/main/recipes/nuxt-vite) - -## Features - -- 🔐  OAuth2/OIDC Authentication with Asgardeo -- 🛡️  Server-side session management -- 🎣  Vue composables for authentication -- 🚀  Simple and easy to use API -- 🔄  Auto-refresh token support - -## Quick Setup - -Install the module to your Nuxt application with one command: +

+

@asgardeo/nuxt

+

+

Nuxt.js SDK for Asgardeo

+
+ npm (scoped) + npm + License +
+ +## Installation ```bash +# Using npm npm install @asgardeo/nuxt -``` - -Then, configure your Nuxt application by updating the `nuxt.config.ts` file: - -```typescript -// https://nuxt.com/docs/api/configuration/nuxt-config -export default defineNuxtConfig({ - compatibilityDate: '2025-05-15', - devtools: { enabled: true }, - modules: ['@asgardeo/nuxt'] -}); -``` - -Next, create a `server/api/auth/[...].ts` file and add the following code: -```typescript -import { AsgardeoAuthHandler } from '@asgardeo/nuxt/server'; +# or using pnpm +pnpm add @asgardeo/nuxt -const config = { - baseUrl: process.env.ASGARDEO_BASE_URL as string, - clientID: process.env.ASGARDEO_CLIENT_ID as string, - clientSecret: process.env.ASGARDEO_CLIENT_SECRET as string, - signInRedirectURL: process.env.ASGARDEO_SIGN_IN_REDIRECT_URL as string, - signOutRedirectURL: process.env.ASGARDEO_SIGN_OUT_REDIRECT_URL as string, - scope: process.env.ASGARDEO_SCOPE?.split(",").map(scope => scope.trim()) as string[] -}; - -export default AsgardeoAuthHandler(config); -``` - -Also, create an `.env` file to store your environment variables: - -``` -ASGARDEO_BASE_URL=https://api.asgardeo.io/t/ -ASGARDEO_CLIENT_ID= -ASGARDEO_CLIENT_SECRET= -ASGARDEO_SIGN_IN_REDIRECT_URL=http://localhost:3000/api/auth/callback -ASGARDEO_SIGN_OUT_REDIRECT_URL=http://localhost:3000 -ASGARDEO_SCOPE=openid,profile,email -``` - -Finally, you can use the SDK in your Vue components like this: - -```typescript - - - +# or using yarn +yarn add @asgardeo/nuxt ``` -That's it! You can now use Asgardeo Auth in your Nuxt app ✨ - -## API Reference - -### `useAuth()` - -The `useAuth` composable provides access to authentication functionality: - -```typescript -const { - signIn, - signOut, - isAuthenticated, - getBasicUserInfo, - getIDToken, - getAccessToken, - getRefreshToken, - getDecodedIDToken -} = useAuth(); -``` - -| Method | Description | -| ------ | ----------- | -| `signIn(callbackUrl?)` | Initiates the login process. Optionally accepts a callback URL to redirect to after successful login. | -| `signOut(callbackUrl?)` | Logs the user out. Optionally accepts a callback URL to redirect to after logout. | -| `isAuthenticated` | Boolean ref that indicates if the user is authenticated. | -| `getBasicUserInfo()` | Returns basic user information. | -| `getIDToken()` | Returns the ID token. | -| `getAccessToken()` | Returns the access token. | -| `getRefreshToken()` | Returns the refresh token. | -| `getDecodedIDToken()` | Returns the decoded ID token payload. | - -## Configuration - -You can also configure the module in your `nuxt.config.ts` file: - -```typescript -export default defineNuxtConfig({ - // ... other config - modules: ['@asgardeo/nuxt'], - asgardeoAuth: { - // Override env variables - baseUrl: 'https://api.asgardeo.io/t/your-org-name', - clientID: 'your-client-id', - clientSecret: 'your-client-secret', - signInRedirectURL: 'http://localhost:3000/api/auth/callback', - signOutRedirectURL: 'http://localhost:3000', - scope: ['openid', 'profile', 'email'] - } -}); -``` - -## Troubleshooting - -### CORS Issues - -If you encounter CORS (Cross-Origin Resource Sharing) issues when interacting with Asgardeo, make sure your Asgardeo application has the correct origins configured: - -1. Go to the Asgardeo Console -2. Navigate to your application -3. Under "Protocol" tab, add your application URL to the "Allowed Origins" list (e.g., `http://localhost:3000`) - -### Authentication Flows - -This module uses the Authorization Code flow with PKCE by default. If you need to customize this, you can set `enablePKCE: false` in your configuration. - -### Common Errors - -- **Invalid Redirect URI**: Ensure your `signInRedirectURL` matches exactly what's configured in Asgardeo -- **Token Validation Failed**: Check that your clock is synchronized and that your application's time is accurate -- **Scope Not Granted**: Verify that your application has the necessary scopes configured in Asgardeo - -For more troubleshooting help, refer to the [Asgardeo documentation](https://wso2.com/asgardeo/docs/). - -## Contribution - -
- Local development - - ```bash - # Install dependencies - npm install - - # Generate type stubs - npm run dev:prepare - - # Develop with the playground - npm run dev - - # Build the playground - npm run dev:build - - # Run ESLint - npm run lint - - # Run Vitest - npm run test - npm run test:watch - - # Release new version - npm run release - ``` - -
- - -[npm-version-src]: https://img.shields.io/npm/v/@asgardeo/nuxt/latest.svg?style=flat&colorA=020420&colorB=00DC82 -[npm-version-href]: https://npmjs.com/package/@asgardeo/nuxt - -[npm-downloads-src]: https://img.shields.io/npm/dm/@asgardeo/nuxt.svg?style=flat&colorA=020420&colorB=00DC82 -[npm-downloads-href]: https://npm.chart.dev/@asgardeo/nuxt - -[license-src]: https://img.shields.io/npm/l/@asgardeo/nuxt.svg?style=flat&colorA=020420&colorB=00DC82 -[license-href]: https://npmjs.com/package/@asgardeo/nuxt +## License -[nuxt-src]: https://img.shields.io/badge/Nuxt-020420?logo=nuxt.js -[nuxt-href]: https://nuxt.com +Apache-2.0 diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index 690853c1a..a4bb27560 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -1,6 +1,6 @@ { "name": "@asgardeo/nuxt", - "version": "0.0.1", + "version": "0.0.0", "description": "Nuxt module for Asgardeo - Authentication and Identity Management", "author": "WSO2", "license": "Apache-2.0", @@ -68,11 +68,13 @@ "@types/node": "latest", "changelogen": "^0.6.1", "cookie-es": "^2.0.0", - "eslint": "catalog:", + "eslint": "8.57.0", "nuxt": "^3.16.2", "typescript": "~5.8.3", "vitest": "^3.1.1", "vue-tsc": "^2.2.8" }, - "packageManager": "pnpm@10.8.0+sha512.0e82714d1b5b43c74610193cb20734897c1d00de89d0e18420aebc5977fa13d780a9cb05734624e81ebd81cc876cd464794850641c48b9544326b5622ca29971" -} + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/packages/nuxt/src/runtime/composables/asgardeo/useAuth.ts b/packages/nuxt/src/runtime/composables/asgardeo/useAuth.ts index 32a1c9358..c1b8a910f 100644 --- a/packages/nuxt/src/runtime/composables/asgardeo/useAuth.ts +++ b/packages/nuxt/src/runtime/composables/asgardeo/useAuth.ts @@ -16,7 +16,7 @@ * under the License. */ -import type {BasicUserInfo, DataLayer, DecodedIDTokenPayload, OIDCEndpoints} from '@asgardeo/auth-node'; +import type {BasicUserInfo, DataLayer, IdTokenPayload, OIDCEndpoints} from '@asgardeo/auth-node'; import type {AuthInterface} from '../../types'; import {navigateTo} from '#imports'; @@ -98,9 +98,9 @@ export const useAuth = (): AuthInterface => { * which expects a valid session cookie. If the session is valid, the function * returns the decoded ID token payload. * - * @returns {Promise} - A promise that resolves to the decoded ID token payload if available, or null if not. + * @returns {Promise} - A promise that resolves to the decoded ID token payload if available, or null if not. */ - const getDecodedIDToken = async (): Promise => { + const getDecodedIDToken = async (): Promise => { try { const response: Response = await fetch(`/api/auth/get-decoded-id-token`, { credentials: 'include', diff --git a/packages/nuxt/src/runtime/types.ts b/packages/nuxt/src/runtime/types.ts index 4584106d2..e34ac84e6 100644 --- a/packages/nuxt/src/runtime/types.ts +++ b/packages/nuxt/src/runtime/types.ts @@ -16,7 +16,7 @@ * under the License. */ -import type {BasicUserInfo, DataLayer, DecodedIDTokenPayload, OIDCEndpoints} from '@asgardeo/auth-node'; +import type {BasicUserInfo, DataLayer, IdTokenPayload, OIDCEndpoints} from '@asgardeo/auth-node'; export interface ModuleOptions { /** @@ -61,7 +61,7 @@ export interface AuthInterface { getAccessToken: () => Promise; getBasicUserInfo: () => Promise; getDataLayer: () => Promise | null>; - getDecodedIDToken: () => Promise; + getDecodedIDToken: () => Promise; getIdToken: () => Promise; getOIDCServiceEndpoints: () => Promise; isAuthenticated: () => Promise; diff --git a/packages/react/.editorconfig b/packages/react/.editorconfig index 54a161112..1b3ce07de 100644 --- a/packages/react/.editorconfig +++ b/packages/react/.editorconfig @@ -1 +1 @@ -../../.editorconfig +../../.editorconfig \ No newline at end of file diff --git a/packages/react/.eslintignore b/packages/react/.eslintignore index c925c21d5..177586b6b 100644 --- a/packages/react/.eslintignore +++ b/packages/react/.eslintignore @@ -1,2 +1,4 @@ /dist +/build /node_modules +/coverage \ No newline at end of file diff --git a/packages/react/.eslintrc.cjs b/packages/react/.eslintrc.cjs index d8644f33e..2676ca816 100644 --- a/packages/react/.eslintrc.cjs +++ b/packages/react/.eslintrc.cjs @@ -1,5 +1,5 @@ /** - * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -19,30 +19,20 @@ const path = require('path'); module.exports = { + env: { + es6: true, + node: true, + }, extends: [ 'plugin:@wso2/typescript', - 'plugin:@wso2/react', 'plugin:@wso2/strict', 'plugin:@wso2/internal', - 'plugin:@wso2/prettier', 'plugin:@wso2/jest', - 'plugin:react/jsx-runtime', + 'plugin:@wso2/prettier', ], parserOptions: { - project: [path.resolve(__dirname, 'tsconfig.lib.json'), path.resolve(__dirname, 'tsconfig.eslint.json')], + ecmaVersion: 2018, + project: [path.resolve(__dirname, 'tsconfig.eslint.json')], }, plugins: ['@wso2'], - rules: { - // In `SignIn.tsx` we are using non dot notation to access the object properties. - // TODO: Refactor the code to use dot notation. - '@typescript-eslint/dot-notation': 'off', - // We are throwing custom exceptions in the codebase. - // Hence, turning this off to avoid linting errors. (https://eslint.org/docs/latest/rules/no-throw-literal#known-limitations) - '@typescript-eslint/no-throw-literal': 'off', - // TODO: Fix this and enable. - // Occurred while linting /packages/react/src/utils/crypto-utils.ts:33 - // Rule: "@typescript-eslint/no-useless-constructor" - '@typescript-eslint/no-useless-constructor': 'off', - 'class-methods-use-this': 'off', - }, }; diff --git a/packages/react/.gitignore b/packages/react/.gitignore index f20a8a8c1..c6bba5913 100644 --- a/packages/react/.gitignore +++ b/packages/react/.gitignore @@ -128,7 +128,3 @@ dist .yarn/build-state.yml .yarn/install-state.gz .pnp.* - -# misc -.DS_Store -*.pem diff --git a/packages/react/.prettierignore b/packages/react/.prettierignore index c925c21d5..99b0b518a 100644 --- a/packages/react/.prettierignore +++ b/packages/react/.prettierignore @@ -1,2 +1,4 @@ /dist +/build /node_modules +/coverage diff --git a/packages/react/README.md b/packages/react/README.md index 30b225361..c224c2600 100644 --- a/packages/react/README.md +++ b/packages/react/README.md @@ -1,7 +1,7 @@

@asgardeo/react

-

React Wrapper to build customizable login UIs for Asgardeo or Identity Server

+

React SDK for Asgardeo

npm (scoped) npm @@ -11,17 +11,119 @@ ## Installation ```bash -# With npm +# Using npm npm install @asgardeo/react -# With pnpm +# or using pnpm pnpm add @asgardeo/react -# With yarn +# or using yarn yarn add @asgardeo/react ``` +## Quick Start + +1. Add `` to your app + +```tsx +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import './index.css' +import App from './App.tsx' +import { AsgardeoProvider } from '@asgardeo/react' + +createRoot(document.getElementById('root')).render( + + ' + clientId: '' + > + + + +) +``` + +2. Add signed-in and signed-out to your app + +```tsx +import { SignedIn, SignedOut, SignInButton, SignOutButton } from '@asgardeo/react' +import './App.css' + +function App() { + return ( + <> + + + + + + + + ) +} + +export default App +``` + +3. Start using other drop-in components like `User`, `UserProfile`, etc. + +```tsx +import { User, UserProfile } from '@asgardeo/react' +import './App.css' + +function App() { + return ( + <> + + {({ user }) => ( +
+

Welcome, {user.username}

+ +
+ )} +
+ + + + ) +} +export default App +``` + +## Using the `useAsgardeo` Hook (For Programmatic Control) + +For more granular control, you can use the useAsgardeo hook. This hook provides direct access to SDK's functions and state: + +```tsx +import { useAsgardeo } from '@asgardeo/react' +import './App.css' + +function App() { + const { user, signIn, signOut, isSignedIn, isLoading } = useAsgardeo() + + if (isLoading) { + return
Loading...
+ } + + return ( +
+ {isSignedIn ? ( +
+
+ {user.username} +

Welcome back, {user.givenname}

+
+ +
+ ) : ( + + )} +
+ ) +} +``` + ## License -Licenses this source under the Apache License, Version 2.0 [LICENSE](./LICENSE), You may not use this file except in -compliance with the License. +Apache-2.0 diff --git a/packages/react/esbuild.config.mjs b/packages/react/esbuild.config.mjs new file mode 100644 index 000000000..efecbbeb8 --- /dev/null +++ b/packages/react/esbuild.config.mjs @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {readFileSync} from 'fs'; +import {build} from 'esbuild'; +import {preserveDirectivesPlugin} from 'esbuild-plugin-preserve-directives'; + +const pkg = JSON.parse(readFileSync('./package.json', 'utf8')); + +const commonOptions = { + bundle: true, + entryPoints: ['src/index.ts'], + external: [...Object.keys(pkg.dependencies || {}), ...Object.keys(pkg.peerDependencies || {})], + metafile: true, + platform: 'browser', + plugins: [ + preserveDirectivesPlugin({ + directives: ['use client', 'use strict'], + include: /\.(js|ts|jsx|tsx)$/, + exclude: /node_modules/, + }), + ], + target: ['es2020'], +}; + +await build({ + ...commonOptions, + format: 'esm', + outfile: 'dist/index.js', + sourcemap: true, +}); + +await build({ + ...commonOptions, + format: 'cjs', + outfile: 'dist/cjs/index.js', + sourcemap: true, +}); diff --git a/packages/react/package.json b/packages/react/package.json index 84c576f63..ef2eb69aa 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,80 +1,75 @@ { "name": "@asgardeo/react", "version": "0.2.4", - "description": "React Wrapper to build customizable login UIs for Asgardeo or Identity Server", - "main": "dist/esm/index.js", - "module": "dist/esm/index.js", - "types": "dist/index.d.ts", - "type": "module", + "description": "React implementation of Asgardeo JavaScript SDK.", + "keywords": [ + "asgardeo", + "react", + "spa" + ], + "homepage": "https://github.com/asgardeo/javascript/tree/main/packages/react#readme", + "bugs": { + "url": "https://github.com/asgardeo/javascript/issues" + }, "author": "WSO2", "license": "Apache-2.0", + "type": "module", + "main": "dist/cjs/index.js", + "module": "dist/index.js", + "exports": { + "import": "./dist/index.js", + "require": "./dist/cjs/index.js" + }, "files": [ "dist", - "LICENSE", - "README.md" + "README.md", + "LICENSE" ], - "homepage": "https://github.com/asgardeo/web-ui-sdks/tree/main/packages/react#readme", - "bugs": { - "url": "https://github.com/asgardeo/web-ui-sdks/issues" - }, + "types": "dist/index.d.ts", "repository": { "type": "git", - "url": "https://github.com/asgardeo/web-ui-sdks", + "url": "https://github.com/asgardeo/javascript", "directory": "packages/react" }, - "keywords": [ - "asgardeo", - "identity", - "ui", - "react", - "login", - "customize" - ], "scripts": { - "build": "rollup -c", - "lint": "eslint .", - "lint:fix": "eslint . --fix" - }, - "publishConfig": { - "access": "public" + "build": "pnpm clean && node esbuild.config.mjs && tsc -p tsconfig.lib.json --emitDeclarationOnly --outDir dist", + "clean": "rimraf dist", + "fix:lint": "eslint . --ext .js,.jsx,.ts,.tsx,.cjs,.mjs", + "lint": "eslint . --ext .js,.jsx,.ts,.tsx,.cjs,.mjs", + "test": "vitest", + "test:browser": "vitest --workspace=vitest.workspace.ts", + "typecheck": "tsc -p tsconfig.lib.json" }, "devDependencies": { - "@rollup/plugin-commonjs": "^25.0.7", - "@rollup/plugin-image": "^3.0.3", - "@rollup/plugin-node-resolve": "^15.2.3", - "@rollup/plugin-typescript": "^11.1.6", - "@types/node": "^20.12.7", - "@types/randombytes": "^2.0.3", - "@types/react": "^18.2.79", - "@types/react-dom": "^18.2.25", + "@testing-library/dom": "^10.4.0", + "@types/node": "^22.15.3", + "@types/react": "^19.1.4", + "@vitest/browser": "^3.1.3", "@wso2/eslint-plugin": "catalog:", "@wso2/prettier-config": "catalog:", - "@wso2/stylelint-config": "catalog:", - "eslint": "catalog:", - "prettier": "^3.2.5", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "rollup": "^4.17.2", - "rollup-plugin-dts": "^6.1.0", - "rollup-plugin-polyfill-node": "^0.13.0", - "rollup-plugin-styles": "^4.0.0", - "sass": "^1.75.0", - "stylelint": "15.1.0", - "tslib": "^2.6.2", - "typescript": "5.1.6" + "esbuild-plugin-preserve-directives": "^0.0.11", + "eslint": "8.57.0", + "playwright": "^1.52.0", + "prettier": "^2.6.2", + "react": "^19.1.0", + "rimraf": "^6.0.1", + "typescript": "~5.7.2", + "vitest": "^3.1.3", + "vitest-browser-react": "^0.1.1" + }, + "peerDependencies": { + "@types/react": ">=16.8.0", + "react": ">=16.8.0" }, "dependencies": { - "@asgardeo/js": "*", - "@oxygen-ui/react": "^1.11.0", - "base64url": "^3.0.1", - "buffer": "^6.0.3", + "@asgardeo/browser": "workspace:^", + "@types/react-dom": "^19.1.5", "clsx": "^2.1.1", - "fast-sha256": "^1.3.0", - "jose": "^5.3.0", - "randombytes": "^2.1.0" + "esbuild": "^0.25.4", + "react-dom": "^19.1.0", + "tslib": "^2.8.1" }, - "peerDependencies": { - "react": ">=18.0.0", - "react-dom": ">=18.0.0" + "publishConfig": { + "access": "public" } -} +} \ No newline at end of file diff --git a/packages/react/prettier.config.cjs b/packages/react/prettier.config.cjs index c07f730d2..929b9b15f 100644 --- a/packages/react/prettier.config.cjs +++ b/packages/react/prettier.config.cjs @@ -1,5 +1,5 @@ /** - * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/packages/react/src/AsgardeoReactClient.ts b/packages/react/src/AsgardeoReactClient.ts new file mode 100644 index 000000000..951271b72 --- /dev/null +++ b/packages/react/src/AsgardeoReactClient.ts @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + AsgardeoBrowserClient, + extractUserClaimsFromIdToken, + getUserInfo, + SignInOptions, + SignOutOptions, + User, +} from '@asgardeo/browser'; +import AuthAPI from './__temp__/api'; +import {AsgardeoReactConfig} from './models/config'; +import getUserProfile from './utils/getUserProfile'; + +/** + * Client for mplementing Asgardeo in React applications. + * This class provides the core functionality for managing user authentication and sessions. + * + * @typeParam T - Configuration type that extends AsgardeoReactConfig. + */ +class AsgardeoReactClient extends AsgardeoBrowserClient { + private asgardeo: AuthAPI; + + constructor() { + super(); + + // FIXME: This has to be the browser client from `@asgardeo/browser` package. + this.asgardeo = new AuthAPI(); + } + + override initialize(config: T): Promise { + const scopes: string[] = Array.isArray(config.scopes) ? config.scopes : config.scopes.split(' '); + + return this.asgardeo.init({ + baseUrl: config.baseUrl, + clientID: config.clientId, + signInRedirectURL: config.afterSignInUrl, + scope: [...scopes, 'internal_login'], + }); + } + + override async getUser(): Promise { + const baseUrl = await (await this.asgardeo.getConfigData()).baseUrl; + const profile = await getUserProfile({baseUrl}); + + return profile; + } + + override isLoading(): boolean { + return this.asgardeo.isLoading(); + } + + override isSignedIn(): Promise { + return this.asgardeo.isSignedIn(); + } + + override signIn(options?: SignInOptions): Promise { + return this.asgardeo.signIn(options as any) as unknown as Promise; + } + + override signOut(options?: SignOutOptions, afterSignOut?: (redirectUrl: string) => void): Promise; + override signOut( + options?: SignOutOptions, + sessionId?: string, + afterSignOut?: (redirectUrl: string) => void, + ): Promise; + override async signOut(...args: any[]): Promise { + if (args[1] && typeof args[1] !== 'function') { + throw new Error('The second argument must be a function.'); + } + + const response: boolean = await this.asgardeo.signOut(args[1]); + + return Promise.resolve(String(response)); + } +} + +export default AsgardeoReactClient; diff --git a/packages/react/src/__temp__/api.ts b/packages/react/src/__temp__/api.ts new file mode 100644 index 000000000..dd46c12d8 --- /dev/null +++ b/packages/react/src/__temp__/api.ts @@ -0,0 +1,487 @@ +/** + * Copyright (c) 2025, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + AsgardeoSPAClient, + AuthClientConfig, + BasicUserInfo, + LegacyConfig as Config, + IdTokenPayload, + FetchResponse, + Hooks, + HttpClientInstance, + HttpRequestConfig, + HttpResponse, + OIDCEndpoints, + SignInConfig, + SPACustomGrantConfig, +} from '@asgardeo/browser'; +import {AuthStateInterface} from './models'; + +class AuthAPI { + static DEFAULT_STATE: AuthStateInterface; + + private _authState = AuthAPI.DEFAULT_STATE; + private _client: AsgardeoSPAClient; + + private _isLoading: boolean; + + constructor(spaClient?: AsgardeoSPAClient) { + this._client = spaClient ?? AsgardeoSPAClient.getInstance(); + + this.getState = this.getState.bind(this); + this.init = this.init.bind(this); + this.signIn = this.signIn.bind(this); + this.signOut = this.signOut.bind(this); + this.updateState = this.updateState.bind(this); + } + + public _setIsLoading(isLoading: boolean): void { + this._isLoading = isLoading; + } + + public _getIsLoading(): boolean { + return this._isLoading; + } + + public isSignedIn(): Promise { + return this.isAuthenticated(); + } + + public isLoading(): boolean { + return this._getIsLoading(); + } + + /** + * Method to return Auth Client instance authentication state. + * + * @return {AuthStateInterface} Authentication State. + */ + public getState(): AuthStateInterface { + return this._authState; + } + + /** + * Method to initialize the AuthClient instance. + * + * @param {Config} config - `dispatch` function from React Auth Context. + */ + public async init(config: AuthClientConfig): Promise { + return await this._client.initialize(config); + } + + /** + * Method to get the configuration data. + * + * @returns {Promise>} - A promise that resolves with the configuration data. + */ + public async getConfigData(): Promise> { + return await this._client.getConfigData(); + } + + /** + * Method to handle user Sign In requests. + * + * @param {any} dispatch - `dispatch` function from React Auth Context. + * @param {AuthStateInterface} state - Current authentication state in React Auth Context. + * @param {any} callback - Action to trigger on successful sign in. + */ + public async signIn( + // dispatch: (state: AuthStateInterface) => void, + // state: AuthStateInterface, + config: SignInConfig, + authorizationCode?: string, + sessionState?: string, + authState?: string, + callback?: (response: BasicUserInfo) => void, + tokenRequestConfig?: { + params: Record; + }, + ): Promise { + return this._client + .signIn(config, authorizationCode, sessionState, authState, tokenRequestConfig) + .then(async (response: BasicUserInfo) => { + if (!response) { + return null; // FIXME: Validate this. Temp fix for: error TS7030: Not all code paths return a value. + } + + if (await this._client.isAuthenticated()) { + const stateToUpdate = { + allowedScopes: response.allowedScopes, + displayName: response.displayName, + email: response.email, + isAuthenticated: true, + isLoading: false, + isSigningOut: false, + sub: response.sub, + username: response.username, + }; + + this.updateState(stateToUpdate); + + // dispatch({...state, ...stateToUpdate}); + this._setIsLoading(false); + + if (callback) { + callback(response); + } + } + + return response; + }) + .catch(error => { + return Promise.reject(error); + }); + } + + /** + * Method to handle user Sign Out requests. + * + * @param {any} dispatch - `dispatch` function from React Auth Context. + * @param {AuthStateInterface} state - Current authentication state in React Auth Context. + * @param {any} callback - Action to trigger on successful sign out. + */ + public signOut(callback?: (response?: boolean) => void): Promise { + return this._client + .signOut() + .then(response => { + if (callback) { + callback(response); + } + + return response; + }) + .catch(error => { + return Promise.reject(error); + }); + } + + /** + * Method to update Auth Client instance authentication state. + * + * @param {AuthStateInterface} state - State values to update in authentication state. + */ + public updateState(state: AuthStateInterface): void { + this._authState = {...this._authState, ...state}; + } + + /** + * This method returns a Promise that resolves with the basic user information obtained from the ID token. + * + * @return {Promise} - A promise that resolves with the user information. + */ + public async getBasicUserInfo(): Promise { + return this._client.getBasicUserInfo(); + } + + /** + * This method sends an API request to a protected endpoint. + * The access token is automatically attached to the header of the request. + * This is the only way by which protected endpoints can be accessed + * when the web worker is used to store session information. + * + * @param {HttpRequestConfig} config - The config object containing attributes necessary to send a request. + * + * @return {Promise} - Returns a Promise that resolves with the response to the request. + */ + public async httpRequest(config: HttpRequestConfig): Promise> { + return this._client.httpRequest(config); + } + + /** + * This method sends multiple API requests to a protected endpoint. + * The access token is automatically attached to the header of the request. + * This is the only way by which multiple requests can be sent to protected endpoints + * when the web worker is used to store session information. + * + * @param {HttpRequestConfig[]} config - The config object containing attributes necessary to send a request. + * + * @return {Promise} - Returns a Promise that resolves with the responses to the requests. + */ + public async httpRequestAll(configs: HttpRequestConfig[]): Promise[]> { + return this._client.httpRequestAll(configs); + } + + /** + * This method allows you to send a request with a custom grant. + * + * @param {CustomGrantRequestParams} config - The request parameters. + * + * @return {Promise | SignInResponse>} - A Promise that resolves with + * the value returned by the custom grant request. + */ + public requestCustomGrant( + config: SPACustomGrantConfig, + callback: (response: BasicUserInfo | FetchResponse) => void, + dispatch: (state: AuthStateInterface) => void, + ): Promise> { + return this._client + .requestCustomGrant(config) + .then((response: BasicUserInfo | FetchResponse) => { + if (!response) { + return null; // FIXME: Validate this. Temp fix for: error TS7030: Not all code paths return a value. + } + + if (config.returnsSession) { + this.updateState({ + ...this.getState(), + ...(response as BasicUserInfo), + isAuthenticated: true, + isLoading: false, + }); + + dispatch({...(response as BasicUserInfo), isAuthenticated: true, isLoading: false}); + } + + callback && callback(response); + + return response; + }) + .catch(error => { + return Promise.reject(error); + }); + } + + /** + * This method ends a user session. The access token is revoked and the session information is destroyed. + * + * @return {Promise} - A promise that resolves with `true` if the process is successful. + */ + public async revokeAccessToken(dispatch: (state: AuthStateInterface) => void): Promise { + return this._client + .revokeAccessToken() + .then(() => { + this.updateState({...AuthAPI.DEFAULT_STATE, isLoading: false}); + dispatch(AuthAPI.DEFAULT_STATE); + return true; + }) + .catch(error => { + return Promise.reject(error); + }); + } + + /** + * This method returns a Promise that resolves with an object containing the service endpoints. + * + * @return {Promise { + return this._client.getOIDCServiceEndpoints(); + } + + /** + * This methods returns the Axios http client. + * + * @return {HttpClientInstance} - The Axios HTTP client. + */ + public async getHttpClient(): Promise { + return this._client.getHttpClient(); + } + + /** + * This method decodes the payload of the id token and returns it. + * + * @return {Promise} - A Promise that resolves with + * the decoded payload of the id token. + */ + public async getDecodedIDToken(): Promise { + return this._client.getDecodedIDToken(); + } + + /** + * This method decodes the payload of the idp id token and returns it. + * + * @return {Promise} - A Promise that resolves with + * the decoded payload of the idp id token. + */ + public async getDecodedIDPIDToken(): Promise { + return this._client.getDecodedIDToken(); + } + + /** + * This method returns the ID token. + * + * @return {Promise} - A Promise that resolves with the id token. + */ + public async getIDToken(): Promise { + return this._client.getIDToken(); + } + + /** + * This method return a Promise that resolves with the access token. + * + * **This method will not return the access token if the storage type is set to `webWorker`.** + * + * @return {Promise} - A Promise that resolves with the access token. + */ + public async getAccessToken(): Promise { + return this._client.getAccessToken(); + } + + /** + * This method return a Promise that resolves with the idp access token. + * + * **This method will not return the idp access token if the storage type is set to `webWorker`.** + * **This can be used to access the IDP access token when custom auth grant functionalities are used** + * + * @return {Promise} - A Promise that resolves with the idp access token. + */ + public async getIDPAccessToken(): Promise { + return this._client.getIDPAccessToken(); + } + + /** + * This method refreshes the access token. + * + * @return {TokenResponseInterface} - A Promise that resolves with an object containing + * information about the refreshed access token. + */ + public async refreshAccessToken(): Promise { + return this._client.refreshAccessToken(); + } + + /** + * This method specifies if the user is authenticated or not. + * + * @return {Promise} - A Promise that resolves with `true` if teh user is authenticated. + */ + public async isAuthenticated(): Promise { + return this._client.isAuthenticated(); + } + + /** + * This method specifies if the session is active or not. + * + * @return {Promise} - A Promise that resolves with `true` if there is an active session. + */ + public async isSessionActive(): Promise { + return this._client.isSessionActive(); + } + + /** + * This method enables callback functions attached to the http client. + * + * @return {Promise} - A promise that resolves with True. + * + */ + public async enableHttpHandler(): Promise { + return this._client.enableHttpHandler(); + } + + /** + * This method disables callback functions attached to the http client. + * + * @return {Promise} - A promise that resolves with True. + */ + public async disableHttpHandler(): Promise { + return this._client.disableHttpHandler(); + } + + /** + * This method updates the configuration that was passed into the constructor when instantiating this class. + * + * @param {Partial>} config - A config object to update the SDK configurations with. + */ + public async updateConfig(config: Partial>): Promise { + return this._client.updateConfig(config); + } + + /** + * This method attaches a callback function to an event hook that fires the callback when the event happens. + * + * @param {Hooks.CustomGrant} hook - The name of the hook. + * @param {(response?: any) => void} callback - The callback function. + * @param {string} id (optional) - The id of the hook. This is used when multiple custom grants are used. + * + */ + public on(hook: Hooks.CustomGrant, callback: (response?: any) => void, id: string): Promise; + public on(hook: Exclude, callback: (response?: any) => void): Promise; + public on(hook: Hooks, callback: (response?: any) => void, id?: string): Promise { + if (hook === Hooks.CustomGrant) { + return this._client.on(hook, callback, id); + } + + return this._client.on(hook, callback); + } + + /** + * This method allows you to sign in silently. + * First, this method sends a prompt none request to see if there is an active user session in the identity server. + * If there is one, then it requests the access token and stores it. Else, it returns false. + * + * @return {Promise} - A Promise that resolves with the user information after signing in + * or with `false` if the user is not signed in. + * + * @example + *``` + * client.trySignInSilently() + *``` + */ + public async trySignInSilently( + state: AuthStateInterface, + dispatch: (state: AuthStateInterface) => void, + additionalParams?: Record, + tokenRequestConfig?: {params: Record}, + ): Promise { + return this._client + .trySignInSilently(additionalParams, tokenRequestConfig) + .then(async (response: BasicUserInfo | boolean) => { + if (!response) { + this.updateState({...this.getState(), isLoading: false}); + dispatch({...state, isLoading: false}); + + return false; + } + + if (await this._client.isAuthenticated()) { + const basicUserInfo = response as BasicUserInfo; + const stateToUpdate = { + allowedScopes: basicUserInfo.allowedScopes, + displayName: basicUserInfo.displayName, + email: basicUserInfo.email, + isAuthenticated: true, + isLoading: false, + isSigningOut: false, + sub: basicUserInfo.sub, + username: basicUserInfo.username, + }; + + this.updateState(stateToUpdate); + + dispatch({...state, ...stateToUpdate}); + } + + return response; + }) + .catch(error => { + return Promise.reject(error); + }); + } +} + +AuthAPI.DEFAULT_STATE = { + allowedScopes: '', + displayName: '', + email: '', + isAuthenticated: false, + isLoading: true, + sub: '', + username: '', +}; + +export default AuthAPI; diff --git a/packages/react/src/__temp__/models.ts b/packages/react/src/__temp__/models.ts new file mode 100644 index 000000000..f6d1edae7 --- /dev/null +++ b/packages/react/src/__temp__/models.ts @@ -0,0 +1,137 @@ +/** + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + AsgardeoAuthException, + AuthClientConfig, + AuthSPAClientConfig, + BasicUserInfo, + Config, + CustomGrantConfig, + IdTokenPayload, + FetchResponse, + Hooks, + HttpClientInstance, + HttpRequestConfig, + HttpResponse, + OIDCEndpoints, + SignInConfig, +} from '@asgardeo/browser'; + +export interface ReactConfig { + /** + * The SDK's `AuthProvider` by default is listening to the URL changes to see + * if `code` & `session_state` search params are available so that it could perform + * token exchange. This option could be used to override that behaviour. + */ + skipRedirectCallback?: boolean; + /** + * The `AuthProvider`, by default, looks for an active session in the server and updates the session information + * with the latest session information from the server. This option could be used to disable that behaviour. + */ + disableTrySignInSilently?: boolean; + disableAutoSignIn?: boolean; +} + +export type AuthReactConfig = AuthSPAClientConfig & ReactConfig; + +/** + * Interface for the Authenticated state of the user which is exposed + * via `state` object from `useAuthContext` hook. + */ +export interface AuthStateInterface { + /** + * The scopes that are allowed for the user. + */ + allowedScopes: string; + /** + * The display name of the user. + */ + displayName?: string; + /** + * The email address of the user. + */ + email?: string; + /** + * Specifies if the user is authenticated or not. + */ + isAuthenticated: boolean; + /** + * Are the Auth requests loading. + */ + isLoading: boolean; + /** + * The uid corresponding to the user who the ID token belonged to. + */ + sub?: string; + /** + * The username of the user. + */ + username?: string; +} + +export interface AuthContextInterface { + signIn: ( + config?: SignInConfig, + authorizationCode?: string, + sessionState?: string, + state?: string, + callback?: (response: BasicUserInfo) => void, + tokenRequestConfig?: { + params: Record; + }, + ) => Promise; + signOut: (callback?: (response: boolean) => void) => Promise; + getBasicUserInfo(): Promise; + httpRequest(config: HttpRequestConfig): Promise>; + httpRequestAll(configs: HttpRequestConfig[]): Promise[]>; + requestCustomGrant( + config: CustomGrantConfig, + callback?: (response: BasicUserInfo | FetchResponse) => void, + ): void; + revokeAccessToken(): Promise; + getOIDCServiceEndpoints(): Promise; + getHttpClient(): Promise; + getDecodedIDPIDToken(): Promise; + getDecodedIDToken(): Promise; + getIDToken(): Promise; + getAccessToken(): Promise; + refreshAccessToken(): Promise; + isAuthenticated(): Promise; + enableHttpHandler(): Promise; + disableHttpHandler(): Promise; + updateConfig(config: Partial>): Promise; + trySignInSilently: ( + additionalParams?: Record, + tokenRequestConfig?: {params: Record}, + ) => Promise; + on(hook: Hooks.CustomGrant, callback: (response?: any) => void, id: string): void; + on(hook: Exclude, callback: (response?: any) => void): void; + on(hook: Hooks, callback: (response?: any) => void, id?: string): void; + state: AuthStateInterface; + error: AsgardeoAuthException; +} + +/** + * The model of the object returned by the `getAuthParams` prop method of the `AuthProvider`. + */ +export interface AuthParams { + authorizationCode?: string; + sessionState?: string; + state?: string; +} diff --git a/packages/react/src/__tests__/greet.test.tsx b/packages/react/src/__tests__/greet.test.tsx new file mode 100644 index 000000000..75aaf494d --- /dev/null +++ b/packages/react/src/__tests__/greet.test.tsx @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {describe, expect, test} from 'vitest'; +import {render} from 'vitest-browser-react'; +import Greet from '../Greet'; + +describe('Greet', () => { + test('should return the proper greeting', async () => { + const {getByText, getByRole} = render(); + + await expect.element(getByText('Hello World!')).toBeInTheDocument(); + }); +}); diff --git a/packages/react/src/api/scim2/getMeProfile.ts b/packages/react/src/api/scim2/getMeProfile.ts new file mode 100644 index 000000000..a0620ee31 --- /dev/null +++ b/packages/react/src/api/scim2/getMeProfile.ts @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {User, AsgardeoAPIError, HttpInstance, AsgardeoSPAClient, HttpRequestConfig} from '@asgardeo/browser'; + +const httpClient: HttpInstance = AsgardeoSPAClient.getInstance().httpRequest.bind(AsgardeoSPAClient.getInstance()); + +/** + * Retrieves the user profile information from the specified selfcare profile endpoint. + * + * @param requestConfig - Request configuration object. + * @returns A promise that resolves with the user profile information. + * @example + * ```typescript + * try { + * const userProfile = await getUserProfile({ + * url: "https://api.asgardeo.io/t//scim2/Me", + * }); + * console.log(userProfile); + * } catch (error) { + * if (error instanceof AsgardeoAPIError) { + * console.error('Failed to get user profile:', error.message); + * } + * } + * ``` + */ +const getMeProfile = async ({url, ...requestConfig}: Partial): Promise => { + try { + new URL(url); + } catch (error) { + throw new AsgardeoAPIError( + 'Invalid endpoint URL provided', + 'getMeProfile-ValidationError-001', + 'javascript', + 400, + 'Invalid Request', + ); + } + + const response: any = await httpClient({ + url, + method: 'GET', + headers: { + 'Content-Type': 'application/scim+json', + Accept: 'application/json', + }, + } as HttpRequestConfig); + + if (!response.data) { + const errorText = await response.text(); + + throw new AsgardeoAPIError( + `Failed to fetch user profile: ${errorText}`, + 'getMeProfile-ResponseError-001', + 'javascript', + response.status, + response.statusText, + ); + } + + return response.data; +}; + +export default getMeProfile; diff --git a/packages/react/src/api/scim2/getSchemas.ts b/packages/react/src/api/scim2/getSchemas.ts new file mode 100644 index 000000000..c419c86b0 --- /dev/null +++ b/packages/react/src/api/scim2/getSchemas.ts @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {Schema, AsgardeoAPIError, HttpInstance, AsgardeoSPAClient, HttpRequestConfig} from '@asgardeo/browser'; + +const httpClient: HttpInstance = AsgardeoSPAClient.getInstance().httpRequest.bind(AsgardeoSPAClient.getInstance()); + +/** + * Retrieves the SCIM2 schemas from the specified endpoint. + * + * @param requestConfig - Request configuration object. + * @returns A promise that resolves with the SCIM2 schemas information. + * @example + * ```typescript + * try { + * const schemas = await getSchemas({ + * url: "https://api.asgardeo.io/t//scim2/Schemas", + * }); + * console.log(schemas); + * } catch (error) { + * if (error instanceof AsgardeoAPIError) { + * console.error('Failed to get schemas:', error.message); + * } + * } + * ``` + */ +const getSchemas = async ({url}: Partial): Promise => { + try { + new URL(url); + } catch (error) { + throw new AsgardeoAPIError( + 'Invalid endpoint URL provided', + 'getSchemas-ValidationError-001', + 'javascript', + 400, + 'Invalid Request', + ); + } + + const response = await httpClient({ + url, + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json', + } + } as HttpRequestConfig); + + if (!response.data) { + throw new AsgardeoAPIError( + `Failed to fetch SCIM2 schemas`, + 'getSchemas-ResponseError-001', + 'javascript', + response.status, + response.statusText, + ); + } + + return response.data; +}; + +export default getSchemas; diff --git a/packages/react/src/api/scim2/updateMeProfile.ts b/packages/react/src/api/scim2/updateMeProfile.ts new file mode 100644 index 000000000..cdf297182 --- /dev/null +++ b/packages/react/src/api/scim2/updateMeProfile.ts @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {User, AsgardeoAPIError, HttpInstance, AsgardeoSPAClient, HttpRequestConfig} from '@asgardeo/browser'; + +const httpClient: HttpInstance = AsgardeoSPAClient.getInstance().httpRequest.bind(AsgardeoSPAClient.getInstance()); + +/** + * Updates the user profile information at the specified SCIM2 Me endpoint. + * + * @param url - The SCIM2 Me endpoint URL. + * @param value - The value object to patch (SCIM2 PATCH value). + * @param requestConfig - Additional request config if needed. + * @returns A promise that resolves with the updated user profile information. + * @example + * ```typescript + * await updateMeProfile({ + * url: "https://api.asgardeo.io/t//scim2/Me", + * value: { "urn:scim:wso2:schema": { mobileNumbers: ["0777933830"] } } + * }); + * ``` + */ +const updateMeProfile = async ({ + url, + payload, + ...requestConfig +}: {url: string; payload: any} & Partial): Promise => { + try { + new URL(url); + } catch (error) { + throw new AsgardeoAPIError( + 'Invalid endpoint URL provided', + 'updateMeProfile-ValidationError-001', + 'javascript', + 400, + 'Invalid Request', + ); + } + + const data = { + Operations: [ + { + op: 'replace', + value: payload, + }, + ], + schemas: ['urn:ietf:params:scim:api:messages:2.0:PatchOp'], + }; + + const response: any = await httpClient({ + url, + method: 'PATCH', + headers: { + 'Content-Type': 'application/scim+json', + Accept: 'application/json', + }, + data, + ...requestConfig, + } as HttpRequestConfig); + + if (!response.data) { + const errorText = await response.text(); + + throw new AsgardeoAPIError( + `Failed to update user profile: ${errorText}`, + 'updateMeProfile-ResponseError-001', + 'javascript', + response.status, + response.statusText, + ); + } + + return response.data; +}; + +export default updateMeProfile; diff --git a/packages/react/src/components/actions/SignInButton/BaseSignInButton.tsx b/packages/react/src/components/actions/SignInButton/BaseSignInButton.tsx new file mode 100644 index 000000000..c13decb08 --- /dev/null +++ b/packages/react/src/components/actions/SignInButton/BaseSignInButton.tsx @@ -0,0 +1,108 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + ButtonHTMLAttributes, + forwardRef, + ForwardRefExoticComponent, + ReactElement, + ReactNode, + Ref, + RefAttributes, +} from 'react'; +import {withVendorCSSClassPrefix} from '@asgardeo/browser'; +import clsx from 'clsx'; + +/** + * Common props shared by all {@link BaseSignInButton} components. + */ +export interface CommonBaseSignInButtonProps { + /** + * Function to initiate the sign-in process + */ + signIn?: () => Promise; + /** + * Loading state during sign-in process + */ + isLoading?: boolean; +} + +/** + * Props passed to the render function of {@link BaseSignInButton} + */ +export type BaseSignInButtonRenderProps = CommonBaseSignInButtonProps; + +/** + * Props interface of {@link BaseSignInButton} + */ +export interface BaseSignInButtonProps + extends CommonBaseSignInButtonProps, + Omit, 'children'> { + /** + * Render prop function that receives sign-in props, or traditional ReactNode children + */ + children?: ((props: BaseSignInButtonRenderProps) => ReactNode) | ReactNode; +} + +/** + * Base SignInButton component that supports both render props and traditional props patterns. + * + * @example Using render props + * ```tsx + * + * {({ signIn, isLoading }) => ( + * + * )} + * + * ``` + * + * @example Using traditional props + * ```tsx + * Sign In + * ``` + */ +const BaseSignInButton: ForwardRefExoticComponent> = + forwardRef( + ( + {children, className, style, signIn, isLoading, ...rest}: BaseSignInButtonProps, + ref: Ref, + ): ReactElement => { + if (typeof children === 'function') { + return <>{children({signIn, isLoading})}; + } + + return ( + + ); + }, + ); + +BaseSignInButton.displayName = 'BaseSignInButton'; + +export default BaseSignInButton; diff --git a/packages/react/src/components/actions/SignInButton/SignInButton.tsx b/packages/react/src/components/actions/SignInButton/SignInButton.tsx new file mode 100644 index 000000000..cec168072 --- /dev/null +++ b/packages/react/src/components/actions/SignInButton/SignInButton.tsx @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {forwardRef, ForwardRefExoticComponent, MouseEvent, ReactElement, Ref, RefAttributes, useState} from 'react'; +import useAsgardeo from '../../../hooks/useAsgardeo'; +import BaseSignInButton, {BaseSignInButtonProps} from './BaseSignInButton'; + +/** + * Props interface of {@link SignInButton} + */ +export type SignInButtonProps = BaseSignInButtonProps; + +/** + * SignInButton component that supports both render props and traditional props patterns. + * + * @remarks This component is only supported in browser based React applications (CSR). + * + * @example Using render props + * ```tsx + * + * {({ handleSignIn, isLoading }) => ( + * + * )} + * + * ``` + * + * @example Using traditional props + * ```tsx + * Sign In + * ``` + */ +const SignInButton: ForwardRefExoticComponent> = forwardRef< + HTMLButtonElement, + SignInButtonProps +>(({children = 'Sign In', onClick, ...rest}: SignInButtonProps, ref: Ref): ReactElement => { + const {signIn} = useAsgardeo(); + const [isLoading, setIsLoading] = useState(false); + + const handleSignIn = async (e?: MouseEvent): Promise => { + try { + setIsLoading(true); + + await signIn(); + + if (onClick) { + onClick(e); + } + } catch (error) { + throw new Error(`Sign in failed: ${error instanceof Error ? error.message : String(error)}`); + } finally { + setIsLoading(false); + } + }; + + return ( + + {children} + + ); +}); + +SignInButton.displayName = 'SignInButton'; + +export default SignInButton; diff --git a/packages/react/src/components/actions/SignOutButton/BaseSignOutButton.tsx b/packages/react/src/components/actions/SignOutButton/BaseSignOutButton.tsx new file mode 100644 index 000000000..5e59b0f3b --- /dev/null +++ b/packages/react/src/components/actions/SignOutButton/BaseSignOutButton.tsx @@ -0,0 +1,108 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + forwardRef, + ForwardRefExoticComponent, + ButtonHTMLAttributes, + ReactElement, + ReactNode, + Ref, + RefAttributes, +} from 'react'; +import {withVendorCSSClassPrefix} from '@asgardeo/browser'; +import clsx from 'clsx'; + +/** + * Common props shared by all {@link BaseSignOutButton} components. + */ +export interface CommonBaseSignOutButtonProps { + /** + * Function to initiate the sign-out process + */ + signOut?: () => Promise; + /** + * Loading state during sign-out process + */ + isLoading?: boolean; +} + +/** + * Props passed to the render function of {@link BaseSignOutButton} + */ +export type BaseSignOutButtonRenderProps = CommonBaseSignOutButtonProps; + +/** + * Props interface of {@link BaseSignOutButton} + */ +export interface BaseSignOutButtonProps + extends CommonBaseSignOutButtonProps, + Omit, 'children'> { + /** + * Render prop function that receives sign-out props, or traditional ReactNode children + */ + children?: ((props: BaseSignOutButtonRenderProps) => ReactNode) | ReactNode; +} + +/** + * Base SignOutButton component that supports both render props and traditional props patterns. + * + * @example Using render props + * ```tsx + * + * {({ signOut, isLoading }) => ( + * + * )} + * + * ``` + * + * @example Using traditional props + * ```tsx + * Sign Out + * ``` + */ +const BaseSignOutButton: ForwardRefExoticComponent> = + forwardRef( + ( + {children, className, style, signOut, isLoading, ...rest}: BaseSignOutButtonProps, + ref: Ref, + ): ReactElement => { + if (typeof children === 'function') { + return <>{children({signOut, isLoading})}; + } + + return ( + + ); + }, + ); + +BaseSignOutButton.displayName = 'BaseSignOutButton'; + +export default BaseSignOutButton; diff --git a/packages/react/src/components/actions/SignOutButton/SignOutButton.tsx b/packages/react/src/components/actions/SignOutButton/SignOutButton.tsx new file mode 100644 index 000000000..d9f476e1b --- /dev/null +++ b/packages/react/src/components/actions/SignOutButton/SignOutButton.tsx @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {FC, forwardRef, ForwardRefExoticComponent, MouseEvent, ReactElement, Ref, RefAttributes, useState} from 'react'; +import useAsgardeo from '../../../hooks/useAsgardeo'; +import BaseSignOutButton, {BaseSignOutButtonProps} from './BaseSignOutButton'; + +/** + * Props interface of {@link SignOutButton} + */ +export type SignOutButtonProps = BaseSignOutButtonProps; + +/** + * SignOutButton component that supports both render props and traditional props patterns. + * + * @example Using render props pattern + * ```tsx + * + * {({ signOut, isLoading }) => ( + * + * )} + * + * ``` + * + * @example Using traditional props pattern + * ```tsx + * Sign Out + * ``` + */ +const SignOutButton: ForwardRefExoticComponent> = forwardRef< + HTMLButtonElement, + SignOutButtonProps +>(({children = 'Sign Out', onClick, ...rest}: SignOutButtonProps, ref: Ref): ReactElement => { + const {signOut} = useAsgardeo(); + const [isLoading, setIsLoading] = useState(false); + + const handleSignOut = async (e?: MouseEvent): Promise => { + try { + setIsLoading(true); + await signOut(); + + if (onClick) { + onClick(e); + } + } catch (error) { + throw new Error(`Sign out failed: ${error instanceof Error ? error.message : String(error)}`); + } finally { + setIsLoading(false); + } + }; + + return ( + + {children} + + ); +}); + +SignOutButton.displayName = 'SignOutButton'; + +export default SignOutButton; diff --git a/packages/react/src/components/actions/SignUpButton/BaseSignUpButton.tsx b/packages/react/src/components/actions/SignUpButton/BaseSignUpButton.tsx new file mode 100644 index 000000000..256d75847 --- /dev/null +++ b/packages/react/src/components/actions/SignUpButton/BaseSignUpButton.tsx @@ -0,0 +1,108 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + forwardRef, + ForwardRefExoticComponent, + ButtonHTMLAttributes, + ReactElement, + ReactNode, + Ref, + RefAttributes, +} from 'react'; +import {withVendorCSSClassPrefix} from '@asgardeo/browser'; +import clsx from 'clsx'; + +/** + * Common props shared by all {@link BaseSignUpButton} components. + */ +export interface CommonBaseSignUpButtonProps { + /** + * Function to initiate the sign-up process + */ + signUp?: () => Promise; + /** + * Loading state during sign-up process + */ + isLoading?: boolean; +} + +/** + * Props passed to the render function of {@link BaseSignUpButton} + */ +export type BaseSignUpButtonRenderProps = CommonBaseSignUpButtonProps; + +/** + * Props interface of {@link BaseSignUpButton} + */ +export interface BaseSignUpButtonProps + extends CommonBaseSignUpButtonProps, + Omit, 'children'> { + /** + * Render prop function that receives sign-up props, or traditional ReactNode children + */ + children?: ((props: BaseSignUpButtonRenderProps) => ReactNode) | ReactNode; +} + +/** + * Base SignUpButton component that supports both render props and traditional props patterns. + * + * @example Using render props + * ```tsx + * + * {({ signUp, isLoading }) => ( + * + * )} + * + * ``` + * + * @example Using traditional props + * ```tsx + * Create Account + * ``` + */ +const BaseSignUpButton: ForwardRefExoticComponent> = + forwardRef( + ( + {children, className, style, signUp, isLoading, ...rest}: BaseSignUpButtonProps, + ref: Ref, + ): ReactElement => { + if (typeof children === 'function') { + return <>{children({signUp, isLoading})}; + } + + return ( + + ); + }, + ); + +BaseSignUpButton.displayName = 'BaseSignUpButton'; + +export default BaseSignUpButton; diff --git a/packages/react/src/components/actions/SignUpButton/SignUpButton.tsx b/packages/react/src/components/actions/SignUpButton/SignUpButton.tsx new file mode 100644 index 000000000..5521e9e98 --- /dev/null +++ b/packages/react/src/components/actions/SignUpButton/SignUpButton.tsx @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {FC, forwardRef, ForwardRefExoticComponent, MouseEvent, ReactElement, Ref, RefAttributes, useState} from 'react'; +import useAsgardeo from '../../../hooks/useAsgardeo'; +import BaseSignUpButton, {BaseSignUpButtonProps} from './BaseSignUpButton'; + +/** + * Props interface of {@link SignUpButton} + */ +export type SignUpButtonProps = BaseSignUpButtonProps; + +/** + * SignUpButton component that supports both render props and traditional props patterns. + * It redirects the user to the Asgardeo sign-up page configured for the application. + * + * @example Using render props pattern + * ```tsx + * + * {({ signUp, isLoading }) => ( + * + * )} + * + * ``` + * + * @example Using traditional props pattern + * ```tsx + * Create Account + * ``` + */ +const SignUpButton: ForwardRefExoticComponent> = forwardRef< + HTMLButtonElement, + SignUpButtonProps +>(({children = 'Sign Up', onClick, ...rest}: SignUpButtonProps, ref: Ref): ReactElement => { + const {signUp} = useAsgardeo(); + const [isLoading, setIsLoading] = useState(false); + + const handleSignUp = async (e?: MouseEvent): Promise => { + try { + setIsLoading(true); + await signUp(); + + if (onClick) { + onClick(e); + } + } catch (error) { + throw new Error(`Sign up failed: ${error instanceof Error ? error.message : String(error)}`); + } finally { + setIsLoading(false); + } + }; + + return ( + + {children} + + ); +}); + +SignUpButton.displayName = 'SignUpButton'; + +export default SignUpButton; diff --git a/packages/react/src/components/control/SignedIn.tsx b/packages/react/src/components/control/SignedIn.tsx new file mode 100644 index 000000000..eeeb462f7 --- /dev/null +++ b/packages/react/src/components/control/SignedIn.tsx @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {FC, PropsWithChildren, ReactNode} from 'react'; +import useAsgardeo from '../../hooks/useAsgardeo'; + +/** + * Props for the SignedIn component. + */ +export interface SignedInProps { + /** + * Content to show when the user is not signed in. + */ + fallback?: ReactNode; +} + +/** + * A component that only renders its children when the user is signed in. + * + * @example + * ```tsx + * import { SignedIn } from '@asgardeo/auth-react'; + * + * const App = () => { + * return ( + * Please sign in to continue

}> + *

Welcome! You are signed in.

+ *
+ * ); + * } + * ``` + */ +const SignedIn: FC> = ({ + children, + fallback = null, +}: PropsWithChildren) => { + const {isSignedIn} = useAsgardeo(); + + if (!isSignedIn) { + return <>{fallback}; + } + + return <>{children}; +}; + +SignedIn.displayName = 'SignedIn'; + +export default SignedIn; diff --git a/packages/react/src/components/control/SignedOut.tsx b/packages/react/src/components/control/SignedOut.tsx new file mode 100644 index 000000000..b5b946052 --- /dev/null +++ b/packages/react/src/components/control/SignedOut.tsx @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {FC, PropsWithChildren, ReactNode} from 'react'; +import useAsgardeo from '../../hooks/useAsgardeo'; + +/** + * Props for the SignedOut component. + */ +export interface SignedOutProps { + /** + * Content to show when the user is signed in. + */ + fallback?: ReactNode; +} + +/** + * A component that only renders its children when the user is signed out. + * + * @example + * ```tsx + * import { SignedOut } from '@asgardeo/auth-react'; + * + * const App = () => { + * return ( + * You are already signed in

}> + *

Please sign in to continue

+ *
+ * ); + * } + * ``` + */ +const SignedOut: FC> = ({ + children, + fallback = null, +}: PropsWithChildren) => { + const {isSignedIn} = useAsgardeo(); + + if (!isSignedIn) { + return <>{children}; + } + + return <>{fallback}; +}; + +SignedOut.displayName = 'SignedOut'; + +export default SignedOut; diff --git a/packages/react/src/components/presentation/User.tsx b/packages/react/src/components/presentation/User.tsx new file mode 100644 index 000000000..f04dbcad6 --- /dev/null +++ b/packages/react/src/components/presentation/User.tsx @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {User as AsgardeoUser} from '@asgardeo/browser'; +import {FC, ReactElement, ReactNode} from 'react'; +import useAsgardeo from '../../hooks/useAsgardeo'; + +/** + * Props for the User component. + */ +export interface UserProps { + /** + * Render prop that takes the user object and returns a ReactNode. + * @param user - The authenticated user object from Asgardeo. + * @returns A ReactNode to render. + */ + children: (user: AsgardeoUser | null) => ReactNode; + + /** + * Optional element to render when no user is signed in. + */ + fallback?: ReactNode; +} + +/** + * A component that uses render props to expose the authenticated user object. + * + * @example + * ```tsx + * import { User } from '@asgardeo/auth-react'; + * + * const App = () => { + * return ( + * Please sign in

}> + * {(user) => ( + *
+ *

Welcome, {user.displayName}!

+ *

Email: {user.email}

+ *
+ * )} + *
+ * ); + * } + * ``` + */ +const User: FC = ({children, fallback = null}): ReactElement => { + const {user} = useAsgardeo(); + + if (!user) { + return <>{fallback}; + } + + return <>{children(user)}; +}; + +User.displayName = 'User'; + +export default User; diff --git a/packages/react/src/components/presentation/UserDropdown/BaseUserDropdown.tsx b/packages/react/src/components/presentation/UserDropdown/BaseUserDropdown.tsx new file mode 100644 index 000000000..299f37d7f --- /dev/null +++ b/packages/react/src/components/presentation/UserDropdown/BaseUserDropdown.tsx @@ -0,0 +1,286 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {CSSProperties, FC, ReactElement, ReactNode, useMemo, useState} from 'react'; +import {withVendorCSSClassPrefix} from '@asgardeo/browser'; +import clsx from 'clsx'; +import {useTheme} from '../../../theme/useTheme'; +import {Avatar} from '../../primitives/Avatar/Avatar'; +import {Popover} from '../../primitives/Popover/Popover'; +import getMappedUserProfileValue from '../../../utils/getMappedUserProfileValue'; + +const useStyles = () => { + const {theme} = useTheme(); + + return useMemo( + () => ({ + trigger: { + display: 'inline-flex', + alignItems: 'center', + gap: theme.spacing.unit + 'px', + padding: theme.spacing.unit * 0.5 + 'px', + border: 'none', + background: 'none', + cursor: 'pointer', + borderRadius: theme.borderRadius.small, + '&:hover': { + backgroundColor: theme.colors.background, + }, + } as CSSProperties, + userName: { + color: theme.colors.text.primary, + fontSize: '1rem', + fontWeight: 500, + } as CSSProperties, + dropdownContent: { + minWidth: '200px', + maxWidth: '300px', + } as CSSProperties, + dropdownMenu: { + display: 'flex', + flexDirection: 'column', + width: '100%', + } as CSSProperties, + menuItem: { + display: 'flex', + alignItems: 'center', + gap: theme.spacing.unit + 'px', + padding: `${theme.spacing.unit * 2}px ${theme.spacing.unit * 2}px`, + width: '100%', + color: theme.colors.text.primary, + textDecoration: 'none', + border: 'none', + background: 'none', + cursor: 'pointer', + fontSize: '0.875rem', + '&:hover': { + backgroundColor: theme.colors.background, + }, + } as CSSProperties, + divider: { + margin: `${theme.spacing.unit * 0.5}px 0`, + borderBottom: `1px solid ${theme.colors.border}`, + } as CSSProperties, + dropdownHeader: { + display: 'flex', + alignItems: 'center', + gap: theme.spacing.unit + 'px', + padding: `${theme.spacing.unit * 1.5}px`, + borderBottom: `1px solid ${theme.colors.border}`, + } as CSSProperties, + headerInfo: { + display: 'flex', + flexDirection: 'column', + gap: theme.spacing.unit / 2 + 'px', + } as CSSProperties, + headerName: { + color: theme.colors.text.primary, + fontSize: '1rem', + fontWeight: 500, + margin: 0, + } as CSSProperties, + headerEmail: { + color: theme.colors.text.secondary, + fontSize: '0.875rem', + margin: 0, + } as CSSProperties, + }), + [theme], + ); +}; + +export interface MenuItem { + label: string; + icon?: ReactNode; + onClick?: () => void; + href?: string; +} + +export interface BaseUserDropdownProps { + /** + * Optional element to render when no user is signed in. + */ + fallback?: ReactElement; + /** + * Optional className for the dropdown container. + */ + className?: string; + /** + * The user object containing profile information + */ + user: any; + /** + * The HTML element ID where the portal should be mounted + */ + portalId?: string; + /** + * Menu items to display in the dropdown + */ + menuItems?: MenuItem[]; + /** + * Show user's display name next to avatar in the trigger button + */ + showTriggerLable?: boolean; + /** + * Show dropdown header with user information + */ + showDropdownHeader?: boolean; + /** + * Optional size for the avatar + */ + avatarSize?: number; + /** + * Mapping of component attribute names to identity provider field names. + * Allows customizing which user profile fields should be used for each attribute. + */ + attributeMapping?: { + picture?: string | string[]; + firstName?: string | string[]; + lastName?: string | string[]; + username?: string | string[]; + [key: string]: string | string[] | undefined; + }; +} + +/** + * BaseUserDropdown component displays a user avatar with a dropdown menu. + * When clicked, it shows a popover with customizable menu items. + * This component serves as the base for framework-specific implementations. + */ +export const BaseUserDropdown: FC = ({ + fallback =
Please sign in
, + className = '', + user, + portalId = 'asgardeo-user-dropdown', + menuItems = [], + showTriggerLable = false, + showDropdownHeader = true, + avatarSize = 32, + attributeMapping = {}, +}): ReactElement => { + const styles = useStyles(); + const [isOpen, setIsOpen] = useState(false); + + const defaultAttributeMappings = { + picture: ['profile', 'profileUrl'], + firstName: 'givenName', + lastName: 'familyName', + email: 'emails', + }; + + const mergedMappings = {...defaultAttributeMappings, ...attributeMapping}; + + const getDisplayName = () => { + const firstName = getMappedUserProfileValue('firstName', mergedMappings, user); + const lastName = getMappedUserProfileValue('lastName', mergedMappings, user); + + if (firstName && lastName) { + return `${firstName} ${lastName}`; + } + + return getMappedUserProfileValue('username', mergedMappings, user) || ''; + }; + + if (!user) { + return fallback; + } + + const handleMenuItemClick = (item: MenuItem) => { + if (item.onClick) { + item.onClick(); + } + setIsOpen(false); + }; + + return ( +
+ + + setIsOpen(false)} portalId={portalId} mode="dropdown"> + +
+ {showDropdownHeader && ( +
+ +
+ + {getDisplayName()} + + {getMappedUserProfileValue('email', mergedMappings, user) !== getDisplayName() && + getMappedUserProfileValue('email', mergedMappings, user) && ( + + {getMappedUserProfileValue('email', mergedMappings, user)} + + )} +
+
+ )} +
+ {menuItems.map((item, index) => ( +
+ {item.href ? ( + + {item.icon} + {item.label} + + ) : ( + + )} + {index < menuItems.length - 1 &&
} +
+ ))} +
+
+ + +
+ ); +}; + +export default BaseUserDropdown; diff --git a/packages/react/src/components/presentation/UserDropdown/UserDropdown.tsx b/packages/react/src/components/presentation/UserDropdown/UserDropdown.tsx new file mode 100644 index 000000000..e6c8c7cf2 --- /dev/null +++ b/packages/react/src/components/presentation/UserDropdown/UserDropdown.tsx @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {FC, ReactElement} from 'react'; +import useAsgardeo from '../../../hooks/useAsgardeo'; +import BaseUserDropdown, {BaseUserDropdownProps} from './BaseUserDropdown'; + +/** + * Props for the UserDropdown component. + * Extends BaseUserDropdownProps but makes the user prop optional since it will be obtained from useAsgardeo + */ +export type UserDropdownProps = Omit; + +/** + * UserDropdown component displays a user avatar with a dropdown menu. + * When clicked, it shows a popover with customizable menu items. + * This component is the React-specific implementation that uses the BaseUserDropdown + * and automatically retrieves the user data from Asgardeo context. + * + * @example + * ```tsx + * // Basic usage - will use user from Asgardeo context + * {} }, + * { label: 'Settings', href: '/settings' }, + * { label: 'Sign Out', onClick: () => {} } + * ]} /> + * + * // With custom configuration + * Please sign in
} + * /> + * ``` + */ +const UserDropdown: FC = ({...rest}: UserDropdownProps): ReactElement => { + const {user} = useAsgardeo(); + + return ; +}; + +export default UserDropdown; diff --git a/packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx b/packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx new file mode 100644 index 000000000..8732ba5ce --- /dev/null +++ b/packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx @@ -0,0 +1,536 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {CSSProperties, FC, ReactElement, useMemo, useState, useCallback} from 'react'; +import {Popover} from '../../primitives/Popover/Popover'; +import {Avatar} from '../../primitives/Avatar/Avatar'; +import {TextField} from '../../primitives/TextField/TextField'; +import {DatePicker} from '../../primitives/DatePicker/DatePicker'; +import {Checkbox} from '../../primitives/Checkbox/Checkbox'; +import {useTheme} from '../../../theme/useTheme'; +import {withVendorCSSClassPrefix} from '@asgardeo/browser'; +import clsx from 'clsx'; +import getMappedUserProfileValue from '../../../utils/getMappedUserProfileValue'; + +interface ExtendedFlatSchema { + schemaId?: string; + path?: string; +} + +interface Schema extends ExtendedFlatSchema { + caseExact?: boolean; + description?: string; + displayName?: string; + multiValued?: boolean; + mutability?: string; + name?: string; + required?: boolean; + returned?: string; + type?: string; + uniqueness?: string; + value?: any; + subAttributes?: Schema[]; +} + +export interface BaseUserProfileProps { + fallback?: ReactElement; + className?: string; + cardLayout?: boolean; + user: any; + mode?: 'inline' | 'popup'; + portalId?: string; + title?: string; + attributeMapping?: { + picture?: string | string[]; + firstName?: string | string[]; + lastName?: string | string[]; + username?: string | string[]; + [key: string]: string | string[] | undefined; + }; + editable?: boolean; + onChange?: (field: string, value: any) => void; + onSubmit?: (data: any) => void; + saveButtonText?: string; + cancelButtonText?: string; + onUpdate?: (payload: any) => Promise; +} + +const BaseUserProfile: FC = ({ + fallback =
Please sign in to view your profile
, + className = '', + cardLayout = true, + user, + mode = 'inline', + portalId = 'asgardeo-user-profile', + title = 'User Profile', + attributeMapping = {}, + editable = true, + onChange, + onSubmit, + onUpdate, + saveButtonText = 'Save Changes', + cancelButtonText = 'Cancel', +}): ReactElement => { + const {theme} = useTheme(); + const [isOpen, setIsOpen] = useState(mode === 'popup'); + const [editedUser, setEditedUser] = useState(user); + const [editingFields, setEditingFields] = useState>({}); + + const PencilIcon = () => ( + + + + ); + + const toggleFieldEdit = useCallback((fieldName: string) => { + setEditingFields(prev => ({ + ...prev, + [fieldName]: !prev[fieldName], + })); + }, []); + + function set(obj: Record, path: string, value: any): void { + const keys = path.split('.'); + let current = obj; + + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + + // If last key, set the value + if (i === keys.length - 1) { + current[key] = value; + } else { + // If the next level does not exist or is not an object, create an object + if (!current[key] || typeof current[key] !== 'object') { + current[key] = {}; + } + current = current[key]; + } + } + } + + const handleFieldSave = useCallback( + (schema: Schema) => { + let payload = {}; + const fieldName = schema.name; + const fieldValue = + editedUser && fieldName && editedUser[fieldName] !== undefined ? editedUser[fieldName] : schema.value; + + set(payload, schema.path, fieldValue); + + onUpdate(payload); + // Optionally, exit edit mode for this field after save + toggleFieldEdit(fieldName!); + }, + [editedUser, onUpdate, toggleFieldEdit], + ); + + const handleFieldCancel = useCallback( + (fieldName: string) => { + setEditedUser(prev => ({ + ...prev, + [fieldName]: user[fieldName], + })); + toggleFieldEdit(fieldName); + }, + [user, toggleFieldEdit], + ); + + const formatLabel = useCallback((key: string): string => { + return key + .split(/(?=[A-Z])|_/) + .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) + .join(' '); + }, []); + + const styles = useStyles(); + const buttonStyle = useMemo( + () => ({ + padding: `${theme.spacing.unit}px ${theme.spacing.unit * 2}px`, + margin: `${theme.spacing.unit}px`, + borderRadius: theme.borderRadius.small, + border: 'none', + cursor: 'pointer', + fontSize: '0.875rem', + fontWeight: 500, + }), + [theme], + ); + + const saveButtonStyle = useMemo( + () => ({ + ...buttonStyle, + backgroundColor: theme.colors.primary.main, + color: theme.colors.primary.contrastText, + }), + [theme, buttonStyle], + ); + + const cancelButtonStyle = useMemo( + () => ({ + ...buttonStyle, + backgroundColor: theme.colors.secondary.main, + border: `1px solid ${theme.colors.border}`, + }), + [theme, buttonStyle], + ); + + const defaultAttributeMappings = { + picture: ['profile', 'profileUrl'], + firstName: 'givenName', + lastName: 'familyName', + }; + + const mergedMappings = {...defaultAttributeMappings, ...attributeMapping}; + + // Combines label and value/field rendering for both view and edit modes + const renderSchemaField = ( + schema: Schema, + isEditing: boolean, + onEditValue?: (value: any) => void, + ): ReactElement | null => { + if (!schema) return null; + const {value, displayName, description, name, type, required, mutability, subAttributes} = schema; + const label = displayName || description || name || ''; + + // If complex or subAttributes, fallback to original renderSchemaValue + if (subAttributes && Array.isArray(subAttributes)) { + return ( + <> + {subAttributes.map((subAttr, index) => ( +
+ {subAttr.displayName || subAttr.description || ''} +
+ {Array.isArray(subAttr.value) + ? subAttr.value + .map(item => (typeof item === 'object' ? JSON.stringify(item) : String(item))) + .join(', ') + : typeof subAttr.value === 'object' + ? JSON.stringify(subAttr.value) + : String(subAttr.value)} +
+
+ ))} + + ); + } + if (Array.isArray(value)) { + const displayValue = value + .map(item => (typeof item === 'object' ? JSON.stringify(item) : String(item))) + .join(', '); + return ( + <> + {label} +
{displayValue}
+ + ); + } + if (type === 'COMPLEX' && typeof value === 'object') { + return ; + } + // If editing, show field instead of value + if (isEditing && onEditValue && mutability !== 'READ_ONLY') { + // Use editedUser value if available + const fieldValue = editedUser && name && editedUser[name] !== undefined ? editedUser[name] : value || ''; + const commonProps = { + label: undefined, // Don't show label in field, we render it outside + required: required, + value: fieldValue, + onChange: (e: any) => onEditValue(e.target ? e.target.value : e), + style: { + marginBottom: 0, + }, + }; + let field: ReactElement; + switch (type) { + case 'STRING': + field = ; + break; + case 'DATE_TIME': + field = ; + break; + case 'BOOLEAN': + field = onEditValue(e.target.checked)} />; + break; + case 'COMPLEX': + field = ; + break; + default: + field = ; + } + return ( + <> + {label} +
{field}
+ + ); + } + // Default: view mode + return ( + <> + {label} +
{String(value)}
+ + ); + }; + + const renderUserInfo = (schema: Schema) => { + if (!schema || !schema.name) return null; + + const isFieldEditing = editingFields[schema.name]; + const fieldStyle = { + ...styles.field, + display: 'flex', + alignItems: 'center', + gap: theme.spacing.unit + 'px', + }; + const actionButtonStyle = { + ...buttonStyle, + padding: `${theme.spacing.unit / 2}px ${theme.spacing.unit}px`, + fontSize: '0.75rem', + marginLeft: 'auto', + }; + + return ( +
+
+ {renderSchemaField(schema, isFieldEditing, value => { + const tempEditedUser = {...editedUser}; + tempEditedUser[schema.name!] = value; + setEditedUser(tempEditedUser); + })} +
+ {editable && schema.mutability !== 'READ_ONLY' && ( +
+ {isFieldEditing ? ( + <> + + + + ) : ( + + )} +
+ )} +
+ ); + }; + + const ObjectDisplay: FC<{data: unknown}> = ({data}) => { + if (!data || typeof data !== 'object') return null; + + return ( + + + {Object.entries(data).map(([key, value]) => ( + + + + + ))} + +
+ {formatLabel(key)}: + + {typeof value === 'object' ? : String(value)} +
+ ); + }; + + const getDisplayName = () => { + const firstName = getMappedUserProfileValue('firstName', mergedMappings, user); + const lastName = getMappedUserProfileValue('lastName', mergedMappings, user); + + if (firstName && lastName) { + return `${firstName} ${lastName}`; + } + + return getMappedUserProfileValue('username', mergedMappings, user) || ''; + }; + + if (!user) { + return fallback; + } + + const containerStyle = { + ...styles.root, + ...(cardLayout ? styles.card : {}), + }; + + const avatarAttributes = ['picture']; + const excludedProps = avatarAttributes.map(attr => mergedMappings[attr] || attr); + + const profileContent = ( +
+
+ +
+
+ {Array.isArray(user) + ? user + .filter(schema => !excludedProps.includes(schema.name) && schema.value) + .map((schema, index) =>
{renderUserInfo(schema)}
) + : Object.entries(user) + .filter(([key]) => !excludedProps.includes(key) && user[key]) + .map(([key, value]) => + renderUserInfo({ + name: key, + value: value, + displayName: formatLabel(key), + }), + )} +
+
+ ); + + if (mode === 'popup') { + return ( + setIsOpen(false)} portalId={portalId}> + {title} + {profileContent} + + ); + } + + return profileContent; +}; + +const useStyles = () => { + const {theme, colorScheme} = useTheme(); + + return useMemo( + () => ({ + root: { + padding: theme.spacing.unit * 4 + 'px', + minWidth: '600px', + margin: '0 auto', + } as CSSProperties, + card: { + background: theme.colors.surface, + borderRadius: theme.borderRadius.large, + } as CSSProperties, + header: { + display: 'flex', + alignItems: 'center', + gap: theme.spacing.unit * 1.5 + 'px', + marginBottom: theme.spacing.unit * 1.5 + 'px', + } as CSSProperties, + profileInfo: { + flex: 1, + } as CSSProperties, + name: { + fontSize: '1.5rem', + fontWeight: 600, + margin: '0', + color: theme.colors.text.primary, + } as CSSProperties, + infoContainer: { + display: 'flex', + flexDirection: 'column' as const, + gap: theme.spacing.unit + 'px', + } as CSSProperties, + field: { + display: 'flex', + alignItems: 'center', + padding: theme.spacing.unit + 'px 0', + borderBottom: `1px solid ${theme.colors.border}`, + minHeight: '32px', + } as CSSProperties, + lastField: { + borderBottom: 'none', + } as CSSProperties, + label: { + fontSize: '0.875rem', + fontWeight: 500, + color: theme.colors.text.secondary, + width: '120px', + flexShrink: 0, + lineHeight: '32px', + } as CSSProperties, + value: { + color: theme.colors.text.primary, + flex: 1, + display: 'flex', + alignItems: 'center', + gap: theme.spacing.unit + 'px', + overflow: 'hidden', + minHeight: '32px', + '& input, & .MuiInputBase-root': { + height: '32px', + margin: 0, + }, + lineHeight: '32px', + '& table': { + backgroundColor: theme.colors.background, + borderRadius: theme.borderRadius.small, + whiteSpace: 'normal', + }, + '& td': { + borderColor: theme.colors.border, + }, + } as CSSProperties, + popup: { + padding: theme.spacing.unit * 2 + 'px', + } as CSSProperties, + }), + [theme, colorScheme], + ); +}; + +export default BaseUserProfile; diff --git a/packages/react/src/components/presentation/UserProfile/UserProfile.tsx b/packages/react/src/components/presentation/UserProfile/UserProfile.tsx new file mode 100644 index 000000000..e795d87f7 --- /dev/null +++ b/packages/react/src/components/presentation/UserProfile/UserProfile.tsx @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {FC, ReactElement} from 'react'; +import useAsgardeo from '../../../hooks/useAsgardeo'; +import BaseUserProfile, {BaseUserProfileProps} from './BaseUserProfile'; +import updateMeProfile from 'packages/react/src/api/scim2/updateMeProfile'; +import getMeProfile from 'packages/react/src/api/scim2/getMeProfile'; + +/** + * Props for the UserProfile component. + * Extends BaseUserProfileProps but makes the user prop optional since it will be obtained from useAsgardeo + */ +export type UserProfileProps = Omit; + +/** + * UserProfile component displays the authenticated user's profile information in a + * structured and styled format. It shows user details such as display name, email, + * username, and other available profile information from Asgardeo. + * + * This component is the React-specific implementation that uses the BaseUserProfile + * and automatically retrieves the user data from Asgardeo context if not provided. + * + * @example + * ```tsx + * // Basic usage - will use user from Asgardeo context + * + * + * // With explicit user data + * + * + * // With card layout and custom fallback + * Please sign in to view your profile
} + * /> + * ``` + */ +const UserProfile: FC = ({...rest}: UserProfileProps): ReactElement => { + const {user, baseUrl} = useAsgardeo(); + + const handleProfileUpdate = async (payload: any): Promise => { + await updateMeProfile({url: `${baseUrl}/scim2/Me`, payload}); + await getMeProfile({url: `${baseUrl}/scim2/Me` }); + }; + + return ; +}; + +export default UserProfile; diff --git a/packages/react/src/components/primitives/Avatar/Avatar.tsx b/packages/react/src/components/primitives/Avatar/Avatar.tsx new file mode 100644 index 000000000..778fe849f --- /dev/null +++ b/packages/react/src/components/primitives/Avatar/Avatar.tsx @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {CSSProperties, FC, useMemo} from 'react'; +import {useTheme} from '../../../theme/useTheme'; +import {withVendorCSSClassPrefix} from '@asgardeo/browser'; +import clsx from 'clsx'; + +export interface AvatarProps { + /** + * The URL of the avatar image + */ + imageUrl?: string; + /** + * Alternative text for the avatar image + */ + alt?: string; + /** + * The size of the avatar in pixels + */ + size?: number; + /** + * The name to use for generating initials when no image is provided + */ + name?: string; + /** + * Optional className for the avatar + */ + className?: string; +} + +const useStyles = ({size}) => { + const {theme, colorScheme} = useTheme(); + + return useMemo( + () => ({ + avatar: { + width: `${size}px`, + height: `${size}px`, + borderRadius: '50%', + overflow: 'hidden', + backgroundColor: theme.colors.surface, + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + fontSize: `${size * 0.4}px`, + fontWeight: 500, + color: theme.colors.text.primary, + border: `1px solid ${theme.colors.border}`, + boxShadow: colorScheme === 'dark' ? 'none' : '0 2px 4px rgba(0, 0, 0, 0.1)', + } as CSSProperties, + image: { + width: '100%', + height: '100%', + objectFit: 'cover', + } as CSSProperties, + }), + [size, theme, colorScheme], + ); +}; + +export const Avatar: FC = ({imageUrl, alt = 'User avatar', size = 64, name, className = ''}) => { + const styles = useStyles({size}); + + const getInitials = (name: string): string => { + return name + .split(' ') + .map(part => part[0]) + .slice(0, 2) + .join('') + .toUpperCase(); + }; + + return ( +
+ {imageUrl ? {alt} : name ? getInitials(name) : '?'} +
+ ); +}; + +export default Avatar; diff --git a/packages/react/src/components/primitives/Checkbox/Checkbox.tsx b/packages/react/src/components/primitives/Checkbox/Checkbox.tsx new file mode 100644 index 000000000..150e6b40b --- /dev/null +++ b/packages/react/src/components/primitives/Checkbox/Checkbox.tsx @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {CSSProperties, FC, InputHTMLAttributes} from 'react'; +import {useTheme} from '../../../theme/useTheme'; +import clsx from 'clsx'; + +export interface CheckboxProps extends Omit, 'className' | 'type'> { + /** + * Label text to display next to the checkbox + */ + label?: string; + /** + * Error message to display below the checkbox + */ + error?: string; + /** + * Additional CSS class names + */ + className?: string; + /** + * Whether the field is required + */ + required?: boolean; + /** + * Helper text to display below the checkbox + */ + helperText?: string; +} + +export const Checkbox: FC = ({label, error, className, required, helperText, style = {}, ...rest}) => { + const {theme} = useTheme(); + + const containerStyle: CSSProperties = { + marginBottom: theme.spacing.unit * 2 + 'px', + display: 'flex', + alignItems: 'center', + ...style + }; + + const inputStyle: CSSProperties = { + width: theme.spacing.unit * 2.5 + 'px', + height: theme.spacing.unit * 2.5 + 'px', + marginRight: theme.spacing.unit + 'px', + accentColor: theme.colors.primary.main, + }; + + const labelStyle: CSSProperties = { + color: error ? theme.colors.error.main : theme.colors.text.primary, + fontSize: '0.875rem', + }; + + const helperTextStyle: CSSProperties = { + fontSize: '0.75rem', + color: error ? theme.colors.error.main : theme.colors.text.secondary, + marginTop: theme.spacing.unit / 2 + 'px', + marginLeft: theme.spacing.unit * 3.5 + 'px', + }; + + return ( +
+
+ + {label && ( + + )} +
+ {(error || helperText) &&
{error || helperText}
} +
+ ); +}; + +export default Checkbox; diff --git a/packages/react/src/components/primitives/DatePicker/DatePicker.tsx b/packages/react/src/components/primitives/DatePicker/DatePicker.tsx new file mode 100644 index 000000000..e2dfbde87 --- /dev/null +++ b/packages/react/src/components/primitives/DatePicker/DatePicker.tsx @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {CSSProperties, FC, InputHTMLAttributes} from 'react'; +import {useTheme} from '../../../theme/useTheme'; +import clsx from 'clsx'; + +export interface DatePickerProps extends Omit, 'className' | 'type'> { + /** + * Label text to display above the input + */ + label?: string; + /** + * Error message to display below the input + */ + error?: string; + /** + * Additional CSS class names + */ + className?: string; + /** + * Whether the field is required + */ + required?: boolean; + /** + * Whether the field is disabled + */ + disabled?: boolean; + /** + * Helper text to display below the input + */ + helperText?: string; + /** + * Custom date format for the regex pattern + */ + dateFormat?: string; +} + +export const DatePicker: FC = ({ + label, + error, + className, + required, + disabled, + helperText, + dateFormat = 'yyyy-MM-dd', + style = {}, + ...rest +}) => { + const {theme} = useTheme(); + + const containerStyle: CSSProperties = { + marginBottom: theme.spacing.unit * 2 + 'px', + ...style + }; + + const labelStyle: CSSProperties = { + display: 'block', + marginBottom: theme.spacing.unit + 'px', + color: error ? theme.colors.error.main : theme.colors.text.secondary, + fontSize: '0.875rem', + fontWeight: 500, + }; + + const inputStyle: CSSProperties = { + width: '100%', + padding: `${theme.spacing.unit}px ${theme.spacing.unit * 1.5}px`, + border: `1px solid ${error ? theme.colors.error.main : theme.colors.border}`, + borderRadius: theme.borderRadius.small, + fontSize: '1rem', + color: theme.colors.text.primary, + backgroundColor: disabled ? theme.colors.background.disabled : theme.colors.background.surface, + outline: 'none', + transition: 'border-color 0.2s ease', + }; + + const helperTextStyle: CSSProperties = { + fontSize: '0.75rem', + color: error ? theme.colors.error.main : theme.colors.text.secondary, + marginTop: theme.spacing.unit / 2 + 'px', + }; + + return ( +
+ {label && ( + + )} + + {(error || helperText) &&
{error || helperText}
} +
+ ); +}; + +export default DatePicker; diff --git a/packages/react/src/components/primitives/Popover/Popover.tsx b/packages/react/src/components/primitives/Popover/Popover.tsx new file mode 100644 index 000000000..d29c63164 --- /dev/null +++ b/packages/react/src/components/primitives/Popover/Popover.tsx @@ -0,0 +1,204 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, {CSSProperties, FC, ReactNode, useEffect, useMemo, useState} from 'react'; +import {createPortal} from 'react-dom'; +import {useTheme} from '../../../theme/useTheme'; +import {withVendorCSSClassPrefix} from '@asgardeo/browser'; +import clsx from 'clsx'; + +const useStyles = () => { + const {theme, colorScheme} = useTheme(); + + return useMemo( + () => ({ + overlay: { + position: 'fixed', + top: 0, + left: 0, + right: 0, + bottom: 0, + backgroundColor: 'rgba(0, 0, 0, 0.5)', + zIndex: 999, + } as CSSProperties, + content: { + position: 'fixed', + top: '50%', + left: '50%', + transform: 'translate(-50%, -50%)', + zIndex: 1000, + maxHeight: '90vh', + overflowY: 'auto', + background: theme.colors.surface, + borderRadius: theme.borderRadius.large, + boxShadow: `0 2px 8px ${colorScheme === 'dark' ? 'rgba(0, 0, 0, 0.3)' : 'rgba(0, 0, 0, 0.15)'}`, + } as CSSProperties, + contentBody: {} as CSSProperties, + header: { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + padding: `${theme.spacing.unit * 3}px ${theme.spacing.unit * 4.5}px`, + borderBottom: `1px solid ${theme.colors.border}`, + } as CSSProperties, + headerTitle: { + margin: 0, + fontSize: '1.2rem', + fontWeight: 600, + color: theme.colors.text.primary, + } as CSSProperties, + closeButton: { + background: 'none', + border: 'none', + cursor: 'pointer', + padding: theme.spacing.unit / 2 + 'px', + color: theme.colors.text.secondary, + fontSize: '1.2rem', + '&:hover': { + color: theme.colors.text.primary, + }, + } as CSSProperties, + }), + [theme, colorScheme], + ); +}; + +interface PopoverContextType { + onClose?: () => void; +} + +const PopoverContext = React.createContext({}); + +interface PopoverHeaderProps { + children?: ReactNode; +} + +const PopoverHeader: FC = ({children}) => { + const styles = useStyles(); + const {onClose} = React.useContext(PopoverContext); + + return ( +
+ {children &&

{children}

} + {onClose && ( + + )} +
+ ); +}; + +interface PopoverContentProps { + children: ReactNode; +} + +const PopoverContent: FC = ({children}) => { + const styles = useStyles(); + return
{children}
; +}; + +export interface PopoverProps { + /** + * Whether the popover is open + */ + isOpen: boolean; + /** + * The content to display inside the popover + */ + children: ReactNode; + /** + * Callback when the popover should close + */ + onClose: () => void; + /** + * Optional custom class name for the popover container + */ + className?: string; + /** + * The HTML element ID where the portal should be mounted + */ + portalId?: string; + /** + * The display mode of the popover + * 'modal' - shows overlay and centers content + * 'dropdown' - no overlay, content positioned relative to trigger + */ + mode?: 'modal' | 'dropdown'; +} + +export const Popover: FC & { + Header: typeof PopoverHeader; + Content: typeof PopoverContent; +} = ({isOpen, children, onClose, className = '', portalId = 'wso2-popover-root', mode = 'modal'}) => { + const [portalEl, setPortalEl] = useState(null); + const styles = useStyles(); + + useEffect(() => { + const existing = document.getElementById(portalId); + if (existing) { + setPortalEl(existing); + return void 0; + } + + const el = document.createElement('div'); + el.id = portalId; + document.body.appendChild(el); + setPortalEl(el); + + return () => { + if (document.getElementById(portalId)) { + document.getElementById(portalId)?.remove(); + } + }; + }, [portalId]); + + useEffect(() => { + const handleEscape = (event: KeyboardEvent) => { + if (event.key === 'Escape' && isOpen) { + onClose(); + } + }; + + document.addEventListener('keydown', handleEscape); + return () => document.removeEventListener('keydown', handleEscape); + }, [isOpen, onClose]); + + if (!isOpen || !portalEl) { + return null; + } + + return createPortal( + +
+ {mode === 'modal' && ( +
+ )} +
+ {children} +
+
+ , + portalEl, + ); +}; + +Popover.Header = PopoverHeader; +Popover.Content = PopoverContent; + +export default Popover; diff --git a/packages/react/src/components/primitives/Select/Select.tsx b/packages/react/src/components/primitives/Select/Select.tsx new file mode 100644 index 000000000..652b1123d --- /dev/null +++ b/packages/react/src/components/primitives/Select/Select.tsx @@ -0,0 +1,135 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {CSSProperties, FC, SelectHTMLAttributes} from 'react'; +import {useTheme} from '../../../theme/useTheme'; +import clsx from 'clsx'; + +export interface SelectOption { + /** + * The value that will be submitted with the form + */ + value: string; + /** + * The text that will be displayed in the select + */ + label: string; +} + +export interface SelectProps extends Omit, 'className'> { + /** + * Label text to display above the select + */ + label?: string; + /** + * Error message to display below the select + */ + error?: string; + /** + * Additional CSS class names + */ + className?: string; + /** + * Whether the field is required + */ + required?: boolean; + /** + * Whether the field is disabled + */ + disabled?: boolean; + /** + * Helper text to display below the select + */ + helperText?: string; + /** + * The options to display in the select + */ + options: SelectOption[]; +} + +export const Select: FC = ({ + label, + error, + className, + required, + disabled, + helperText, + options, + style = {}, + ...rest +}) => { + const {theme} = useTheme(); + + const containerStyle: CSSProperties = { + marginBottom: theme.spacing.unit * 2 + 'px', + ...style, + }; + + const labelStyle: CSSProperties = { + display: 'block', + marginBottom: theme.spacing.unit + 'px', + color: error ? theme.colors.error.main : theme.colors.text.secondary, + fontSize: '0.875rem', + fontWeight: 500, + }; + + const selectStyle: CSSProperties = { + width: '100%', + padding: `${theme.spacing.unit}px ${theme.spacing.unit * 1.5}px`, + border: `1px solid ${error ? theme.colors.error.main : theme.colors.border}`, + borderRadius: theme.borderRadius.small, + fontSize: '1rem', + color: theme.colors.text.primary, + backgroundColor: disabled ? theme.colors.background.disabled : theme.colors.background.surface, + outline: 'none', + transition: 'border-color 0.2s ease', + appearance: 'none', + backgroundImage: + "url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23${theme.colors.text.secondary.replace('#', '')}%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E')", + backgroundRepeat: 'no-repeat', + backgroundPosition: 'right .7em top 50%', + backgroundSize: '.65em auto', + }; + + const helperTextStyle: CSSProperties = { + fontSize: '0.75rem', + color: error ? theme.colors.error.main : theme.colors.text.secondary, + marginTop: theme.spacing.unit / 2 + 'px', + }; + + return ( +
+ {label && ( + + )} + + {(error || helperText) &&
{error || helperText}
} +
+ ); +}; + +export default Select; diff --git a/packages/react/src/components/primitives/TextField/TextField.tsx b/packages/react/src/components/primitives/TextField/TextField.tsx new file mode 100644 index 000000000..7b5ea1e6f --- /dev/null +++ b/packages/react/src/components/primitives/TextField/TextField.tsx @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {CSSProperties, FC, InputHTMLAttributes} from 'react'; +import {useTheme} from '../../../theme/useTheme'; +import clsx from 'clsx'; + +export interface TextFieldProps extends Omit, 'className'> { + /** + * Label text to display above the input + */ + label?: string; + /** + * Error message to display below the input + */ + error?: string; + /** + * Additional CSS class names + */ + className?: string; + /** + * Whether the field is required + */ + required?: boolean; + /** + * Whether the field is disabled + */ + disabled?: boolean; + /** + * Helper text to display below the input + */ + helperText?: string; +} + +export const TextField: FC = ({label, error, required, className, disabled, helperText, style = {}, ...rest}) => { + const {theme} = useTheme(); + + const containerStyle: CSSProperties = { + marginBottom: theme.spacing.unit * 2 + 'px', + ...style + }; + + const labelStyle: CSSProperties = { + display: 'block', + marginBottom: theme.spacing.unit + 'px', + color: error ? theme.colors.error.main : theme.colors.text.secondary, + fontSize: '0.875rem', + fontWeight: 500, + }; + + const inputStyle: CSSProperties = { + width: '100%', + padding: `${theme.spacing.unit}px ${theme.spacing.unit * 1.5}px`, + border: `1px solid ${error ? theme.colors.error.main : theme.colors.border}`, + borderRadius: theme.borderRadius.small, + fontSize: '1rem', + color: theme.colors.text.primary, + backgroundColor: disabled ? theme.colors.background.disabled : theme.colors.background.surface, + outline: 'none', + transition: 'border-color 0.2s ease', + }; + + const helperTextStyle: CSSProperties = { + fontSize: '0.75rem', + color: error ? theme.colors.error.main : theme.colors.text.secondary, + marginTop: theme.spacing.unit / 2 + 'px', + }; + + return ( +
+ {label && ( + + )} + + {(error || helperText) &&
{error || helperText}
} +
+ ); +}; + +export default TextField; diff --git a/packages/react/src/contexts/AsgardeoContext.ts b/packages/react/src/contexts/AsgardeoContext.ts new file mode 100644 index 000000000..596649124 --- /dev/null +++ b/packages/react/src/contexts/AsgardeoContext.ts @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {Context, createContext} from 'react'; +import {User} from '@asgardeo/browser'; + +/** + * Props interface of {@link AsgardeoContext} + */ +export type AsgardeoContextProps = { + /** + * Flag indicating whether the SDK is working in the background. + */ + isLoading: boolean; + /** + * Flag indicating whether the user is signed in or not. + */ + isSignedIn: boolean; + /** + * Sign-in function to initiate the authentication process. + * @remark This is the programmatic version of the `SignInButton` component. + * TODO: Fix the types. + */ + signIn: any; + /** + * Sign-out function to terminate the authentication session. + * @remark This is the programmatic version of the `SignOutButton` component. + * FIXME: Fix the types. + */ + signOut: any; + /** + * Sign-up function to initiate the registration process. + * @remark This is the programmatic version of the `SignUpButton` component. + * FIXME: Fix the types. + */ + signUp: any; + user: any; + baseUrl: string; +}; + +/** + * Context object for managing the Authentication flow builder core context. + */ +const AsgardeoContext: Context = createContext({ + isLoading: true, + isSignedIn: false, + signIn: null, + signOut: null, + signUp: null, + user: null, + baseUrl: '' +}); + +AsgardeoContext.displayName = 'AsgardeoContext'; + +export default AsgardeoContext; diff --git a/packages/react/src/hooks/useAsgardeo.ts b/packages/react/src/hooks/useAsgardeo.ts new file mode 100644 index 000000000..4c9622f3e --- /dev/null +++ b/packages/react/src/hooks/useAsgardeo.ts @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {useContext} from 'react'; +import AsgardeoContext, {AsgardeoContextProps} from '../contexts/AsgardeoContext'; + +const useAsgardeo = (): AsgardeoContextProps => { + const context: AsgardeoContextProps | null = useContext(AsgardeoContext); + + if (!context) { + throw new Error('useAsgardeo must be used within an AsgardeoProvider'); + } + + return context; +}; + +export default useAsgardeo; diff --git a/packages/react/src/hooks/useBrowserUrl.ts b/packages/react/src/hooks/useBrowserUrl.ts new file mode 100644 index 000000000..fd4bbd30c --- /dev/null +++ b/packages/react/src/hooks/useBrowserUrl.ts @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {hasAuthParamsInUrl} from '@asgardeo/browser'; + +/** + * Interface for the useBrowserUrl hook return value. + */ +export interface UseBrowserUrl { + /** + * Checks if the current URL contains authentication parameters. + * + * @param url - The URL object to check for authentication parameters + * @param afterSignInUrl - The URL where the authorization server should redirect after authentication + * @returns True if the URL contains authentication parameters and matches the afterSignInUrl, or if it contains an error parameter + */ + hasAuthParams: (url: URL, afterSignInUrl: string) => boolean; +} + +/** + * Hook that provides utilities for handling browser URLs in authentication flows. + * + * @returns An object containing URL utility functions + * + * @example + * ```tsx + * const { hasAuthParams } = useBrowserUrl(); + * const url = new URL(window.location.href); + * + * if (hasAuthParams(url, "/after-signin")) { + * // Handle authentication callback + * } + * ``` + */ +const useBrowserUrl = (): UseBrowserUrl => { + const hasAuthParams = (url: URL, afterSignInUrl: string): boolean => + (hasAuthParamsInUrl() && new URL(url.origin + url.pathname).toString() === new URL(afterSignInUrl).toString()) || + // authParams?.authorizationCode || // FIXME: These are sent externally. Need to see what we can do about this. + url.searchParams.get('error') !== null; + + return {hasAuthParams}; +}; + +export default useBrowserUrl; diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 98f497c95..b86effea7 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -16,8 +16,55 @@ * under the License. */ -export * from './components/public-components'; -export * from './models/public-models'; export {default as AsgardeoProvider} from './providers/AsgardeoProvider'; -export {default as useAuthentication} from './hooks/use-authentication'; -export {default as useOn} from './hooks/use-on'; +export * from './providers/AsgardeoProvider'; + +export {default as AsgardeoContext} from './contexts/AsgardeoContext'; +export * from './contexts/AsgardeoContext'; + +export {default as useAsgardeo} from './hooks/useAsgardeo'; +export * from './hooks/useAsgardeo'; + +export {default as useBrowserUrl} from './hooks/useBrowserUrl'; +export * from './hooks/useBrowserUrl'; + +export {default as BaseSignInButton} from './components/actions/SignInButton/BaseSignInButton'; +export * from './components/actions/SignInButton/BaseSignInButton'; + +export {default as SignInButton} from './components/actions/SignInButton/SignInButton'; +export * from './components/actions/SignInButton/SignInButton'; + +export {default as BaseSignOutButton} from './components/actions/SignOutButton/BaseSignOutButton'; +export * from './components/actions/SignOutButton/BaseSignOutButton'; + +export {default as SignOutButton} from './components/actions/SignOutButton/SignOutButton'; +export * from './components/actions/SignOutButton/SignOutButton'; + +export {default as BaseSignUpButton} from './components/actions/SignUpButton/BaseSignUpButton'; +export * from './components/actions/SignUpButton/BaseSignUpButton'; + +export {default as SignUpButton} from './components/actions/SignUpButton/SignUpButton'; +export * from './components/actions/SignUpButton/SignUpButton'; + +export {default as SignedIn} from './components/control/SignedIn'; +export * from './components/control/SignedIn'; + +export {default as SignedOut} from './components/control/SignedOut'; +export * from './components/control/SignedOut'; + +export {default as User} from './components/presentation/User'; +export * from './components/presentation/User'; + +export {default as BaseUserProfile} from './components/presentation/UserProfile/BaseUserProfile'; +export * from './components/presentation/UserProfile/BaseUserProfile'; + +export {default as UserProfile} from './components/presentation/UserProfile/UserProfile'; +export * from './components/presentation/UserProfile/UserProfile'; + +export {default as BaseUserDropdown} from './components/presentation/UserDropdown/BaseUserDropdown'; +export * from './components/presentation/UserDropdown/BaseUserDropdown'; + +export {default as UserDropdown} from './components/presentation/UserDropdown/UserDropdown'; +export * from './components/presentation/UserDropdown/UserDropdown'; + +export * from '@asgardeo/browser'; diff --git a/packages/react/src/models/config.ts b/packages/react/src/models/config.ts new file mode 100644 index 000000000..f53fdd48b --- /dev/null +++ b/packages/react/src/models/config.ts @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {AsgardeoBrowserConfig} from '@asgardeo/browser'; + +export type AsgardeoReactConfig = AsgardeoBrowserConfig; diff --git a/packages/react/src/providers/AsgardeoProvider.tsx b/packages/react/src/providers/AsgardeoProvider.tsx index 50b5cf777..f580c1b75 100644 --- a/packages/react/src/providers/AsgardeoProvider.tsx +++ b/packages/react/src/providers/AsgardeoProvider.tsx @@ -1,5 +1,5 @@ /** - * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -16,170 +16,166 @@ * under the License. */ -import { - AuthApiResponse, - AuthClient, - CryptoUtils, - MeAPIResponse, - Store, - UIAuthClient, - getProfileInformation, -} from '@asgardeo/js'; -import {FC, PropsWithChildren, useCallback, useEffect, useMemo, useRef, useState} from 'react'; -import BrandingPreferenceProvider from './BrandingPreferenceProvider'; -import I18nProvider from './I18nProvider'; -import AsgardeoContext from '../contexts/asgardeo-context'; -import AsgardeoProviderProps from '../models/asgardeo-provider-props'; -import AuthContext from '../models/auth-context'; -import SPACryptoUtils from '../utils/crypto-utils'; -import SessionStore from '../utils/session-store'; +import {SignInOptions, SignOutOptions, User} from '@asgardeo/browser'; +import {FC, RefObject, PropsWithChildren, ReactElement, useEffect, useMemo, useRef, useState, use} from 'react'; +import AsgardeoReactClient from '../AsgardeoReactClient'; +import AsgardeoContext from '../contexts/AsgardeoContext'; +import useBrowserUrl from '../hooks/useBrowserUrl'; +import {AsgardeoReactConfig} from '../models/config'; +import {ThemeProvider} from '../theme/ThemeProvider'; /** - * `AsgardeoProvider` is a component that provides an Asgardeo context to all its children. - * It takes an object of type `AsgardeProviderProps` as props, which includes the children to render, - * a configuration object, a store instance, and a branding object. - * - * @param {PropsWithChildren} props - The properties passed to the component. - * @param {ReactNode} props.children - The children to render inside the provider. - * @param {Config} props.config - The configuration object for the Asgardeo context. - * @param {Store} [props.store] - An optional store instance. If not provided, a new SessionStore will be created. - * @param {Branding} props.branding - The branding object for the Asgardeo context. - * - * @returns {ReactElement} A React element that provides the Asgardeo context to all its children. + * Props interface of {@link AsgardeoProvider} */ -const AsgardeoProvider: FC> = ( - props: PropsWithChildren, -) => { - const {children, config, store, branding} = props; - - const [accessToken, setAccessToken] = useState(''); - const [isAuthenticated, setIsAuthenticated] = useState(); - const [user, setUser] = useState(); - const [isBrandingLoading, setIsBrandingLoading] = useState(true); - const [isTextLoading, setIsTextLoading] = useState(true); - const [isAuthLoading, setIsAuthLoading] = useState(false); - const [isComponentLoading, setIsComponentLoading] = useState(true); - const [authResponse, setAuthResponse] = useState(); - const [username, setUsername] = useState(''); - - const onSignInRef: React.MutableRefObject = useRef(); - const onSignOutRef: React.MutableRefObject = useRef(); - - const setOnSignIn: (newOnSignIn: Function) => void = useCallback( - (newOnSignIn: Function): void => { - onSignInRef.current = newOnSignIn; - }, - [], // Add any dependencies here... - ); - - const setOnSignOut: (newOnSignOut: Function) => void = useCallback( - (newOnSignOut: Function): void => { - onSignOutRef.current = newOnSignOut; - }, - [], // Add any dependencies here... - ); - - const storeInstance: Store = store || new SessionStore(); - - const spaUtils: CryptoUtils = new SPACryptoUtils(); +export type AsgardeoProviderProps = AsgardeoReactConfig; + +const AsgardeoProvider: FC> = ({ + afterSignInUrl = window.location.origin, + baseUrl, + clientId, + children, + scopes, + preferences, +}: PropsWithChildren): ReactElement => { + const reRenderCheckRef: RefObject = useRef(false); + const asgardeo: AsgardeoReactClient = useMemo(() => new AsgardeoReactClient(), []); + const {hasAuthParams} = useBrowserUrl(); + const [user, setUser] = useState(null); + + const [isSignedInSync, setIsSignedInSync] = useState(false); - const authClient: UIAuthClient = AuthClient.getInstance(config, storeInstance, spaUtils); + useEffect(() => { + (async (): Promise => { + await asgardeo.initialize({ + afterSignInUrl, + baseUrl, + clientId, + scopes, + }); + })(); + }, []); /** - * Sets the authentication status and access token. + * Try signing in when the component is mounted. */ - const setAuthentication: () => void = useCallback((): void => { - authClient.isAuthenticated().then((isAuth: boolean) => { - setIsAuthenticated(isAuth); + useEffect(() => { + // React 18.x Strict.Mode has a new check for `Ensuring reusable state` to facilitate an upcoming react feature. + // https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state + // This will remount all the useEffects to ensure that there are no unexpected side effects. + // When react remounts the signIn hook of the AuthProvider, it will cause a race condition. Hence, we have to + // prevent the re-render of this hook as suggested in the following discussion. + // https://github.com/reactwg/react-18/discussions/18#discussioncomment-795623 + if (reRenderCheckRef.current) { + return; + } - if (isAuth) { - authClient.getAccessToken().then((accessTokenFromClient: string) => { - if (accessTokenFromClient) { - setAccessToken(accessTokenFromClient); + reRenderCheckRef.current = true; - getProfileInformation().then((response: MeAPIResponse) => { - setUser(response); - }); + (async (): Promise => { + // User is already authenticated. Skip... + if (await asgardeo.isSignedIn()) { + setUser(await asgardeo.getUser()); - if (onSignInRef.current) { - onSignInRef.current(); - } + return; + } + + if (hasAuthParams(new URL(window.location.href), afterSignInUrl)) { + try { + await signIn( + {callOnlyOnRedirect: true}, + // authParams?.authorizationCode, + // authParams?.sessionState, + // authParams?.state, + ); + + // setError(null); + } catch (error) { + debugger; + if (error && Object.prototype.hasOwnProperty.call(error, 'code')) { + // setError(error); } - }); + } } - }); - }, [authClient]); + })(); + }, []); + /** + * Check if the user is signed in and update the state accordingly. + * This will also set an interval to check for the sign-in status every second + * until the user is signed in. + */ useEffect(() => { - setAuthentication(); - - /** - * This script is added so that the popup window can send the code and state to the parent window - */ - const url: URL = new URL(window.location.href); - if (url.searchParams.has('code') && url.searchParams.has('state')) { - const code: string = url.searchParams.get('code'); - const state: string = url.searchParams.get('state'); - - /** - * Send the 'code' and 'state' to the parent window and close the current window (popup) - */ - window.opener.postMessage({code, state}, config.signInRedirectURL); - window.close(); + let interval: NodeJS.Timeout; + + (async () => { + try { + const status = await asgardeo.isSignedIn(); + setIsSignedInSync(status); + + if (!status) { + interval = setInterval(async () => { + const newStatus = await asgardeo.isSignedIn(); + if (newStatus) { + setIsSignedInSync(true); + clearInterval(interval); + } + }, 1000); + } + } catch (error) { + setIsSignedInSync(false); + } + })(); + + return () => { + if (interval) { + clearInterval(interval); + } + }; + }, [asgardeo]); + + const signIn = async (options?: SignInOptions): Promise => { + try { + const response = await asgardeo.signIn(options); + setUser(await asgardeo.getUser()); + + return response; + } catch (error) { + throw new Error(`Error while signing in: ${error}`); } - }, [config.signInRedirectURL, setAuthentication]); - - const value: AuthContext = useMemo( - () => ({ - accessToken, - authResponse, - config, - isAuthLoading, - isAuthenticated, - isBrandingLoading, - isComponentLoading, - isGlobalLoading: isAuthLoading || isBrandingLoading || isComponentLoading || isTextLoading, - isTextLoading, - onSignOutRef, - setAuthResponse, - setAuthentication, - setIsAuthLoading, - setIsBrandingLoading, - setIsComponentLoading, - setIsTextLoading, - setOnSignIn, - setOnSignOut, - setUsername, - user, - username, - }), - [ - accessToken, - authResponse, - config, - isAuthLoading, - isAuthenticated, - isBrandingLoading, - isComponentLoading, - isTextLoading, - setAuthResponse, - setAuthentication, - setIsComponentLoading, - setOnSignIn, - setOnSignOut, - setUsername, - user, - username, - ], - ); + }; + + const signUp = (): void => { + throw new Error('Not implemented'); + }; + + const signOut = async (options?: SignOutOptions, afterSignOut?: () => void): Promise => + asgardeo.signOut(options, afterSignOut); + + const isDarkMode = useMemo(() => { + if (!preferences?.theme?.mode || preferences.theme.mode === 'system') { + return window.matchMedia('(prefers-color-scheme: dark)').matches; + } + return preferences.theme.mode === 'dark'; + }, [preferences?.theme?.mode]); return ( - - - - {children} - - + { + // TODO: Implement signUp functionality + throw new Error('Sign up functionality not implemented yet'); + }, + user, + baseUrl + }} + > + + {children} + ); }; diff --git a/packages/react/src/theme/ThemeContext.ts b/packages/react/src/theme/ThemeContext.ts new file mode 100644 index 000000000..726959012 --- /dev/null +++ b/packages/react/src/theme/ThemeContext.ts @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {createContext} from 'react'; +import {Theme} from '@asgardeo/browser'; + +export interface ThemeContextValue { + theme: Theme; + colorScheme: 'light' | 'dark'; + toggleTheme: () => void; +} + +const ThemeContext = createContext(null); + +ThemeContext.displayName = 'ThemeContext'; + +export default ThemeContext; diff --git a/packages/react/src/theme/ThemeProvider.tsx b/packages/react/src/theme/ThemeProvider.tsx new file mode 100644 index 000000000..f885c7662 --- /dev/null +++ b/packages/react/src/theme/ThemeProvider.tsx @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {FC, PropsWithChildren, ReactElement, useEffect, useMemo, useState} from 'react'; +import {createTheme, Theme, ThemeConfig, RecursivePartial} from '@asgardeo/browser'; +import ThemeContext from './ThemeContext'; + +export interface ThemeProviderProps { + theme?: RecursivePartial; + defaultColorScheme?: 'light' | 'dark'; +} + +const applyThemeToDOM = (theme: Theme) => { + Object.entries(theme.cssVariables).forEach(([key, value]) => { + document.documentElement.style.setProperty(key, value); + }); +}; + +export const ThemeProvider: FC> = ({ + children, + theme: themeConfig, + defaultColorScheme = 'light', +}: PropsWithChildren): ReactElement => { + const [colorScheme, setColorScheme] = useState<'light' | 'dark'>(defaultColorScheme); + + const theme = useMemo(() => createTheme(themeConfig, colorScheme === 'dark'), [themeConfig, colorScheme]); + + const toggleTheme = () => { + setColorScheme(prev => (prev === 'light' ? 'dark' : 'light')); + }; + + useEffect(() => { + applyThemeToDOM(theme); + }, [theme]); + + const value = { + theme, + colorScheme, + toggleTheme, + }; + + return {children}; +}; diff --git a/packages/react/src/theme/types.ts b/packages/react/src/theme/types.ts new file mode 100644 index 000000000..bc81f7e3d --- /dev/null +++ b/packages/react/src/theme/types.ts @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export interface ThemeColors { + primary: string; + background: string; + surface: string; + text: { + primary: string; + secondary: string; + }; + border: string; +} + +export interface ThemeConfig { + colors: ThemeColors; + spacing: { + unit: number; + }; + borderRadius: { + small: string; + medium: string; + large: string; + }; +} + +export interface Theme extends ThemeConfig { + cssVariables: Record; +} diff --git a/packages/react/src/theme/useTheme.ts b/packages/react/src/theme/useTheme.ts new file mode 100644 index 000000000..f907897bf --- /dev/null +++ b/packages/react/src/theme/useTheme.ts @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {useContext} from 'react'; +import ThemeContext, {ThemeContextValue} from './ThemeContext'; + +export const useTheme = (): ThemeContextValue => { + const context = useContext(ThemeContext); + if (!context) { + throw new Error('useTheme must be used within a ThemeProvider'); + } + return context; +}; diff --git a/packages/react/src/utils/getMappedUserProfileValue.ts b/packages/react/src/utils/getMappedUserProfileValue.ts new file mode 100644 index 000000000..652ad0315 --- /dev/null +++ b/packages/react/src/utils/getMappedUserProfileValue.ts @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const getMappedUserProfileValue = (key: string, mappings, user) => { + const mappedKey = mappings[key]; + + if (Array.isArray(user)) { + if (Array.isArray(mappedKey)) { + for (const field of mappedKey) { + const found = user.find(u => u.name === field); + if (found?.value !== undefined) { + return found.value; + } + } + } else { + const found = user.find(u => u.name === mappedKey); + if (found?.value !== undefined) { + return found.value; + } + } + + const found = user.find(u => u.name === key); + + return found?.value; + } + + return mappedKey ? user[mappedKey] : user[key]; +}; + +export default getMappedUserProfileValue; diff --git a/packages/react/src/utils/getUserProfile.ts b/packages/react/src/utils/getUserProfile.ts new file mode 100644 index 000000000..5d8b2af52 --- /dev/null +++ b/packages/react/src/utils/getUserProfile.ts @@ -0,0 +1,131 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import getMeProfile from '../api/scim2/getMeProfile'; +import {AsgardeoAPIError, User, WellKnownSchemaIds} from '@asgardeo/browser'; +import getSchemas from '../api/scim2/getSchemas'; + +/** + * Retrieves the authenticated user's profile information with all SCIM2 schema properties + * flattened to the root level for easier access. + * + * The function flattens properties from all schemas defined in WellKnownSchemaIds: + * - Core User properties (urn:ietf:params:scim:schemas:core:2.0:User) + * - Enterprise User properties (urn:ietf:params:scim:schemas:extension:enterprise:2.0:User) + * - System User properties (urn:scim:wso2:schema) + * - Custom User properties (urn:scim:schemas:extension:custom:User) + * + * @param requestConfig - Request configuration object. + * @returns A promise that resolves with the flattened user profile information. + * @example + * ```typescript + * try { + * const userProfile = await getUserProfile({ + * url: "https://api.asgardeo.io/t//scim2/Me", + * }); + * + * // Access flattened properties directly: + * console.log("Email:", userProfile.emails[0]); + * console.log("Name:", userProfile.name.formatted); + * console.log("Username:", userProfile.userName); + * + * // WSO2 specific properties: + * console.log("Account State:", userProfile.accountState); + * console.log("Email Verified:", userProfile.emailVerified); + * + * // Enterprise properties (if available): + * console.log("Employee Number:", userProfile.employeeNumber); + * console.log("Cost Center:", userProfile.costCenter); + * } catch (error) { + * if (error instanceof AsgardeoAPIError) { + * console.error('Failed to get user profile:', error.message); + * } + * } + * ``` + */ +const getUserProfile = async ({baseUrl}): Promise => { + try { + const profile = await getMeProfile({url: `${baseUrl}/scim2/Me`}); + const schemas = await getSchemas({url: `${baseUrl}/scim2/Schemas`}); + + const result = []; + + for (const schema of schemas) { + const schemaId = schema.id; + + const source = schemaId.startsWith('urn:ietf:params:scim:schemas:core:2.0') ? profile : profile[schemaId] ?? {}; + + for (const attr of schema.attributes || []) { + const {name, type, subAttributes, multiValued, caseExact, returned} = attr; + + if (type === 'COMPLEX' && subAttributes?.length && typeof source[name] === 'object') { + // For complex attributes with subAttributes, create an entry for each subAttribute + const complexValue = source[name]; + for (const subAttr of subAttributes) { + if (complexValue[subAttr.name] !== undefined) { + const {subAttributes, ...attrWithoutSubAttrs} = attr; + + // UPDATED PATH: prefix with schemaId except for core user schema + const basePath = + schemaId === 'urn:ietf:params:scim:schemas:core:2.0:User' + ? `${name}.${subAttr.name}` + : `${schemaId}.${name}.${subAttr.name}`; + + result.push({ + schemaId, + ...subAttr, + value: complexValue[subAttr.name], + parent: { + ...attrWithoutSubAttrs, + }, + path: basePath, + }); + } + } + } else { + const value = source[name]; + // Only include if value exists + + if (value !== undefined) { + // UPDATED PATH: prefix with schemaId except for core user schema + const basePath = schemaId === 'urn:ietf:params:scim:schemas:core:2.0:User' ? name : `${schemaId}.${name}`; + + result.push({ + schemaId, + ...attr, + value, + path: basePath, + }); + } + } + } + } + + return result; + } catch (error) { + throw new AsgardeoAPIError( + 'Failed to get user profile', + 'getUserProfile-Error-001', + 'javascript', + 500, + 'Internal Server Error', + ); + } +}; + +export default getUserProfile; diff --git a/packages/react/tsconfig.eslint.json b/packages/react/tsconfig.eslint.json index bdaa69d4b..d5eefbbbb 100644 --- a/packages/react/tsconfig.eslint.json +++ b/packages/react/tsconfig.eslint.json @@ -1,14 +1,4 @@ { - "extends": "./tsconfig.json", - "compilerOptions": { - "module": "ESNext", - "types": ["jest", "node"] - }, - "include": [ - "**/*.cjs", - "**/*.js", - "**/*.jsx", - "**/*.ts", - "**/*.tsx", - ] - } + "extends": "./tsconfig.json", + "include": ["**/.*.js", "**/.*.cjs", "**/.*.ts", "**/*.js", "**/*.cjs", "**/*.ts"] +} diff --git a/packages/react/tsconfig.json b/packages/react/tsconfig.json index cb627bf60..59084d66b 100644 --- a/packages/react/tsconfig.json +++ b/packages/react/tsconfig.json @@ -1,35 +1,36 @@ { - "compileOnSave": false, - "compilerOptions": { - "jsx": "react-jsx", - "target": "es2016", - "module": "ESNext", - "emitDecoratorMetadata": true, - "esModuleInterop": true, - "experimentalDecorators": true, - "forceConsistentCasingInFileNames": true, - "strict": false, - "skipLibCheck": true, - "skipDefaultLibCheck": true, - "allowJs": true, - "allowSyntheticDefaultImports": true, - "declaration": true, - "declarationDir": "dist/types", - "outDir": "dist", - "moduleResolution": "node", - "importHelpers": true, - "resolveJsonModule": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, + "extends": "../../tsconfig.json", + "compileOnSave": false, + "compilerOptions": { + "declaration": false, + "emitDecoratorMetadata": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "importHelpers": true, + "jsx": "react-jsx", + "lib": ["ESNext", "DOM"], + "module": "ESNext", + "moduleResolution": "node", + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "sourceMap": true, + "target": "ESNext", + "forceConsistentCasingInFileNames": true, + "strict": false, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true }, - "include": [], - "files": [], - "exclude": ["node_modules", "tmp"], - "references": [ - { - "path": "./tsconfig.lib.json" - } + "exclude": ["node_modules", "tmp", "dist"], + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } ] } diff --git a/packages/react/tsconfig.lib.json b/packages/react/tsconfig.lib.json index 7f9476b9b..8d37e00df 100644 --- a/packages/react/tsconfig.lib.json +++ b/packages/react/tsconfig.lib.json @@ -1,26 +1,20 @@ { - "extends": "./tsconfig.json", - "compilerOptions": { - "declaration": true, - "outDir": "dist", - "declarationDir": "types", - "types": ["node"], - "emitDeclarationOnly": true - }, - "files": [], - "exclude": [ - "test-configs", - "jest.config.ts", - "**/*.spec.ts", - "**/*.test.ts", - "**/*.spec.tsx", - "**/*.test.tsx", - "**/*.spec.js", - "**/*.test.js", - "**/*.spec.jsx", - "**/*.test.jsx", - "scripts", - "dist" - ], - "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx", "rollup.config.cjs", "declarations.d.ts"] - } + "extends": "./tsconfig.json", + "compilerOptions": { + "declaration": true, + "outDir": "dist", + "declarationDir": "dist", + "types": ["node"] + }, + "exclude": [ + "**/*.spec.ts", + "**/*.test.ts", + "**/*.spec.tsx", + "**/*.test.tsx", + "**/*.spec.js", + "**/*.test.js", + "**/*.spec.jsx", + "**/*.test.jsx" + ], + "include": ["src/**/*.js", "src/**/*.ts", "src/**/*.jsx", "src/**/*.tsx", "types/**/*.d.ts"] +} diff --git a/packages/react/tsconfig.spec.json b/packages/react/tsconfig.spec.json new file mode 100644 index 000000000..46a76e285 --- /dev/null +++ b/packages/react/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "test-configs", + "jest.config.js", + "**/*.test.ts", + "**/*.spec.ts", + "**/*.test.js", + "**/*.spec.js", + "**/*.d.ts" + ] +} diff --git a/packages/react/vitest.config.ts b/packages/react/vitest.config.ts new file mode 100644 index 000000000..bfcf53bd8 --- /dev/null +++ b/packages/react/vitest.config.ts @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {defineConfig} from 'vitest/config'; + +export default defineConfig({ + test: { + browser: { + enabled: true, + headless: true, + instances: [{browser: 'chromium'}], + provider: 'playwright', + }, + }, +}); diff --git a/packages/vue/README.md b/packages/vue/README.md index 9cd69cf61..52b520283 100644 --- a/packages/vue/README.md +++ b/packages/vue/README.md @@ -1,31 +1,30 @@ -# @asgardeo/vue - -

Vue Wrapper to build customizable login UIs for Asgardeo or Identity Server

- +

+

@asgardeo/vue

+

+

Vue.js SDK for Asgardeo

npm (scoped) npm License
-## Prerequisites -- Vue.js 3.4.0 or higher - ## Installation ```bash -# With npm +# Using npm npm install @asgardeo/vue -# With pnpm +# or using pnpm pnpm add @asgardeo/vue -# With yarn +# or using yarn yarn add @asgardeo/vue ``` ## Basic Setup +1. Configure the authentication plugin: + ```typescript import { createApp } from 'vue' import { AsgardeoAuth } from '@asgardeo/vue' @@ -43,6 +42,61 @@ app.use(AsgardeoAuth, { app.mount('#app') ``` +2. Use in your components: + +```vue + + + +``` + +## Composables + +- `useAsgardeo()`: Main composable that provides: + - `isAuthenticated`: Boolean indicating authentication status + - `user`: Current user information + - `signIn()`: Function to initiate sign in + - `signOut()`: Function to sign out + - `getAccessToken()`: Function to get the current access token + - `getBasicUserInfo()`: Function to get basic user information + +- `useAuthContext()`: Composable to access the raw authentication context +- `useIsAuthenticated()`: Composable to check authentication status + +## Development + +1. Install dependencies: +```bash +pnpm install +``` + +2. Build: +```bash +pnpm build +``` + +3. Run tests: +```bash +pnpm test +``` + +4. Run development server: +```bash +pnpm dev +``` + ## License -Licenses this source under the Apache License, Version 2.0 [LICENSE](./LICENSE), You may not use this file except in compliance with the License. +Apache License, Version 2.0 - see [LICENSE](./LICENSE) for details. diff --git a/packages/vue/package.json b/packages/vue/package.json index 7e4cff461..c1ba90fac 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -42,9 +42,6 @@ "typecheck": "vue-tsc --noEmit", "test": "vitest --config src/vitest.config.ts --environment=jsdom --run --passWithNoTests" }, - "publishConfig": { - "access": "public" - }, "devDependencies": { "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-image": "^3.0.3", @@ -59,7 +56,7 @@ "@wso2/eslint-plugin": "catalog:", "@wso2/prettier-config": "catalog:", "@wso2/stylelint-config": "catalog:", - "eslint": "catalog:", + "eslint": "8.57.0", "prettier": "^3.2.5", "rollup": "^4.17.2", "rollup-plugin-dts": "^6.1.0", @@ -90,5 +87,8 @@ "types": "./dist/index.d.ts", "import": "./dist/esm/index.js", "require": "./dist/cjs/index.js" + }, + "publishConfig": { + "access": "public" } -} +} \ No newline at end of file diff --git a/packages/vue/src/auth-api.ts b/packages/vue/src/auth-api.ts index a26c04bde..d4a2f1a55 100644 --- a/packages/vue/src/auth-api.ts +++ b/packages/vue/src/auth-api.ts @@ -22,7 +22,7 @@ import { AuthClientConfig, BasicUserInfo, Config, - DecodedIDTokenPayload, + IdTokenPayload, FetchResponse, Hooks, HttpClientInstance, @@ -247,7 +247,7 @@ class AuthAPI { * @return {Promise} - A Promise that resolves with * the decoded payload of the id token. */ - public async getDecodedIDToken(): Promise { + public async getDecodedIDToken(): Promise { return this._client.getDecodedIDToken(); } @@ -259,7 +259,7 @@ class AuthAPI { * @return {Promise} - A Promise that resolves with * the decoded payload of the idp id token. */ - public async getDecodedIDPIDToken(): Promise { + public async getDecodedIDPIDToken(): Promise { return this._client.getDecodedIDToken(); } diff --git a/packages/vue/src/plugins/AsgardeoPlugin.ts b/packages/vue/src/plugins/AsgardeoPlugin.ts index 858790823..7c7ed9e00 100644 --- a/packages/vue/src/plugins/AsgardeoPlugin.ts +++ b/packages/vue/src/plugins/AsgardeoPlugin.ts @@ -21,7 +21,7 @@ import { AuthClientConfig, Config, CustomGrantConfig, - DecodedIDTokenPayload, + IdTokenPayload, FetchResponse, Hooks, HttpClientInstance, @@ -159,7 +159,7 @@ export const asgardeoPlugin: Plugin = { error: error.value, getAccessToken: (): Promise => AuthClient.getAccessToken(), getBasicUserInfo: (): Promise => AuthClient.getBasicUserInfo(), - getDecodedIDToken: (): Promise => AuthClient.getDecodedIDToken(), + getDecodedIDToken: (): Promise => AuthClient.getDecodedIDToken(), getHttpClient: (): Promise => AuthClient.getHttpClient(), getIDToken: (): Promise => AuthClient.getIDToken(), getOIDCServiceEndpoints: (): Promise => AuthClient.getOIDCServiceEndpoints(), diff --git a/packages/vue/src/tests/AsgardeoPlugin.test.ts b/packages/vue/src/tests/AsgardeoPlugin.test.ts index 5879c6f80..be94a1ae3 100644 --- a/packages/vue/src/tests/AsgardeoPlugin.test.ts +++ b/packages/vue/src/tests/AsgardeoPlugin.test.ts @@ -20,7 +20,7 @@ import { AuthClientConfig, BasicUserInfo, Config, - DecodedIDTokenPayload, + IdTokenPayload, FetchResponse, Hooks, HttpClientInstance, @@ -213,9 +213,9 @@ describe('asgardeoPlugin', () => { expect(mockAuthAPI.getAccessToken).toHaveBeenCalled(); expect(accessTokenValue).toBe(accessToken); - const decodedIDToken: DecodedIDTokenPayload = {aud: 'client-id', iss: 'https://test.com', sub: 'user-id-123'}; + const decodedIDToken: IdTokenPayload = {aud: 'client-id', iss: 'https://test.com', sub: 'user-id-123'}; mockAuthAPI.getDecodedIDToken.mockResolvedValueOnce(decodedIDToken); - const idToken: DecodedIDTokenPayload = await authContext.getDecodedIDToken(); + const idToken: IdTokenPayload = await authContext.getDecodedIDToken(); expect(mockAuthAPI.getDecodedIDToken).toHaveBeenCalled(); expect(idToken).toMatchObject(decodedIDToken); }); diff --git a/packages/vue/src/tests/auth-api.test.ts b/packages/vue/src/tests/auth-api.test.ts index f842536d4..cb2cb4a40 100644 --- a/packages/vue/src/tests/auth-api.test.ts +++ b/packages/vue/src/tests/auth-api.test.ts @@ -21,7 +21,7 @@ import { type AuthClientConfig, type BasicUserInfo, type Config, - type DecodedIDTokenPayload, + type IdTokenPayload, type FetchResponse, Hooks, type HttpRequestConfig, @@ -349,13 +349,13 @@ describe('AuthAPI', () => { describe('token related methods', () => { it('should call getDecodedIDToken on the client', async () => { - const result: DecodedIDTokenPayload = await authApi.getDecodedIDToken(); + const result: IdTokenPayload = await authApi.getDecodedIDToken(); expect(mockClient.getDecodedIDToken).toHaveBeenCalled(); expect(result).toEqual({sub: 'user-id-123'}); }); it('should call getDecodedIDPIDToken on the client', async () => { - const result: DecodedIDTokenPayload = await authApi.getDecodedIDPIDToken(); + const result: IdTokenPayload = await authApi.getDecodedIDPIDToken(); expect(mockClient.getDecodedIDToken).toHaveBeenCalled(); expect(result).toEqual({sub: 'user-id-123'}); }); diff --git a/packages/vue/src/tests/useAsgardeo.test.ts b/packages/vue/src/tests/useAsgardeo.test.ts index 40ccde7d6..aa2cae9d6 100644 --- a/packages/vue/src/tests/useAsgardeo.test.ts +++ b/packages/vue/src/tests/useAsgardeo.test.ts @@ -19,7 +19,7 @@ import { AsgardeoAuthException, BasicUserInfo, - DecodedIDTokenPayload, + IdTokenPayload, HttpClientInstance, HttpResponse, OIDCEndpoints, @@ -40,7 +40,7 @@ describe('useAsgardeo', () => { error: new AsgardeoAuthException('Some error', 'Error message', 'error'), getAccessToken: vi.fn().mockResolvedValue('token'), getBasicUserInfo: vi.fn().mockResolvedValue({} as BasicUserInfo), - getDecodedIDToken: vi.fn().mockResolvedValue({} as DecodedIDTokenPayload), + getDecodedIDToken: vi.fn().mockResolvedValue({} as IdTokenPayload), getHttpClient: vi.fn().mockResolvedValue({} as HttpClientInstance), getIDToken: vi.fn().mockResolvedValue('id_token'), getOIDCServiceEndpoints: vi.fn().mockResolvedValue({} as OIDCEndpoints), diff --git a/packages/vue/src/types.ts b/packages/vue/src/types.ts index 7e60852a7..1e52871c0 100644 --- a/packages/vue/src/types.ts +++ b/packages/vue/src/types.ts @@ -23,7 +23,7 @@ import { BasicUserInfo, Config, CustomGrantConfig, - DecodedIDTokenPayload, + IdTokenPayload, FetchResponse, Hooks, HttpClientInstance, @@ -96,7 +96,7 @@ export interface AuthContextInterface { error: AsgardeoAuthException; getAccessToken(): Promise; getBasicUserInfo(): Promise; - getDecodedIDToken(): Promise; + getDecodedIDToken(): Promise; getHttpClient(): Promise; getIDToken(): Promise; getOIDCServiceEndpoints(): Promise; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5bb873033..4cfa42beb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,113 +7,275 @@ settings: catalogs: default: '@wso2/eslint-plugin': - specifier: https://gitpkg.now.sh/brionmario/wso2-ui-configs/packages/eslint-plugin?4ee6f6be232d7631999d709a86b91612f1d34ce7 + specifier: https://gitpkg.now.sh/brionmario/wso2-ui-configs/packages/eslint-plugin?a1fc6eb570653c999828aea9f5027cba06af4391 version: 0.1.0 '@wso2/prettier-config': - specifier: https://gitpkg.now.sh/brionmario/wso2-ui-configs/packages/prettier-config?4ee6f6be232d7631999d709a86b91612f1d34ce7 + specifier: https://gitpkg.now.sh/brionmario/wso2-ui-configs/packages/prettier-config?a1fc6eb570653c999828aea9f5027cba06af4391 version: 0.1.0 '@wso2/stylelint-config': - specifier: https://gitpkg.now.sh/brionmario/wso2-ui-configs/packages/stylelint-config?4ee6f6be232d7631999d709a86b91612f1d34ce7 + specifier: https://gitpkg.now.sh/brionmario/wso2-ui-configs/packages/stylelint-config?a1fc6eb570653c999828aea9f5027cba06af4391 version: 0.1.0 - eslint: - specifier: ~8.57.0 - version: 8.57.1 importers: .: devDependencies: '@changesets/changelog-github': - specifier: ^0.5.0 + specifier: ^0.5.1 version: 0.5.1 '@changesets/cli': - specifier: ^2.27.3 - version: 2.28.1 + specifier: ^2.29.4 + version: 2.29.4 '@wso2/eslint-plugin': specifier: 'catalog:' - version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/eslint-plugin?4ee6f6be232d7631999d709a86b91612f1d34ce7(eslint@8.57.1)(typescript@5.1.6) + version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/eslint-plugin?a1fc6eb570653c999828aea9f5027cba06af4391(eslint@8.57.0)(typescript@5.7.3) '@wso2/prettier-config': specifier: 'catalog:' - version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/prettier-config?4ee6f6be232d7631999d709a86b91612f1d34ce7(prettier@3.5.3)(typescript@5.1.6) + version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/prettier-config?a1fc6eb570653c999828aea9f5027cba06af4391(prettier@2.8.8)(typescript@5.7.3) eslint: - specifier: 'catalog:' - version: 8.57.1 + specifier: 8.57.0 + version: 8.57.0 nx: - specifier: 18.2.4 - version: 18.2.4 + specifier: 20.8.1 + version: 20.8.1 prettier: - specifier: ^3.2.5 - version: 3.5.3 + specifier: ^2.6.2 + version: 2.8.8 typescript: - specifier: 5.1.6 - version: 5.1.6 + specifier: ~5.7.2 + version: 5.7.3 docs: devDependencies: vitepress: specifier: ^1.2.2 - version: 1.6.3(@algolia/client-search@5.21.0)(@types/node@22.15.18)(@types/react@18.3.18)(axios@1.8.4)(fuse.js@7.1.0)(jwt-decode@4.0.0)(postcss@8.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1)(search-insights@2.17.3)(terser@5.39.0)(typescript@5.8.3) + version: 1.6.3(@algolia/client-search@5.25.0)(@types/node@22.15.29)(axios@1.9.0)(fuse.js@7.1.0)(jwt-decode@4.0.0)(postcss@8.5.3)(sass@1.89.0)(search-insights@2.17.3)(terser@5.39.2)(typescript@5.8.3) - packages/core: + packages/browser: dependencies: - '@asgardeo/auth-js': - specifier: ^5.0.1 - version: 5.1.1 - csstype: - specifier: ^3.1.3 - version: 3.1.3 - lodash.isempty: - specifier: ^4.4.0 - version: 4.4.0 - lodash.merge: - specifier: ^4.6.2 - version: 4.6.2 + '@asgardeo/javascript': + specifier: workspace:^ + version: link:../javascript + axios: + specifier: ^0.26.0 + version: 0.26.1 + base64url: + specifier: ^3.0.1 + version: 3.0.1 + buffer: + specifier: ^6.0.3 + version: 6.0.3 + core-js: + specifier: ^3.42.0 + version: 3.42.0 + crypto-browserify: + specifier: ^3.12.1 + version: 3.12.1 + esbuild-plugin-polyfill-node: + specifier: ^0.3.0 + version: 0.3.0(esbuild@0.25.4) + fast-sha256: + specifier: ^1.3.0 + version: 1.3.0 + jose: + specifier: ^6.0.11 + version: 6.0.11 + process: + specifier: ^0.11.10 + version: 0.11.10 + randombytes: + specifier: ^2.1.0 + version: 2.1.0 + stream-browserify: + specifier: ^3.0.0 + version: 3.0.0 + tslib: + specifier: ^2.8.1 + version: 2.8.1 devDependencies: - '@rollup/plugin-commonjs': - specifier: ^25.0.7 - version: 25.0.8(rollup@4.35.0) - '@rollup/plugin-dynamic-import-vars': - specifier: ^2.1.2 - version: 2.1.5(rollup@4.35.0) - '@rollup/plugin-node-resolve': - specifier: ^15.2.3 - version: 15.3.1(rollup@4.35.0) - '@rollup/plugin-typescript': - specifier: ^11.1.6 - version: 11.1.6(rollup@4.35.0)(tslib@2.8.1)(typescript@5.1.6) - '@types/lodash.isempty': - specifier: ^4.4.9 - version: 4.4.9 - '@types/lodash.merge': - specifier: ^4.6.9 - version: 4.6.9 + '@testing-library/dom': + specifier: ^10.4.0 + version: 10.4.0 '@types/node': - specifier: ^20.12.7 - version: 20.17.24 + specifier: ^22.15.3 + version: 22.15.18 + '@vitest/browser': + specifier: ^3.1.3 + version: 3.1.3(playwright@1.52.0)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vitest@3.1.3) '@wso2/eslint-plugin': specifier: 'catalog:' - version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/eslint-plugin?4ee6f6be232d7631999d709a86b91612f1d34ce7(eslint@8.57.1)(typescript@5.1.6) + version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/eslint-plugin?a1fc6eb570653c999828aea9f5027cba06af4391(eslint@8.57.0)(typescript@5.7.3) '@wso2/prettier-config': specifier: 'catalog:' - version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/prettier-config?4ee6f6be232d7631999d709a86b91612f1d34ce7(prettier@3.5.3)(typescript@5.1.6) + version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/prettier-config?a1fc6eb570653c999828aea9f5027cba06af4391(prettier@2.8.8)(typescript@5.7.3) + esbuild: + specifier: ^0.25.4 + version: 0.25.4 + esbuild-plugins-node-modules-polyfill: + specifier: ^1.7.0 + version: 1.7.0(esbuild@0.25.4) eslint: + specifier: 8.57.0 + version: 8.57.0 + playwright: + specifier: ^1.52.0 + version: 1.52.0 + prettier: + specifier: ^2.6.2 + version: 2.8.8 + rimraf: + specifier: ^6.0.1 + version: 6.0.1 + typescript: + specifier: ~5.7.2 + version: 5.7.3 + vitest: + specifier: ^3.1.3 + version: 3.1.3(@types/node@22.15.18)(@vitest/browser@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + + packages/javascript: + dependencies: + tslib: + specifier: ^2.8.1 + version: 2.8.1 + devDependencies: + '@types/node': + specifier: ^22.15.3 + version: 22.15.18 + '@wso2/eslint-plugin': + specifier: 'catalog:' + version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/eslint-plugin?a1fc6eb570653c999828aea9f5027cba06af4391(eslint@8.57.0)(typescript@5.7.3) + '@wso2/prettier-config': specifier: 'catalog:' - version: 8.57.1 + version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/prettier-config?a1fc6eb570653c999828aea9f5027cba06af4391(prettier@2.8.8)(typescript@5.7.3) + esbuild: + specifier: ^0.25.4 + version: 0.25.4 + eslint: + specifier: 8.57.0 + version: 8.57.0 prettier: - specifier: ^3.2.5 - version: 3.5.3 - rollup: - specifier: ^4.17.2 - version: 4.35.0 - rollup-plugin-dts: - specifier: ^6.1.0 - version: 6.1.1(rollup@4.35.0)(typescript@5.1.6) + specifier: ^2.6.2 + version: 2.8.8 + rimraf: + specifier: ^6.0.1 + version: 6.0.1 + typescript: + specifier: ~5.7.2 + version: 5.7.3 + vitest: + specifier: ^3.1.3 + version: 3.1.3(@types/node@22.15.18)(@vitest/browser@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + + packages/nextjs: + dependencies: + '@asgardeo/node': + specifier: workspace:^ + version: link:../node + '@asgardeo/react': + specifier: workspace:^ + version: link:../react + '@types/react': + specifier: ^19.1.4 + version: 19.1.5 tslib: + specifier: ^2.8.1 + version: 2.8.1 + devDependencies: + '@types/node': + specifier: ^22.15.3 + version: 22.15.29 + '@wso2/eslint-plugin': + specifier: 'catalog:' + version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/eslint-plugin?a1fc6eb570653c999828aea9f5027cba06af4391(eslint@8.57.0)(typescript@5.7.3) + '@wso2/prettier-config': + specifier: 'catalog:' + version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/prettier-config?a1fc6eb570653c999828aea9f5027cba06af4391(prettier@2.8.8)(typescript@5.7.3) + esbuild: + specifier: ^0.25.4 + version: 0.25.4 + esbuild-plugin-preserve-directives: + specifier: ^0.0.11 + version: 0.0.11(esbuild@0.25.4) + eslint: + specifier: 8.57.0 + version: 8.57.0 + next: + specifier: ^15.3.2 + version: 15.3.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.0) + prettier: specifier: ^2.6.2 + version: 2.8.8 + react: + specifier: ^19.1.0 + version: 19.1.0 + rimraf: + specifier: ^6.0.1 + version: 6.0.1 + typescript: + specifier: ~5.7.2 + version: 5.7.3 + vitest: + specifier: ^3.1.3 + version: 3.1.3(@types/node@22.15.29)(@vitest/browser@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + + packages/node: + dependencies: + '@asgardeo/javascript': + specifier: workspace:^ + version: link:../javascript + base64url: + specifier: ^3.0.1 + version: 3.0.1 + cross-fetch: + specifier: ^4.1.0 + version: 4.1.0 + fast-sha256: + specifier: ^1.3.0 + version: 1.3.0 + jose: + specifier: ^6.0.11 + version: 6.0.11 + memory-cache: + specifier: ^0.2.0 + version: 0.2.0 + secure-random-bytes: + specifier: ^5.0.1 + version: 5.0.1 + tslib: + specifier: ^2.8.1 version: 2.8.1 + uuid: + specifier: ^11.1.0 + version: 11.1.0 + devDependencies: + '@types/node': + specifier: ^22.15.3 + version: 22.15.18 + '@wso2/eslint-plugin': + specifier: 'catalog:' + version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/eslint-plugin?a1fc6eb570653c999828aea9f5027cba06af4391(eslint@8.57.0)(typescript@5.7.3) + '@wso2/prettier-config': + specifier: 'catalog:' + version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/prettier-config?a1fc6eb570653c999828aea9f5027cba06af4391(prettier@2.8.8)(typescript@5.7.3) + esbuild: + specifier: ^0.25.4 + version: 0.25.4 + eslint: + specifier: 8.57.0 + version: 8.57.0 + prettier: + specifier: ^2.6.2 + version: 2.8.8 + rimraf: + specifier: ^6.0.1 + version: 6.0.1 typescript: - specifier: 5.1.6 - version: 5.1.6 + specifier: ~5.7.2 + version: 5.7.3 + vitest: + specifier: ^3.1.3 + version: 3.1.3(@types/node@22.15.18)(@vitest/browser@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) packages/nuxt: dependencies: @@ -122,29 +284,29 @@ importers: version: 0.1.3 '@nuxt/kit': specifier: ^3.16.2 - version: 3.16.2(magicast@0.3.5) + version: 3.17.4(magicast@0.3.5) defu: specifier: ^6.1.4 version: 6.1.4 devDependencies: '@nuxt/devtools': specifier: ^2.4.0 - version: 2.4.0(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) + version: 2.4.1(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3)) '@nuxt/eslint-config': specifier: ^1.3.0 - version: 1.3.0(@vue/compiler-sfc@3.5.13)(eslint@8.57.1)(typescript@5.8.3) + version: 1.4.1(@vue/compiler-sfc@3.5.14)(eslint@8.57.0)(typescript@5.8.3) '@nuxt/module-builder': specifier: ^1.0.1 - version: 1.0.1(@nuxt/cli@3.25.1(magicast@0.3.5))(esbuild@0.25.4)(sass@1.85.1)(typescript@5.8.3)(vue-tsc@2.2.8(typescript@5.8.3))(vue@3.5.13(typescript@5.8.3)) + version: 1.0.1(@nuxt/cli@3.25.1(magicast@0.3.5))(@vue/compiler-core@3.5.14)(esbuild@0.25.4)(sass@1.89.0)(typescript@5.8.3)(vue-tsc@2.2.10(typescript@5.8.3))(vue@3.5.14(typescript@5.8.3)) '@nuxt/schema': specifier: ^3.16.2 - version: 3.16.2 + version: 3.17.4 '@nuxt/test-utils': specifier: ^3.17.2 - version: 3.17.2(@types/node@22.14.1)(@vue/test-utils@2.4.6)(jiti@2.4.2)(jsdom@26.0.0)(magicast@0.3.5)(sass@1.85.1)(terser@5.39.0)(typescript@5.8.3)(vitest@3.1.1(@types/node@22.14.1)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(yaml@2.7.1) + version: 3.19.0(@types/node@22.15.29)(@vue/test-utils@2.4.6)(jiti@2.4.2)(jsdom@26.1.0)(magicast@0.3.5)(playwright-core@1.52.0)(sass@1.89.0)(terser@5.39.2)(typescript@5.8.3)(vitest@3.1.3)(yaml@2.8.0) '@types/node': specifier: latest - version: 22.14.1 + version: 22.15.29 changelogen: specifier: ^0.6.1 version: 0.6.1(magicast@0.3.5) @@ -152,129 +314,99 @@ importers: specifier: ^2.0.0 version: 2.0.0 eslint: - specifier: 'catalog:' - version: 8.57.1 + specifier: 8.57.0 + version: 8.57.0 nuxt: specifier: ^3.16.2 - version: 3.16.2(@parcel/watcher@2.5.1)(@types/node@22.14.1)(db0@0.3.1)(eslint@8.57.1)(ioredis@5.6.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.39.0)(sass@1.85.1)(terser@5.39.0)(typescript@5.8.3)(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue-tsc@2.2.8(typescript@5.8.3))(yaml@2.7.1) + version: 3.17.4(@parcel/watcher@2.5.1)(@types/node@22.15.29)(db0@0.3.2)(eslint@8.57.0)(ioredis@5.6.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.40.2)(sass@1.89.0)(terser@5.39.2)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue-tsc@2.2.10(typescript@5.8.3))(yaml@2.8.0) typescript: specifier: ~5.8.3 version: 5.8.3 vitest: specifier: ^3.1.1 - version: 3.1.1(@types/node@22.14.1)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + version: 3.1.3(@types/node@22.15.29)(@vitest/browser@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) vue-tsc: specifier: ^2.2.8 - version: 2.2.8(typescript@5.8.3) + version: 2.2.10(typescript@5.8.3) packages/react: dependencies: - '@asgardeo/js': - specifier: '*' - version: 0.1.3 - '@oxygen-ui/react': - specifier: ^1.11.0 - version: 1.15.2(0356e0e967205ddd07cd0bc9fd616469) - base64url: - specifier: ^3.0.1 - version: 3.0.1 - buffer: - specifier: ^6.0.3 - version: 6.0.3 + '@asgardeo/browser': + specifier: workspace:^ + version: link:../browser + '@types/react-dom': + specifier: ^19.1.5 + version: 19.1.5(@types/react@19.1.5) clsx: specifier: ^2.1.1 version: 2.1.1 - fast-sha256: - specifier: ^1.3.0 - version: 1.3.0 - jose: - specifier: ^5.3.0 - version: 5.10.0 - randombytes: - specifier: ^2.1.0 - version: 2.1.0 + esbuild: + specifier: ^0.25.4 + version: 0.25.4 + react-dom: + specifier: ^19.1.0 + version: 19.1.0(react@19.1.0) + tslib: + specifier: ^2.8.1 + version: 2.8.1 devDependencies: - '@rollup/plugin-commonjs': - specifier: ^25.0.7 - version: 25.0.8(rollup@4.35.0) - '@rollup/plugin-image': - specifier: ^3.0.3 - version: 3.0.3(rollup@4.35.0) - '@rollup/plugin-node-resolve': - specifier: ^15.2.3 - version: 15.3.1(rollup@4.35.0) - '@rollup/plugin-typescript': - specifier: ^11.1.6 - version: 11.1.6(rollup@4.35.0)(tslib@2.8.1)(typescript@5.1.6) + '@testing-library/dom': + specifier: ^10.4.0 + version: 10.4.0 '@types/node': - specifier: ^20.12.7 - version: 20.17.24 - '@types/randombytes': - specifier: ^2.0.3 - version: 2.0.3 + specifier: ^22.15.3 + version: 22.15.18 '@types/react': - specifier: ^18.2.79 - version: 18.3.18 - '@types/react-dom': - specifier: ^18.2.25 - version: 18.3.5(@types/react@18.3.18) + specifier: ^19.1.4 + version: 19.1.5 + '@vitest/browser': + specifier: ^3.1.3 + version: 3.1.3(playwright@1.52.0)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vitest@3.1.3) '@wso2/eslint-plugin': specifier: 'catalog:' - version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/eslint-plugin?4ee6f6be232d7631999d709a86b91612f1d34ce7(eslint@8.57.1)(typescript@5.1.6) + version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/eslint-plugin?a1fc6eb570653c999828aea9f5027cba06af4391(eslint@8.57.0)(typescript@5.7.3) '@wso2/prettier-config': specifier: 'catalog:' - version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/prettier-config?4ee6f6be232d7631999d709a86b91612f1d34ce7(prettier@3.5.3)(typescript@5.1.6) - '@wso2/stylelint-config': - specifier: 'catalog:' - version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/stylelint-config?4ee6f6be232d7631999d709a86b91612f1d34ce7(postcss@8.5.3)(stylelint@15.1.0(typescript@5.1.6))(typescript@5.1.6) + version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/prettier-config?a1fc6eb570653c999828aea9f5027cba06af4391(prettier@2.8.8)(typescript@5.7.3) + esbuild-plugin-preserve-directives: + specifier: ^0.0.11 + version: 0.0.11(esbuild@0.25.4) eslint: - specifier: 'catalog:' - version: 8.57.1 + specifier: 8.57.0 + version: 8.57.0 + playwright: + specifier: ^1.52.0 + version: 1.52.0 prettier: - specifier: ^3.2.5 - version: 3.5.3 - react: - specifier: ^18.2.0 - version: 18.3.1 - react-dom: - specifier: ^18.2.0 - version: 18.3.1(react@18.3.1) - rollup: - specifier: ^4.17.2 - version: 4.35.0 - rollup-plugin-dts: - specifier: ^6.1.0 - version: 6.1.1(rollup@4.35.0)(typescript@5.1.6) - rollup-plugin-polyfill-node: - specifier: ^0.13.0 - version: 0.13.0(rollup@4.35.0) - rollup-plugin-styles: - specifier: ^4.0.0 - version: 4.0.0(rollup@4.35.0) - sass: - specifier: ^1.75.0 - version: 1.85.1 - stylelint: - specifier: 15.1.0 - version: 15.1.0(typescript@5.1.6) - tslib: specifier: ^2.6.2 - version: 2.8.1 + version: 2.8.8 + react: + specifier: ^19.1.0 + version: 19.1.0 + rimraf: + specifier: ^6.0.1 + version: 6.0.1 typescript: - specifier: 5.1.6 - version: 5.1.6 + specifier: ~5.7.2 + version: 5.7.3 + vitest: + specifier: ^3.1.3 + version: 3.1.3(@types/node@22.15.18)(@vitest/browser@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + vitest-browser-react: + specifier: ^0.1.1 + version: 0.1.1(@types/react-dom@19.1.5(@types/react@19.1.5))(@types/react@19.1.5)(@vitest/browser@3.1.3)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(vitest@3.1.3) packages/vue: dependencies: '@asgardeo/auth-spa': specifier: ^3.1.4 - version: 3.1.4 + version: 3.2.0 '@asgardeo/js': specifier: '*' version: 0.1.3 '@vitejs/plugin-vue': specifier: ^5.0.0 - version: 5.2.1(vite@6.2.2(@types/node@20.17.24)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.1.6)) + version: 5.2.4(vite@6.3.5(@types/node@20.17.50)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.1.6)) base64url: specifier: ^3.0.1 version: 3.0.1 @@ -295,68 +427,68 @@ importers: version: 2.1.0 vue: specifier: '>=3.5.13' - version: 3.5.13(typescript@5.1.6) + version: 3.5.14(typescript@5.1.6) devDependencies: '@rollup/plugin-commonjs': specifier: ^25.0.7 - version: 25.0.8(rollup@4.35.0) + version: 25.0.8(rollup@4.40.2) '@rollup/plugin-image': specifier: ^3.0.3 - version: 3.0.3(rollup@4.35.0) + version: 3.0.3(rollup@4.40.2) '@rollup/plugin-node-resolve': specifier: ^15.2.3 - version: 15.3.1(rollup@4.35.0) + version: 15.3.1(rollup@4.40.2) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.35.0)(tslib@2.8.1)(typescript@5.1.6) + version: 11.1.6(rollup@4.40.2)(tslib@2.8.1)(typescript@5.1.6) '@types/node': specifier: ^20.12.7 - version: 20.17.24 + version: 20.17.50 '@vitest/coverage-v8': specifier: 3.0.8 - version: 3.0.8(vitest@3.0.8(@types/node@20.17.24)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) + version: 3.0.8(vitest@3.1.3(@types/node@20.17.50)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0)) '@vitest/web-worker': specifier: ^3.0.8 - version: 3.0.8(vitest@3.0.8(@types/node@20.17.24)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) + version: 3.1.4(vitest@3.1.3(@types/node@20.17.50)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0)) '@vue/eslint-config-prettier': specifier: ^8.0.0 - version: 8.0.0(eslint@8.57.1)(prettier@3.5.3) + version: 8.0.0(eslint@8.57.0)(prettier@3.5.3) '@vue/eslint-config-typescript': specifier: ^12.0.0 - version: 12.0.0(eslint-plugin-vue@10.0.0(eslint@8.57.1)(vue-eslint-parser@10.1.1(eslint@8.57.1)))(eslint@8.57.1)(typescript@5.1.6) + version: 12.0.0(eslint-plugin-vue@10.1.0(eslint@8.57.0)(vue-eslint-parser@10.1.3(eslint@8.57.0)))(eslint@8.57.0)(typescript@5.1.6) '@vue/test-utils': specifier: ^2.4.6 version: 2.4.6 '@wso2/eslint-plugin': specifier: 'catalog:' - version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/eslint-plugin?4ee6f6be232d7631999d709a86b91612f1d34ce7(eslint@8.57.1)(typescript@5.1.6) + version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/eslint-plugin?a1fc6eb570653c999828aea9f5027cba06af4391(eslint@8.57.0)(typescript@5.1.6) '@wso2/prettier-config': specifier: 'catalog:' - version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/prettier-config?4ee6f6be232d7631999d709a86b91612f1d34ce7(prettier@3.5.3)(typescript@5.1.6) + version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/prettier-config?a1fc6eb570653c999828aea9f5027cba06af4391(prettier@3.5.3)(typescript@5.1.6) '@wso2/stylelint-config': specifier: 'catalog:' - version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/stylelint-config?4ee6f6be232d7631999d709a86b91612f1d34ce7(postcss@8.5.3)(stylelint@15.1.0(typescript@5.1.6))(typescript@5.1.6) + version: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/stylelint-config?a1fc6eb570653c999828aea9f5027cba06af4391(postcss@8.5.3)(stylelint@15.1.0(typescript@5.1.6))(typescript@5.1.6) eslint: - specifier: 'catalog:' - version: 8.57.1 + specifier: 8.57.0 + version: 8.57.0 prettier: specifier: ^3.2.5 version: 3.5.3 rollup: specifier: ^4.17.2 - version: 4.35.0 + version: 4.40.2 rollup-plugin-dts: specifier: ^6.1.0 - version: 6.1.1(rollup@4.35.0)(typescript@5.1.6) + version: 6.2.1(rollup@4.40.2)(typescript@5.1.6) rollup-plugin-polyfill-node: specifier: ^0.13.0 - version: 0.13.0(rollup@4.35.0) + version: 0.13.0(rollup@4.40.2) rollup-plugin-styles: specifier: ^4.0.0 - version: 4.0.0(rollup@4.35.0) + version: 4.0.0(rollup@4.40.2) sass: specifier: ^1.75.0 - version: 1.85.1 + version: 1.89.0 stylelint: specifier: 15.1.0 version: 15.1.0(typescript@5.1.6) @@ -368,159 +500,93 @@ importers: version: 5.1.6 vitest: specifier: ^3.0.8 - version: 3.0.8(@types/node@20.17.24)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + version: 3.1.3(@types/node@20.17.50)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) vue-tsc: specifier: ^2.2.2 - version: 2.2.8(typescript@5.1.6) + version: 2.2.10(typescript@5.1.6) - recipes/nuxt-vite: + recipes/create-next-app-ts-app-router: dependencies: - '@asgardeo/nuxt': - specifier: workspace:* - version: link:../../packages/nuxt - nuxt: - specifier: ^3.17.3 - version: 3.17.3(@parcel/watcher@2.5.1)(@types/node@22.15.18)(db0@0.3.2)(eslint@8.57.1)(ioredis@5.6.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.40.2)(sass@1.85.1)(terser@5.39.0)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(yaml@2.7.1) - vue: - specifier: ^3.5.13 - version: 3.5.13(typescript@5.8.3) - vue-router: - specifier: ^4.5.1 - version: 4.5.1(vue@3.5.13(typescript@5.8.3)) + '@asgardeo/nextjs': + specifier: workspace:^ + version: link:../../packages/nextjs + next: + specifier: 15.3.2 + version: 15.3.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.0) + react: + specifier: ^19.0.0 + version: 19.1.0 + react-dom: + specifier: ^19.0.0 + version: 19.1.0(react@19.1.0) + devDependencies: + '@eslint/eslintrc': + specifier: ^3 + version: 3.3.1 + '@types/node': + specifier: ^20 + version: 20.17.50 + '@types/react': + specifier: ^19 + version: 19.1.5 + '@types/react-dom': + specifier: ^19 + version: 19.1.5(@types/react@19.1.5) + eslint: + specifier: ^9 + version: 9.28.0(jiti@2.4.2) + eslint-config-next: + specifier: 15.3.2 + version: 15.3.2(eslint-plugin-import-x@4.12.2(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + typescript: + specifier: ^5 + version: 5.8.3 - recipes/react-vite: + recipes/vite-react-ts: dependencies: '@asgardeo/react': - specifier: '*' - version: 0.2.4(0356e0e967205ddd07cd0bc9fd616469) - '@vitejs/plugin-basic-ssl': - specifier: ^1.1.0 - version: 1.2.0(vite@5.4.14(@types/node@22.15.18)(sass@1.85.1)(terser@5.39.0)) + specifier: workspace:^ + version: link:../../packages/react react: - specifier: ^18.2.0 - version: 18.3.1 + specifier: ^19.1.0 + version: 19.1.0 react-dom: - specifier: ^18.2.0 - version: 18.3.1(react@18.3.1) - react-vite: - specifier: 'link:' - version: 'link:' - vite-plugin-node-polyfills: - specifier: ^0.21.0 - version: 0.21.0(rollup@4.40.2)(vite@5.4.14(@types/node@22.15.18)(sass@1.85.1)(terser@5.39.0)) + specifier: ^19.1.0 + version: 19.1.0(react@19.1.0) devDependencies: + '@eslint/js': + specifier: ^9.25.0 + version: 9.27.0 '@types/react': - specifier: ^18.2.66 - version: 18.3.18 + specifier: ^19.1.2 + version: 19.1.5 '@types/react-dom': - specifier: ^18.2.22 - version: 18.3.5(@types/react@18.3.18) - '@typescript-eslint/eslint-plugin': - specifier: ^7.2.0 - version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6) - '@typescript-eslint/parser': - specifier: ^7.2.0 - version: 7.18.0(eslint@8.57.1)(typescript@5.1.6) + specifier: ^19.1.2 + version: 19.1.5(@types/react@19.1.5) '@vitejs/plugin-react': - specifier: ^4.2.1 - version: 4.3.4(vite@5.4.14(@types/node@22.15.18)(sass@1.85.1)(terser@5.39.0)) + specifier: ^4.4.1 + version: 4.5.1(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0)) eslint: - specifier: 'catalog:' - version: 8.57.1 + specifier: ^9.25.0 + version: 9.28.0(jiti@2.4.2) eslint-plugin-react-hooks: - specifier: ^4.6.0 - version: 4.6.2(eslint@8.57.1) + specifier: ^5.2.0 + version: 5.2.0(eslint@9.28.0(jiti@2.4.2)) eslint-plugin-react-refresh: - specifier: ^0.4.6 - version: 0.4.19(eslint@8.57.1) + specifier: ^0.4.19 + version: 0.4.20(eslint@9.28.0(jiti@2.4.2)) + globals: + specifier: ^16.0.0 + version: 16.1.0 typescript: - specifier: 5.1.6 - version: 5.1.6 - vite: - specifier: ^5.2.0 - version: 5.4.14(@types/node@22.15.18)(sass@1.85.1)(terser@5.39.0) - - recipes/vue-vite: - dependencies: - '@asgardeo/vue': - specifier: workspace:* - version: link:../../packages/vue - '@vitejs/plugin-vue': - specifier: ^5.2.1 - version: 5.2.1(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.1.6)) + specifier: ~5.8.3 + version: 5.8.3 + typescript-eslint: + specifier: ^8.30.1 + version: 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) vite: - specifier: ^6.1.0 - version: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vite-plugin-vue-devtools: - specifier: ^7.7.2 - version: 7.7.2(rollup@4.40.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.1.6)) - vitest: - specifier: ^3.0.5 - version: 3.0.8(@types/node@22.13.10)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vue: - specifier: ^3.5.13 - version: 3.5.13(typescript@5.1.6) - vue-router: - specifier: ^4.5.0 - version: 4.5.0(vue@3.5.13(typescript@5.1.6)) - devDependencies: - '@eslint/js': - specifier: ^9.22.0 - version: 9.22.0 - '@tsconfig/node22': - specifier: ^22.0.0 - version: 22.0.0 - '@types/jsdom': - specifier: ^21.1.7 - version: 21.1.7 - '@types/node': - specifier: ^22.13.4 - version: 22.13.10 - '@typescript-eslint/eslint-plugin': - specifier: ^7.2.0 - version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6) - '@typescript-eslint/parser': - specifier: ^7.2.0 - version: 7.18.0(eslint@8.57.1)(typescript@5.1.6) - '@vitest/eslint-plugin': - specifier: 1.1.31 - version: 1.1.31(@typescript-eslint/utils@8.30.1(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6)(vitest@3.0.8(@types/node@22.13.10)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) - '@vue/eslint-config-prettier': - specifier: ^10.2.0 - version: 10.2.0(eslint@8.57.1)(prettier@3.5.3) - '@vue/eslint-config-typescript': - specifier: ^14.4.0 - version: 14.5.0(eslint-plugin-vue@9.33.0(eslint@8.57.1))(eslint@8.57.1)(typescript@5.1.6) - '@vue/test-utils': - specifier: ^2.4.6 - version: 2.4.6 - '@vue/tsconfig': - specifier: ^0.7.0 - version: 0.7.0(typescript@5.1.6)(vue@3.5.13(typescript@5.1.6)) - eslint: - specifier: 'catalog:' - version: 8.57.1 - eslint-plugin-vue: - specifier: ^9.33.0 - version: 9.33.0(eslint@8.57.1) - jiti: - specifier: ^2.4.2 - version: 2.4.2 - jsdom: - specifier: ^26.0.0 - version: 26.0.0 - npm-run-all2: - specifier: ^7.0.2 - version: 7.0.2 - prettier: - specifier: ^3.5.1 - version: 3.5.3 - typescript: - specifier: 5.1.6 - version: 5.1.6 - vue-tsc: - specifier: ^2.2.2 - version: 2.2.8(typescript@5.1.6) + specifier: ^6.3.5 + version: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) packages: @@ -544,270 +610,213 @@ packages: '@algolia/client-search': '>= 4.9.1 < 6' algoliasearch: '>= 4.9.1 < 6' - '@algolia/client-abtesting@5.21.0': - resolution: {integrity: sha512-I239aSmXa3pXDhp3AWGaIfesqJBNFA7drUM8SIfNxMIzvQXUnHRf4rW1o77QXLI/nIClNsb8KOLaB62gO9LnlQ==} + '@algolia/client-abtesting@5.25.0': + resolution: {integrity: sha512-1pfQulNUYNf1Tk/svbfjfkLBS36zsuph6m+B6gDkPEivFmso/XnRgwDvjAx80WNtiHnmeNjIXdF7Gos8+OLHqQ==} engines: {node: '>= 14.0.0'} - '@algolia/client-analytics@5.21.0': - resolution: {integrity: sha512-OxoUfeG9G4VE4gS7B4q65KkHzdGsQsDwxQfR5J9uKB8poSGuNlHJWsF3ABqCkc5VliAR0m8KMjsQ9o/kOpEGnQ==} + '@algolia/client-analytics@5.25.0': + resolution: {integrity: sha512-AFbG6VDJX/o2vDd9hqncj1B6B4Tulk61mY0pzTtzKClyTDlNP0xaUiEKhl6E7KO9I/x0FJF5tDCm0Hn6v5x18A==} engines: {node: '>= 14.0.0'} - '@algolia/client-common@5.21.0': - resolution: {integrity: sha512-iHLgDQFyZNe9M16vipbx6FGOA8NoMswHrfom/QlCGoyh7ntjGvfMb+J2Ss8rRsAlOWluv8h923Ku3QVaB0oWDQ==} + '@algolia/client-common@5.25.0': + resolution: {integrity: sha512-il1zS/+Rc6la6RaCdSZ2YbJnkQC6W1wiBO8+SH+DE6CPMWBU6iDVzH0sCKSAtMWl9WBxoN6MhNjGBnCv9Yy2bA==} engines: {node: '>= 14.0.0'} - '@algolia/client-insights@5.21.0': - resolution: {integrity: sha512-y7XBO9Iwb75FLDl95AYcWSLIViJTpR5SUUCyKsYhpP9DgyUqWbISqDLXc96TS9shj+H+7VsTKA9cJK8NUfVN6g==} + '@algolia/client-insights@5.25.0': + resolution: {integrity: sha512-blbjrUH1siZNfyCGeq0iLQu00w3a4fBXm0WRIM0V8alcAPo7rWjLbMJMrfBtzL9X5ic6wgxVpDADXduGtdrnkw==} engines: {node: '>= 14.0.0'} - '@algolia/client-personalization@5.21.0': - resolution: {integrity: sha512-6KU658lD9Tss4oCX6c/O15tNZxw7vR+WAUG95YtZzYG/KGJHTpy2uckqbMmC2cEK4a86FAq4pH5azSJ7cGMjuw==} + '@algolia/client-personalization@5.25.0': + resolution: {integrity: sha512-aywoEuu1NxChBcHZ1pWaat0Plw7A8jDMwjgRJ00Mcl7wGlwuPt5dJ/LTNcg3McsEUbs2MBNmw0ignXBw9Tbgow==} engines: {node: '>= 14.0.0'} - '@algolia/client-query-suggestions@5.21.0': - resolution: {integrity: sha512-pG6MyVh1v0X+uwrKHn3U+suHdgJ2C+gug+UGkNHfMELHMsEoWIAQhxMBOFg7hCnWBFjQnuq6qhM3X9X5QO3d9Q==} + '@algolia/client-query-suggestions@5.25.0': + resolution: {integrity: sha512-a/W2z6XWKjKjIW1QQQV8PTTj1TXtaKx79uR3NGBdBdGvVdt24KzGAaN7sCr5oP8DW4D3cJt44wp2OY/fZcPAVA==} engines: {node: '>= 14.0.0'} - '@algolia/client-search@5.21.0': - resolution: {integrity: sha512-nZfgJH4njBK98tFCmCW1VX/ExH4bNOl9DSboxeXGgvhoL0fG1+4DDr/mrLe21OggVCQqHwXBMh6fFInvBeyhiQ==} + '@algolia/client-search@5.25.0': + resolution: {integrity: sha512-9rUYcMIBOrCtYiLX49djyzxqdK9Dya/6Z/8sebPn94BekT+KLOpaZCuc6s0Fpfq7nx5J6YY5LIVFQrtioK9u0g==} engines: {node: '>= 14.0.0'} - '@algolia/ingestion@1.21.0': - resolution: {integrity: sha512-k6MZxLbZphGN5uRri9J/krQQBjUrqNcScPh985XXEFXbSCRvOPKVtjjLdVjGVHXXPOQgKrIZHxIdRNbHS+wVuA==} + '@algolia/ingestion@1.25.0': + resolution: {integrity: sha512-jJeH/Hk+k17Vkokf02lkfYE4A+EJX+UgnMhTLR/Mb+d1ya5WhE+po8p5a/Nxb6lo9OLCRl6w3Hmk1TX1e9gVbQ==} engines: {node: '>= 14.0.0'} - '@algolia/monitoring@1.21.0': - resolution: {integrity: sha512-FiW5nnmyHvaGdorqLClw3PM6keXexAMiwbwJ9xzQr4LcNefLG3ln82NafRPgJO/z0dETAOKjds5aSmEFMiITHQ==} + '@algolia/monitoring@1.25.0': + resolution: {integrity: sha512-Ls3i1AehJ0C6xaHe7kK9vPmzImOn5zBg7Kzj8tRYIcmCWVyuuFwCIsbuIIz/qzUf1FPSWmw0TZrGeTumk2fqXg==} engines: {node: '>= 14.0.0'} - '@algolia/recommend@5.21.0': - resolution: {integrity: sha512-+JXavbbliaLmah5QNgc/TDW/+r0ALa+rGhg5Y7+pF6GpNnzO0L+nlUaDNE8QbiJfz54F9BkwFUnJJeRJAuzTFw==} + '@algolia/recommend@5.25.0': + resolution: {integrity: sha512-79sMdHpiRLXVxSjgw7Pt4R1aNUHxFLHiaTDnN2MQjHwJ1+o3wSseb55T9VXU4kqy3m7TUme3pyRhLk5ip/S4Mw==} engines: {node: '>= 14.0.0'} - '@algolia/requester-browser-xhr@5.21.0': - resolution: {integrity: sha512-Iw+Yj5hOmo/iixHS94vEAQ3zi5GPpJywhfxn1el/zWo4AvPIte/+1h9Ywgw/+3M7YBj4jgAkScxjxQCxzLBsjA==} + '@algolia/requester-browser-xhr@5.25.0': + resolution: {integrity: sha512-JLaF23p1SOPBmfEqozUAgKHQrGl3z/Z5RHbggBu6s07QqXXcazEsub5VLonCxGVqTv6a61AAPr8J1G5HgGGjEw==} engines: {node: '>= 14.0.0'} - '@algolia/requester-fetch@5.21.0': - resolution: {integrity: sha512-Z00SRLlIFj3SjYVfsd9Yd3kB3dUwQFAkQG18NunWP7cix2ezXpJqA+xAoEf9vc4QZHdxU3Gm8gHAtRiM2iVaTQ==} + '@algolia/requester-fetch@5.25.0': + resolution: {integrity: sha512-rtzXwqzFi1edkOF6sXxq+HhmRKDy7tz84u0o5t1fXwz0cwx+cjpmxu/6OQKTdOJFS92JUYHsG51Iunie7xbqfQ==} engines: {node: '>= 14.0.0'} - '@algolia/requester-node-http@5.21.0': - resolution: {integrity: sha512-WqU0VumUILrIeVYCTGZlyyZoC/tbvhiyPxfGRRO1cSjxN558bnJLlR2BvS0SJ5b75dRNK7HDvtXo2QoP9eLfiA==} + '@algolia/requester-node-http@5.25.0': + resolution: {integrity: sha512-ZO0UKvDyEFvyeJQX0gmZDQEvhLZ2X10K+ps6hViMo1HgE2V8em00SwNsQ+7E/52a+YiBkVWX61pJJJE44juDMQ==} engines: {node: '>= 14.0.0'} '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@antfu/install-pkg@1.0.0': - resolution: {integrity: sha512-xvX6P/lo1B3ej0OsaErAjqgFYzYVcJpamjLAFLYh9vRJngBrMoUG7aVnrGTeqM7yxbyTD5p3F2+0/QUEh8Vzhw==} + '@antfu/install-pkg@1.1.0': + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} - '@antfu/utils@0.7.10': - resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==} - - '@asamuzakjp/css-color@3.1.1': - resolution: {integrity: sha512-hpRD68SV2OMcZCsrbdkccTw5FXjNDLo5OuqSHyHZfwweGsDWZwDJ2+gONyNAbazZclobMirACLw0lk8WVxIqxA==} + '@asamuzakjp/css-color@3.1.7': + resolution: {integrity: sha512-Ok5fYhtwdyJQmU1PpEv6Si7Y+A4cYb8yNM9oiIJC9TzXPMuN9fvdonKJqcnz9TbFqV6bQ8z0giRq0iaOpGZV2g==} '@asgardeo/auth-js@2.0.15': resolution: {integrity: sha512-ciMLhrm/M//CvyMpCvaoA82S3tKvB529L+MwKKBbRZFe+d0HRPuDfruDhclWl7i07XO1+AVp9Dy1MdUDkhzR4Q==} - '@asgardeo/auth-js@5.1.1': - resolution: {integrity: sha512-yIgBKvHbt9ENczm2n3FGPET/Xf0I9H+Jm6oMXb8ClB/5m5qygHLoF3bsiDlzNuw3wuz8RH8F+waRudVI+IoLtQ==} + '@asgardeo/auth-js@5.1.2': + resolution: {integrity: sha512-fGfUorhUwUSXC/sETTlRbXJ0kMwcLKvVXCieePnxg2AVeiy1lFdRqZt1zsnr4/rd0jd/woYBE96rOAS5fVGFPw==} '@asgardeo/auth-node@0.1.3': resolution: {integrity: sha512-92mruI26puw7Cm3CgeVCBgUZ5FduAzEb/Pf7UMDsKJOQX5N0OjKzRoblYSDvGaFxs2gbU9BvqIp+UpPHoTboIQ==} - '@asgardeo/auth-spa@3.1.4': - resolution: {integrity: sha512-ToDPbwNUY7hOK+vQbZWILe1n1gCxs6s+qZAUCjR0SmAEzf72rFHN6wv0Xg4e91MI8pb4xVJ3JmtJhDX4To8Tog==} + '@asgardeo/auth-spa@3.2.0': + resolution: {integrity: sha512-ptNeWyccApqpMVi9t1RYI95d0/jCS1Zs7qh9uU2c9FbTIquv2xMbJZhUCmU9Ana3IC+ouS53amxcUGZSVrh58g==} '@asgardeo/js@0.1.3': resolution: {integrity: sha512-k7dtodvqqIXOcBUxqTPwm7ChdX5bWl2K70eFQDmnha4bNVcNrsNOzPt4rbIAntOjfUwJpg05YO/ZIV4lZwfB8Q==} - '@asgardeo/react@0.2.4': - resolution: {integrity: sha512-MhwsLL+BFdEVPsb3Ql9to0XYc1sPshAPCLpqCLNFemafKOP+bP07mb/VHricEp5OeIOHkxSMIcMVjJ8B1L8H/g==} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - - '@babel/code-frame@7.26.2': - resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} - engines: {node: '>=6.9.0'} - '@babel/code-frame@7.27.1': resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.26.8': - resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} + '@babel/compat-data@7.27.2': + resolution: {integrity: sha512-TUtMJYRPyUb/9aU8f3K0mjmjf6M9N5Woshn2CS6nqJSeJtTtQcpLUXjGt9vbF8ZGff0El99sWkLgzwW3VXnxZQ==} engines: {node: '>=6.9.0'} - '@babel/core@7.26.10': - resolution: {integrity: sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==} + '@babel/core@7.27.1': + resolution: {integrity: sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==} engines: {node: '>=6.9.0'} - '@babel/eslint-parser@7.26.10': - resolution: {integrity: sha512-QsfQZr4AiLpKqn7fz+j7SN+f43z2DZCgGyYbNJ2vJOqKfG4E6MZer1+jqGZqKJaxq/gdO2DC/nUu45+pOL5p2Q==} + '@babel/eslint-parser@7.27.1': + resolution: {integrity: sha512-q8rjOuadH0V6Zo4XLMkJ3RMQ9MSBqwaDByyYB0izsYdaIWGNLmEblbCOf1vyFHICcg16CD7Fsi51vcQnYxmt6Q==} engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} peerDependencies: '@babel/core': ^7.11.0 eslint: ^7.5.0 || ^8.0.0 || ^9.0.0 - '@babel/generator@7.26.10': - resolution: {integrity: sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==} + '@babel/generator@7.27.1': + resolution: {integrity: sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==} engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.25.9': - resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} + '@babel/helper-annotate-as-pure@7.27.1': + resolution: {integrity: sha512-WnuuDILl9oOBbKnb4L+DyODx7iC47XfzmNCpTttFsSp6hTG7XZxu60+4IO+2/hPfcGOoKbFiwoI/+zwARbNQow==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.26.5': - resolution: {integrity: sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==} + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} engines: {node: '>=6.9.0'} - '@babel/helper-create-class-features-plugin@7.26.9': - resolution: {integrity: sha512-ubbUqCofvxPRurw5L8WTsCLSkQiVpov4Qx0WMA+jUN+nXBK8ADPlJO1grkFw5CWKC5+sZSOfuGMdX1aI1iT9Sg==} + '@babel/helper-create-class-features-plugin@7.27.1': + resolution: {integrity: sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-member-expression-to-functions@7.25.9': - resolution: {integrity: sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==} + '@babel/helper-member-expression-to-functions@7.27.1': + resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.25.9': - resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.26.0': - resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} + '@babel/helper-module-transforms@7.27.1': + resolution: {integrity: sha512-9yHn519/8KvTU5BjTVEEeIM3w9/2yXNKoD82JifINImhpKkARMJKPP59kLo+BafpdN5zgNeIcS4jsGDmd3l58g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-optimise-call-expression@7.25.9': - resolution: {integrity: sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==} + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.26.5': - resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} engines: {node: '>=6.9.0'} - '@babel/helper-replace-supers@7.26.5': - resolution: {integrity: sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==} + '@babel/helper-replace-supers@7.27.1': + resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-skip-transparent-expression-wrappers@7.25.9': - resolution: {integrity: sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.25.9': - resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} engines: {node: '>=6.9.0'} '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.25.9': - resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} - engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.27.1': resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.25.9': - resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.26.10': - resolution: {integrity: sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==} + '@babel/helpers@7.27.1': + resolution: {integrity: sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==} engines: {node: '>=6.9.0'} - '@babel/parser@7.26.10': - resolution: {integrity: sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/parser@7.27.0': - resolution: {integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==} + '@babel/parser@7.27.2': + resolution: {integrity: sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-proposal-decorators@7.25.9': - resolution: {integrity: sha512-smkNLL/O1ezy9Nhy4CNosc4Va+1wo5w4gzSZeLe6y6dM4mmHfYOCPolXQPHQxonZCF+ZyebxN9vqOolkYrSn5g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-decorators@7.25.9': - resolution: {integrity: sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-attributes@7.26.0': - resolution: {integrity: sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-meta@7.10.4': - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-jsx@7.25.9': - resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-typescript@7.25.9': - resolution: {integrity: sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==} + '@babel/plugin-syntax-typescript@7.27.1': + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx-self@7.25.9': - resolution: {integrity: sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==} + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx-source@7.25.9': - resolution: {integrity: sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==} + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.26.8': - resolution: {integrity: sha512-bME5J9AC8ChwA7aEPJ6zym3w7aObZULHhbNLU0bKUhKsAkylkzUdq+0kdymh9rzi8nlNFl2bmldFBCKNJBUpuw==} + '@babel/plugin-transform-typescript@7.27.1': + resolution: {integrity: sha512-Q5sT5+O4QUebHdbwKedFBEwRLb02zJ7r4A5Gg2hUoLuU3FjdMcyqcywqUrLCaDsFCxzokf7u9kuy7qz51YUuAg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.26.10': - resolution: {integrity: sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==} - engines: {node: '>=6.9.0'} - - '@babel/template@7.26.9': - resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.26.10': - resolution: {integrity: sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A==} + '@babel/runtime@7.27.1': + resolution: {integrity: sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==} engines: {node: '>=6.9.0'} - '@babel/types@7.26.10': - resolution: {integrity: sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==} + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} - '@babel/types@7.27.0': - resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==} + '@babel/traverse@7.27.1': + resolution: {integrity: sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==} engines: {node: '>=6.9.0'} '@babel/types@7.27.1': @@ -818,11 +827,11 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@changesets/apply-release-plan@7.0.10': - resolution: {integrity: sha512-wNyeIJ3yDsVspYvHnEz1xQDq18D9ifed3lI+wxRQRK4pArUcuHgCTrHv0QRnnwjhVCQACxZ+CBih3wgOct6UXw==} + '@changesets/apply-release-plan@7.0.12': + resolution: {integrity: sha512-EaET7As5CeuhTzvXTQCRZeBUcisoYPDDcXvgTE/2jmmypKp0RC7LxKj/yzqeh/1qFTZI7oDGFcL1PHRuQuketQ==} - '@changesets/assemble-release-plan@6.0.6': - resolution: {integrity: sha512-Frkj8hWJ1FRZiY3kzVCKzS0N5mMwWKwmv9vpam7vt8rZjLL1JMthdh6pSDVSPumHPshTTkKZ0VtNbE0cJHZZUg==} + '@changesets/assemble-release-plan@6.0.8': + resolution: {integrity: sha512-y8+8LvZCkKJdbUlpXFuqcavpzJR80PN0OIfn8HZdwK7Sh6MgLXm4hKY5vu6/NDoKp8lAlM4ERZCqRMLxP4m+MQ==} '@changesets/changelog-git@0.2.1': resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} @@ -830,8 +839,8 @@ packages: '@changesets/changelog-github@0.5.1': resolution: {integrity: sha512-BVuHtF+hrhUScSoHnJwTELB4/INQxVFc+P/Qdt20BLiBFIHFJDDUaGsZw+8fQeJTRP5hJZrzpt3oZWh0G19rAQ==} - '@changesets/cli@2.28.1': - resolution: {integrity: sha512-PiIyGRmSc6JddQJe/W1hRPjiN4VrMvb2VfQ6Uydy2punBioQrsxppyG5WafinKcW1mT0jOe/wU4k9Zy5ff21AA==} + '@changesets/cli@2.29.4': + resolution: {integrity: sha512-VW30x9oiFp/un/80+5jLeWgEU6Btj8IqOgI+X/zAYu4usVOWXjPIK5jSSlt5jsCU7/6Z7AxEkarxBxGUqkAmNg==} hasBin: true '@changesets/config@3.1.1': @@ -846,14 +855,14 @@ packages: '@changesets/get-github-info@0.6.0': resolution: {integrity: sha512-v/TSnFVXI8vzX9/w3DU2Ol+UlTZcu3m0kXTjTT4KlAdwSvwutcByYwyYn9hwerPWfPkT2JfpoX0KgvCEi8Q/SA==} - '@changesets/get-release-plan@4.0.8': - resolution: {integrity: sha512-MM4mq2+DQU1ZT7nqxnpveDMTkMBLnwNX44cX7NSxlXmr7f8hO6/S2MXNiXG54uf/0nYnefv0cfy4Czf/ZL/EKQ==} + '@changesets/get-release-plan@4.0.12': + resolution: {integrity: sha512-KukdEgaafnyGryUwpHG2kZ7xJquOmWWWk5mmoeQaSvZTWH1DC5D/Sw6ClgGFYtQnOMSQhgoEbDxAbpIIayKH1g==} '@changesets/get-version-range-type@0.4.0': resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} - '@changesets/git@3.0.2': - resolution: {integrity: sha512-r1/Kju9Y8OxRRdvna+nxpQIsMsRQn9dhhAZt94FLDeu0Hij2hnOozW8iqnHBgvu+KdnJppCveQwK4odwfw/aWQ==} + '@changesets/git@3.0.4': + resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==} '@changesets/logger@0.1.1': resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} @@ -864,8 +873,8 @@ packages: '@changesets/pre@2.0.2': resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} - '@changesets/read@0.6.3': - resolution: {integrity: sha512-9H4p/OuJ3jXEUTjaVGdQEhBdqoT2cO5Ts95JTFsQyawmKzpL8FnIeJSyhTDPW1MBRDnwZlHFEM9SpPwJDY5wIg==} + '@changesets/read@0.6.5': + resolution: {integrity: sha512-UPzNGhsSjHD3Veb0xO/MwvasGe8eMyNrR/sT9gR8Q3DhOQZirgKhhXv/8hVsI0QpPjR004Z9iFxoJU6in3uGMg==} '@changesets/should-skip-package@0.1.2': resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} @@ -897,15 +906,15 @@ packages: resolution: {integrity: sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==} engines: {node: '>=18'} - '@csstools/css-calc@2.1.2': - resolution: {integrity: sha512-TklMyb3uBB28b5uQdxjReG4L80NxAqgrECqLZFQbyLekwwlcDDS8r3f07DKqeo8C4926Br0gf/ZDe17Zv4wIuw==} + '@csstools/css-calc@2.1.3': + resolution: {integrity: sha512-XBG3talrhid44BY1x3MHzUx/aTG8+x/Zi57M4aTKK9RFB4aLlF3TTSzfzn8nWVHWL3FgAXAxmupmDd6VWww+pw==} engines: {node: '>=18'} peerDependencies: '@csstools/css-parser-algorithms': ^3.0.4 '@csstools/css-tokenizer': ^3.0.3 - '@csstools/css-color-parser@3.0.8': - resolution: {integrity: sha512-pdwotQjCCnRPuNi06jFuP68cykU1f3ZWExLe/8MQ1LOs8Xq+fTkYgd+2V8mWUWMrOn9iS2HftPVaMZDaXzGbhQ==} + '@csstools/css-color-parser@3.0.9': + resolution: {integrity: sha512-wILs5Zk7BU86UArYBJTPy/FMPPKVKHMj1ycCEyf3VUptol0JNRLFU/BZsJ4aiIHJEbSLiizzRrw8Pc1uAEDrXw==} engines: {node: '>=18'} peerDependencies: '@csstools/css-parser-algorithms': ^3.0.4 @@ -947,9 +956,9 @@ packages: '@dabh/diagnostics@2.0.3': resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} - '@dependents/detective-less@4.1.0': - resolution: {integrity: sha512-KrkT6qO5NxqNfy68sBl6CTSoJ4SNDIS5iQArkibhlbGU4LaDukZ3q2HIkh8aUKDio6o4itU4xDR7t82Y2eP1Bg==} - engines: {node: '>=14'} + '@dependents/detective-less@5.0.1': + resolution: {integrity: sha512-Y6+WUMsTFWE5jb20IFP4YGa5IrGY/+a/FbOSjDF/wz9gepU2hwCYSXRHP/vPwBvwcY3SVMASt4yXxbXNXigmZQ==} + engines: {node: '>=18'} '@docsearch/css@3.8.2': resolution: {integrity: sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==} @@ -974,90 +983,24 @@ packages: search-insights: optional: true - '@emnapi/core@1.4.0': - resolution: {integrity: sha512-H+N/FqT07NmLmt6OFFtDfwe8PNygprzBikrEMyQfgqSmT0vzE515Pz7R8izwB9q/zsH/MA64AKoul3sA6/CzVg==} - - '@emnapi/runtime@1.4.0': - resolution: {integrity: sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw==} + '@emnapi/core@1.4.3': + resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==} - '@emnapi/wasi-threads@1.0.1': - resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==} + '@emnapi/runtime@1.4.3': + resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} - '@emotion/babel-plugin@11.13.5': - resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==} + '@emnapi/wasi-threads@1.0.2': + resolution: {integrity: sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==} - '@emotion/cache@11.14.0': - resolution: {integrity: sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==} - - '@emotion/hash@0.9.2': - resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} - - '@emotion/is-prop-valid@1.3.1': - resolution: {integrity: sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==} + '@es-joy/jsdoccomment@0.50.2': + resolution: {integrity: sha512-YAdE/IJSpwbOTiaURNCKECdAwqrJuFiZhylmesBcIRawtYKnBR2wxPhoIewMg+Yu+QuYvHfJNReWpoxGBKOChA==} + engines: {node: '>=18'} - '@emotion/memoize@0.9.0': - resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} - - '@emotion/react@11.14.0': - resolution: {integrity: sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==} - peerDependencies: - '@types/react': '*' - react: '>=16.8.0' - peerDependenciesMeta: - '@types/react': - optional: true - - '@emotion/serialize@1.3.3': - resolution: {integrity: sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==} - - '@emotion/sheet@1.4.0': - resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==} - - '@emotion/styled@11.14.0': - resolution: {integrity: sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==} - peerDependencies: - '@emotion/react': ^11.0.0-rc.0 - '@types/react': '*' - react: '>=16.8.0' - peerDependenciesMeta: - '@types/react': - optional: true - - '@emotion/unitless@0.10.0': - resolution: {integrity: sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==} - - '@emotion/use-insertion-effect-with-fallbacks@1.2.0': - resolution: {integrity: sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==} - peerDependencies: - react: '>=16.8.0' - - '@emotion/utils@1.4.2': - resolution: {integrity: sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==} - - '@emotion/weak-memoize@0.4.0': - resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} - - '@es-joy/jsdoccomment@0.49.0': - resolution: {integrity: sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==} - engines: {node: '>=16'} - - '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - - '@esbuild/aix-ppc64@0.25.1': - resolution: {integrity: sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/aix-ppc64@0.25.2': - resolution: {integrity: sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] '@esbuild/aix-ppc64@0.25.4': resolution: {integrity: sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==} @@ -1071,18 +1014,6 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.25.1': - resolution: {integrity: sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.25.2': - resolution: {integrity: sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm64@0.25.4': resolution: {integrity: sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==} engines: {node: '>=18'} @@ -1095,18 +1026,6 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.25.1': - resolution: {integrity: sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.25.2': - resolution: {integrity: sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - '@esbuild/android-arm@0.25.4': resolution: {integrity: sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==} engines: {node: '>=18'} @@ -1119,18 +1038,6 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.25.1': - resolution: {integrity: sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.25.2': - resolution: {integrity: sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - '@esbuild/android-x64@0.25.4': resolution: {integrity: sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==} engines: {node: '>=18'} @@ -1143,18 +1050,6 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.25.1': - resolution: {integrity: sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.25.2': - resolution: {integrity: sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-arm64@0.25.4': resolution: {integrity: sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==} engines: {node: '>=18'} @@ -1167,18 +1062,6 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.25.1': - resolution: {integrity: sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/darwin-x64@0.25.2': - resolution: {integrity: sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - '@esbuild/darwin-x64@0.25.4': resolution: {integrity: sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==} engines: {node: '>=18'} @@ -1191,18 +1074,6 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.25.1': - resolution: {integrity: sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.25.2': - resolution: {integrity: sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-arm64@0.25.4': resolution: {integrity: sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==} engines: {node: '>=18'} @@ -1215,18 +1086,6 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.1': - resolution: {integrity: sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.25.2': - resolution: {integrity: sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - '@esbuild/freebsd-x64@0.25.4': resolution: {integrity: sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==} engines: {node: '>=18'} @@ -1239,18 +1098,6 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.25.1': - resolution: {integrity: sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.25.2': - resolution: {integrity: sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm64@0.25.4': resolution: {integrity: sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==} engines: {node: '>=18'} @@ -1263,18 +1110,6 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.25.1': - resolution: {integrity: sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.25.2': - resolution: {integrity: sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - '@esbuild/linux-arm@0.25.4': resolution: {integrity: sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==} engines: {node: '>=18'} @@ -1287,18 +1122,6 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.25.1': - resolution: {integrity: sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.25.2': - resolution: {integrity: sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-ia32@0.25.4': resolution: {integrity: sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==} engines: {node: '>=18'} @@ -1311,18 +1134,6 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.25.1': - resolution: {integrity: sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.25.2': - resolution: {integrity: sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-loong64@0.25.4': resolution: {integrity: sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==} engines: {node: '>=18'} @@ -1335,18 +1146,6 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.25.1': - resolution: {integrity: sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.25.2': - resolution: {integrity: sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-mips64el@0.25.4': resolution: {integrity: sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==} engines: {node: '>=18'} @@ -1359,18 +1158,6 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.25.1': - resolution: {integrity: sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.25.2': - resolution: {integrity: sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-ppc64@0.25.4': resolution: {integrity: sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==} engines: {node: '>=18'} @@ -1383,18 +1170,6 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.25.1': - resolution: {integrity: sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-riscv64@0.25.2': - resolution: {integrity: sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-riscv64@0.25.4': resolution: {integrity: sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==} engines: {node: '>=18'} @@ -1407,18 +1182,6 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.25.1': - resolution: {integrity: sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.25.2': - resolution: {integrity: sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-s390x@0.25.4': resolution: {integrity: sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==} engines: {node: '>=18'} @@ -1431,36 +1194,12 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.25.1': - resolution: {integrity: sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.25.2': - resolution: {integrity: sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - '@esbuild/linux-x64@0.25.4': resolution: {integrity: sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.1': - resolution: {integrity: sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-arm64@0.25.2': - resolution: {integrity: sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - '@esbuild/netbsd-arm64@0.25.4': resolution: {integrity: sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==} engines: {node: '>=18'} @@ -1473,36 +1212,12 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.1': - resolution: {integrity: sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.25.2': - resolution: {integrity: sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - '@esbuild/netbsd-x64@0.25.4': resolution: {integrity: sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.1': - resolution: {integrity: sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-arm64@0.25.2': - resolution: {integrity: sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - '@esbuild/openbsd-arm64@0.25.4': resolution: {integrity: sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==} engines: {node: '>=18'} @@ -1515,18 +1230,6 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.1': - resolution: {integrity: sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.25.2': - resolution: {integrity: sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - '@esbuild/openbsd-x64@0.25.4': resolution: {integrity: sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==} engines: {node: '>=18'} @@ -1539,18 +1242,6 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.25.1': - resolution: {integrity: sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/sunos-x64@0.25.2': - resolution: {integrity: sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - '@esbuild/sunos-x64@0.25.4': resolution: {integrity: sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==} engines: {node: '>=18'} @@ -1563,18 +1254,6 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.25.1': - resolution: {integrity: sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.25.2': - resolution: {integrity: sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-arm64@0.25.4': resolution: {integrity: sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==} engines: {node: '>=18'} @@ -1587,18 +1266,6 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.25.1': - resolution: {integrity: sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-ia32@0.25.2': - resolution: {integrity: sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-ia32@0.25.4': resolution: {integrity: sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==} engines: {node: '>=18'} @@ -1611,26 +1278,14 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.25.1': - resolution: {integrity: sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.25.2': - resolution: {integrity: sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - '@esbuild/win32-x64@0.25.4': resolution: {integrity: sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.5.1': - resolution: {integrity: sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==} + '@eslint-community/eslint-utils@4.7.0': + resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 @@ -1639,8 +1294,8 @@ packages: resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/compat@1.2.8': - resolution: {integrity: sha512-LqCYHdWL/QqKIJuZ/ucMAv8d4luKGs4oCPgpt8mWztQAtPrHfXKQ/XAUc8ljCHAfJCn6SvkpTcGt5Tsh8saowA==} + '@eslint/compat@1.2.9': + resolution: {integrity: sha512-gCdSY54n7k+driCadyMNv8JSPzYLeDVM/ikZRtvtROBpRdFSkS8W9A82MqsaY7lZuwL0wiapgD0NT1xT0hyJsA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^9.10.0 @@ -1648,35 +1303,67 @@ packages: eslint: optional: true + '@eslint/config-array@0.20.0': + resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.2.2': + resolution: {integrity: sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@0.13.0': resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@0.14.0': + resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/eslintrc@2.1.4': resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@eslint/js@8.57.1': - resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} + '@eslint/eslintrc@3.3.1': + resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@8.57.0': + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@eslint/js@9.22.0': - resolution: {integrity: sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==} + '@eslint/js@9.27.0': + resolution: {integrity: sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.28.0': + resolution: {integrity: sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.24.0': - resolution: {integrity: sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==} + '@eslint/object-schema@2.1.6': + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/plugin-kit@0.2.8': resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/plugin-kit@0.3.1': + resolution: {integrity: sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@fastify/busboy@3.1.1': resolution: {integrity: sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw==} - '@humanwhocodes/config-array@0.13.0': - resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/config-array@0.11.14': + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} deprecated: Use @eslint/config-array instead @@ -1688,22 +1375,146 @@ packages: resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} deprecated: Use @eslint/object-schema instead - '@iconify-json/simple-icons@1.2.28': - resolution: {integrity: sha512-KoCuXgJ2AysGjzOAMUtNPrXeOvvC3zRR+REbYhei2mx5LGTSSrrlVJdaSBv4f8LH9hgfhG7E4Us3hH3XwreP+A==} + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@iconify-json/simple-icons@1.2.35': + resolution: {integrity: sha512-PAHZZn6P5ToHMhmEeeh/O96E/Ep4PctN44N64dWYbDasEvbVoN6x62m+Doz8au0SVS4/zYEMAsDO6TdO9ep84Q==} '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} - '@ioredis/commands@1.2.0': - resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} + '@img/sharp-darwin-arm64@0.34.2': + resolution: {integrity: sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] - '@isaacs/fs-minipass@4.0.1': - resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} - engines: {node: '>=18.0.0'} + '@img/sharp-darwin-x64@0.34.2': + resolution: {integrity: sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.1.0': + resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.1.0': + resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.1.0': + resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.1.0': + resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-ppc64@1.1.0': + resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.1.0': + resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.1.0': + resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.1.0': + resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.1.0': + resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.34.2': + resolution: {integrity: sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.34.2': + resolution: {integrity: sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-s390x@0.34.2': + resolution: {integrity: sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.34.2': + resolution: {integrity: sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.34.2': + resolution: {integrity: sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.34.2': + resolution: {integrity: sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.34.2': + resolution: {integrity: sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.2': + resolution: {integrity: sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.2': + resolution: {integrity: sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.2': + resolution: {integrity: sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@ioredis/commands@1.2.0': + resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} '@istanbuljs/schema@0.1.3': resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} @@ -1734,6 +1545,9 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jspm/core@2.1.0': + resolution: {integrity: sha512-3sRl+pkyFY/kLmHl0cgHiFp2xEqErA8N3ECjMs7serSUBmoJ70lBa0PG5t0IM6WJgdZNyyI0R8YFfi5wM8+mzg==} + '@kwsites/file-exists@1.1.1': resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} @@ -1746,10 +1560,6 @@ packages: '@manypkg/get-packages@1.1.3': resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} - '@mapbox/node-pre-gyp@1.0.11': - resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} - hasBin: true - '@mapbox/node-pre-gyp@2.0.0': resolution: {integrity: sha512-llMXd39jtP0HpQLVI37Bf1m2ADlEb35GYSh1SDSLsBhR+5iCxiNGlT31yqbNtVHygHAtMy6dWFERpU2JgufhPg==} engines: {node: '>=18'} @@ -1761,156 +1571,25 @@ packages: '@microsoft/tsdoc@0.14.2': resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==} - '@mui/base@5.0.0-alpha.108': - resolution: {integrity: sha512-KjzRUts2i/ODlMfywhFTqTzQl+Cr9nlDSZxJcnYjrbOV/iRyQNBTDoiFJt+XEdRi0fZBHnk74AFbnP56ehybsA==} - engines: {node: '>=12.0.0'} - deprecated: This package has been replaced by @base-ui-components/react - peerDependencies: - '@types/react': ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - '@mui/core-downloads-tracker@5.16.14': - resolution: {integrity: sha512-sbjXW+BBSvmzn61XyTMun899E7nGPTXwqD9drm1jBUAvWEhJpPFIRxwQQiATWZnd9rvdxtnhhdsDxEGWI0jxqA==} - - '@mui/icons-material@5.16.14': - resolution: {integrity: sha512-heL4S+EawrP61xMXBm59QH6HODsu0gxtZi5JtnXF2r+rghzyU/3Uftlt1ij8rmJh+cFdKTQug1L9KkZB5JgpMQ==} - engines: {node: '>=12.0.0'} - peerDependencies: - '@mui/material': ^5.0.0 - '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - '@mui/lab@5.0.0-alpha.110': - resolution: {integrity: sha512-SkX5QNbaWouO7BXvb8zpFzDizLt7UzgaebqKSvFJLF28OXiNDfPVCle6IIB4g7hAyb/o19Kbhxs9V+LwK5gQzA==} - engines: {node: '>=12.0.0'} - peerDependencies: - '@emotion/react': ^11.5.0 - '@emotion/styled': ^11.3.0 - '@mui/material': ^5.0.0 - '@types/react': ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@emotion/react': - optional: true - '@emotion/styled': - optional: true - '@types/react': - optional: true - - '@mui/material@5.16.14': - resolution: {integrity: sha512-eSXQVCMKU2xc7EcTxe/X/rC9QsV2jUe8eLM3MUCPYbo6V52eCE436akRIvELq/AqZpxx2bwkq7HC0cRhLB+yaw==} - engines: {node: '>=12.0.0'} - peerDependencies: - '@emotion/react': ^11.5.0 - '@emotion/styled': ^11.3.0 - '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@emotion/react': - optional: true - '@emotion/styled': - optional: true - '@types/react': - optional: true - - '@mui/private-theming@5.16.14': - resolution: {integrity: sha512-12t7NKzvYi819IO5IapW2BcR33wP/KAVrU8d7gLhGHoAmhDxyXlRoKiRij3TOD8+uzk0B6R9wHUNKi4baJcRNg==} - engines: {node: '>=12.0.0'} - peerDependencies: - '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - '@mui/styled-engine@5.16.14': - resolution: {integrity: sha512-UAiMPZABZ7p8mUW4akDV6O7N3+4DatStpXMZwPlt+H/dA0lt67qawN021MNND+4QTpjaiMYxbhKZeQcyWCbuKw==} - engines: {node: '>=12.0.0'} - peerDependencies: - '@emotion/react': ^11.4.1 - '@emotion/styled': ^11.3.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@emotion/react': - optional: true - '@emotion/styled': - optional: true - - '@mui/system@5.16.14': - resolution: {integrity: sha512-KBxMwCb8mSIABnKvoGbvM33XHyT+sN0BzEBG+rsSc0lLQGzs7127KWkCA6/H8h6LZ00XpBEME5MAj8mZLiQ1tw==} - engines: {node: '>=12.0.0'} - peerDependencies: - '@emotion/react': ^11.5.0 - '@emotion/styled': ^11.3.0 - '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@emotion/react': - optional: true - '@emotion/styled': - optional: true - '@types/react': - optional: true - - '@mui/types@7.2.21': - resolution: {integrity: sha512-6HstngiUxNqLU+/DPqlUJDIPbzUBxIVHb1MmXP0eTWDIROiCR2viugXpEif0PPe2mLqqakPzzRClWAnK+8UJww==} - peerDependencies: - '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - '@mui/utils@5.16.14': - resolution: {integrity: sha512-wn1QZkRzSmeXD1IguBVvJJHV3s6rxJrfb6YuC9Kk6Noh9f8Fb54nUs5JRkKm+BOerRhj5fLg05Dhx/H3Ofb8Mg==} - engines: {node: '>=12.0.0'} - peerDependencies: - '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - '@mui/x-data-grid@6.20.4': - resolution: {integrity: sha512-I0JhinVV4e25hD2dB+R6biPBtpGeFrXf8RwlMPQbr9gUggPmPmNtWKo8Kk2PtBBMlGtdMAgHWe7PqhmucUxU1w==} - engines: {node: '>=14.0.0'} - peerDependencies: - '@mui/material': ^5.4.1 - '@mui/system': ^5.4.1 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - - '@napi-rs/wasm-runtime@0.2.8': - resolution: {integrity: sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg==} + '@napi-rs/wasm-runtime@0.2.10': + resolution: {integrity: sha512-bCsCyeZEwVErsGmyPNSzwfwFn4OdxBj0mmv6hOFucB/k81Ojdu68RbZdxYsRQUPc9l6SU5F/cG+bXgWs3oUgsQ==} - '@napi-rs/wasm-runtime@0.2.9': - resolution: {integrity: sha512-OKRBiajrrxB9ATokgEQoG87Z25c67pCpYcCwmXYX8PBftC9pBfN18gnm/fh1wurSLEKIAt+QRFLFCQISrb66Jg==} + '@napi-rs/wasm-runtime@0.2.4': + resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} '@netlify/binary-info@1.0.0': resolution: {integrity: sha512-4wMPu9iN3/HL97QblBsBay3E1etIciR84izI3U+4iALY+JHCrI+a2jO0qbAZ/nxKoegypYEaiiqWXylm+/zfrw==} - '@netlify/blobs@9.1.1': - resolution: {integrity: sha512-hOrWBMOvdh9oa+8Z6ocvkY92q9YtfD+Vbh2i+Qs14cHsl9SYxRzPRQnBxU/H6PNtj6gtEJ7tv8RbBN8z7jH2jA==} + '@netlify/blobs@9.1.2': + resolution: {integrity: sha512-7dMjExSH4zj4ShvLem49mE3mf0K171Tx2pV4WDWhJbRUWW3SJIR2qntz0LvUGS97N5HO1SmnzrgWUhEXCsApiw==} engines: {node: ^14.16.0 || >=16.0.0} - '@netlify/dev-utils@2.1.1': - resolution: {integrity: sha512-0O4/eEcmZCNUkpSuN/yYRkX6BAcK/sbnH0YYNuK3HX193QXaSBT60TUpvTpiRxI6zvIfYCDRl3rz63w8m/lEMg==} + '@netlify/dev-utils@2.2.0': + resolution: {integrity: sha512-5XUvZuffe3KetyhbWwd4n2ktd7wraocCYw10tlM+/u/95iAz29GjNiuNxbCD1T6Bn1MyGc4QLVNKOWhzJkVFAw==} engines: {node: ^14.16.0 || >=16.0.0} - '@netlify/functions@3.0.4': - resolution: {integrity: sha512-Ox8+ABI+nsLK+c4/oC5dpquXuEIjzfTlJrdQKgQijCsDQoje7inXFAtKDLvvaGvuvE+PVpMLwQcIUL6P9Ob1hQ==} - engines: {node: '>=18.0.0'} - - '@netlify/functions@3.1.8': - resolution: {integrity: sha512-oAHPyybBx4oH8+3RfgihrTVhv6gseQw1pt0k4kZ/NDmGbEsgrr3gw+3ajzM5+fW5UnWiNuR5c+d7JgtRqjyMkw==} + '@netlify/functions@3.1.9': + resolution: {integrity: sha512-mbmQIylPzOTDicMFbJF839W3bywJVR0Fm77uvjS6AkDl000VlLwQb+4eO3p0BV7j8+l5IgN/3ltQ/Byi/esTEQ==} engines: {node: '>=14.0.0'} '@netlify/open-api@2.37.0': @@ -1921,21 +1600,71 @@ packages: resolution: {integrity: sha512-7/vIJlMYrPJPlEW84V2yeRuG3QBu66dmlv9neTmZ5nXzwylhBEOhy11ai+34A8mHCSZI4mKns25w3HM9kaDdJg==} engines: {node: '>=16.0.0'} - '@netlify/serverless-functions-api@1.36.0': - resolution: {integrity: sha512-z6okREyK8in0486a22Oro0k+YsuyEjDXJt46FpgeOgXqKJ9ElM8QPll0iuLBkpbH33ENiNbIPLd1cuClRQnhiw==} - engines: {node: '>=18.0.0'} - - '@netlify/serverless-functions-api@1.41.1': - resolution: {integrity: sha512-swjyZEd8U1QVp01rZdHxpwWie7GkP1kS4+4n8kuNKA8+3G5tD0JXXf3a5d4tdwVvrU9k7a4GP1Bn792UPwecmw==} + '@netlify/serverless-functions-api@1.41.2': + resolution: {integrity: sha512-pfCkH50JV06SGMNsNPjn8t17hOcId4fA881HeYQgMBOrewjsw4csaYgHEnCxCEu24Y5x75E2ULbFpqm9CvRCqw==} engines: {node: '>=18.0.0'} - '@netlify/zip-it-and-ship-it@10.1.1': - resolution: {integrity: sha512-MMXrty1NADxyMPgd7qZvDUYunhcPhxIA/jWP2joceOoPcAxOno/aS4jFuIHf2Dbb4HdhR+BlvgvDCy7QTXXyLQ==} - engines: {node: ^14.18.0 || >=16.0.0} + '@netlify/zip-it-and-ship-it@12.1.0': + resolution: {integrity: sha512-+ND2fNnfeOZwnho79aMQ5rreFpI9tu/l4N9/F5H8t9rKYwVHHlv5Zi9o6g/gxZHDLfSbGC9th7Z46CihV8JaZw==} + engines: {node: '>=18.14.0'} hasBin: true - '@next/eslint-plugin-next@13.5.8': - resolution: {integrity: sha512-rmNr6kz5g7x2CQ/5RMmav7/wTGOFIv4fcP+bxawNaJP+Y5Gb0Dvq+omBUvL66pDo/fhWurElatelEFpHX+tMSw==} + '@next/env@15.3.2': + resolution: {integrity: sha512-xURk++7P7qR9JG1jJtLzPzf0qEvqCN0A/T3DXf8IPMKo9/6FfjxtEffRJIIew/bIL4T3C2jLLqBor8B/zVlx6g==} + + '@next/eslint-plugin-next@13.5.11': + resolution: {integrity: sha512-0qjDhes9UTSxirt/dYzrv20hs8SUhcIOvlEioj5+XucVrBHihnAk6Om7Vzk+VZ2nRE7tcShm/6lH1xSkJ3XMpg==} + + '@next/eslint-plugin-next@15.3.2': + resolution: {integrity: sha512-ijVRTXBgnHT33aWnDtmlG+LJD+5vhc9AKTJPquGG5NKXjpKNjc62woIhFtrAcWdBobt8kqjCoaJ0q6sDQoX7aQ==} + + '@next/swc-darwin-arm64@15.3.2': + resolution: {integrity: sha512-2DR6kY/OGcokbnCsjHpNeQblqCZ85/1j6njYSkzRdpLn5At7OkSdmk7WyAmB9G0k25+VgqVZ/u356OSoQZ3z0g==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-x64@15.3.2': + resolution: {integrity: sha512-ro/fdqaZWL6k1S/5CLv1I0DaZfDVJkWNaUU3un8Lg6m0YENWlDulmIWzV96Iou2wEYyEsZq51mwV8+XQXqMp3w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-linux-arm64-gnu@15.3.2': + resolution: {integrity: sha512-covwwtZYhlbRWK2HlYX9835qXum4xYZ3E2Mra1mdQ+0ICGoMiw1+nVAn4d9Bo7R3JqSmK1grMq/va+0cdh7bJA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-musl@15.3.2': + resolution: {integrity: sha512-KQkMEillvlW5Qk5mtGA/3Yz0/tzpNlSw6/3/ttsV1lNtMuOHcGii3zVeXZyi4EJmmLDKYcTcByV2wVsOhDt/zg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-x64-gnu@15.3.2': + resolution: {integrity: sha512-uRBo6THWei0chz+Y5j37qzx+BtoDRFIkDzZjlpCItBRXyMPIg079eIkOCl3aqr2tkxL4HFyJ4GHDes7W8HuAUg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-musl@15.3.2': + resolution: {integrity: sha512-+uxFlPuCNx/T9PdMClOqeE8USKzj8tVz37KflT3Kdbx/LOlZBRI2yxuIcmx1mPNK8DwSOMNCr4ureSet7eyC0w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-win32-arm64-msvc@15.3.2': + resolution: {integrity: sha512-LLTKmaI5cfD8dVzh5Vt7+OMo+AIOClEdIU/TSKbXXT2iScUTSxOGoBhfuv+FU8R9MLmrkIL1e2fBMkEEjYAtPQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-x64-msvc@15.3.2': + resolution: {integrity: sha512-aW5B8wOPioJ4mBdMDXkt5f3j8pUr9W8AnlX0Df35uRWNT1Y6RIybxjnSUe+PhM+M1bwgyY8PHLmXZC6zT1o5tA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} @@ -1952,14 +1681,9 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@nrwl/tao@18.2.4': - resolution: {integrity: sha512-kgJwZ26F+AzvFXaW5eh1g4HLntPcJ6+EE7JyEvrdRzpw7KxTqWy6Ql7dYys6zGlpP4c3PbsXwdc7tGM3Df2PNg==} - hasBin: true - - '@nuxt/cli@3.24.1': - resolution: {integrity: sha512-dWoB3gZj2H04x58QWNWpshQUxjsf0TB6Ppy7YKswS5hGtQkOlQ5k85f133+Bg50TJqzNuZ3OUMRduftppdJjrg==} - engines: {node: ^16.10.0 || >=18.0.0} - hasBin: true + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} '@nuxt/cli@3.25.1': resolution: {integrity: sha512-7+Ut7IvAD4b5piikJFSgIqSPbHKFT5gq05JvCsEHRM0MPA5QR9QHkicklyMqSj0D/oEkDohen8qRgdxRie3oUA==} @@ -1969,23 +1693,23 @@ packages: '@nuxt/devalue@2.0.2': resolution: {integrity: sha512-GBzP8zOc7CGWyFQS6dv1lQz8VVpz5C2yRszbXufwG/9zhStTIH50EtD87NmWbTMwXDvZLNg8GIpb1UFdH93JCA==} - '@nuxt/devtools-kit@2.4.0': - resolution: {integrity: sha512-GdxdxEDN1f6uxJOPooYQTLC6X1QUe5kRs83A0PVH/uD0sqoXCjpKHOw+H0vdhkHOwOIsVIsbL+TdaF4k++p9TA==} + '@nuxt/devtools-kit@2.4.1': + resolution: {integrity: sha512-taA2Nm03JiV3I+SEYS/u1AfjvLm3V9PO8lh0xLsUk/2mlUnL6GZ9xLXrp8VRg11HHt7EPXERGQh8h4iSPU2bSQ==} peerDependencies: vite: '>=6.0' - '@nuxt/devtools-wizard@2.4.0': - resolution: {integrity: sha512-3/5S2zpl79rE1b/lh8M/2lDNsYiYIXXHZmCwsYPuFJA6DilLQo/VY44oq6cY0Q1up32HYB3h1Te/q3ELbsb+ag==} + '@nuxt/devtools-wizard@2.4.1': + resolution: {integrity: sha512-2BaryhfribzQ95UxR7vLLV17Pk1Otxg9ryqH71M1Yp0mybBFs6Z3b0v+RXfCb4BwA10s/tXBhfF13DHSSJF1+A==} hasBin: true - '@nuxt/devtools@2.4.0': - resolution: {integrity: sha512-iXjLoLeWfMa2qWWKRG3z6DKlKVLmbIa3zl7Y8X83BF83m7RW1xVXu6S4tVlLaTi+5tzeKIFlXHo+RO/tJVA72A==} + '@nuxt/devtools@2.4.1': + resolution: {integrity: sha512-2gwjUF1J1Bp/V9ZTsYJe8sS9O3eg80gdf01fT8aEBcilR3wf0PSIxjEyYk+YENtrHPLXcnnUko89jHGq23MHPQ==} hasBin: true peerDependencies: vite: '>=6.0' - '@nuxt/eslint-config@1.3.0': - resolution: {integrity: sha512-m0ebtmjyAiPVctBn+YijVst3WA2tQ6s/YJT4Dr33bTiSVvl+sFapxvAV+YOTyS4WECCBtjTAct61gamjbiahPg==} + '@nuxt/eslint-config@1.4.1': + resolution: {integrity: sha512-ubVHUZlOAJsSlnHWI3TO0b1w6sz7sS5wjQyslO98rgxjqbaI7yw6aIB3loQrjiSAS0jxzfzZTnXxC6ysPkXqvw==} peerDependencies: eslint: ^9.0.0 eslint-plugin-format: '*' @@ -1993,17 +1717,13 @@ packages: eslint-plugin-format: optional: true - '@nuxt/eslint-plugin@1.3.0': - resolution: {integrity: sha512-XrBSM81/nqMg4t4/iI2ZzSWlqz6v2IHmgQHobVuRASFI4b4fPRMoAl46CEGoDs8TgK7RBOJ1BziJ64c7Icos0g==} + '@nuxt/eslint-plugin@1.4.1': + resolution: {integrity: sha512-1d/1GjQBlk7naGrq+ipvWj2CJkIMrM6BkIXIkRo+v1ohx8reQE7sU2SFnxN4HtQGZefSuwriudcUp4ABeXdYTQ==} peerDependencies: eslint: ^9.0.0 - '@nuxt/kit@3.16.2': - resolution: {integrity: sha512-K1SAUo2vweTfudKZzjKsZ5YJoxPLTspR5qz5+G61xtZreLpsdpDYfBseqsIAl5VFLJuszeRpWQ01jP9LfQ6Ksw==} - engines: {node: '>=18.12.0'} - - '@nuxt/kit@3.17.3': - resolution: {integrity: sha512-aw6u6mT3TnM/MmcCRDMv3i9Sbm5/ZMSJgDl+N+WsrWNDIQ2sWmsqdDkjb/HyXF20SNwc2891hRBkaQr3hG2mhA==} + '@nuxt/kit@3.17.4': + resolution: {integrity: sha512-l+hY8sy2XFfg3PigZj+PTu6+KIJzmbACTRimn1ew/gtCz+F38f6KTF4sMRTN5CUxiB8TRENgEonASmkAWfpO9Q==} engines: {node: '>=18.12.0'} '@nuxt/module-builder@1.0.1': @@ -2014,12 +1734,8 @@ packages: '@nuxt/cli': ^3.24.1 typescript: ^5.8.3 - '@nuxt/schema@3.16.2': - resolution: {integrity: sha512-2HZPM372kuI/uw9VU/hOoYuzv803oZAtyoEKC5dQCQTKAQ293AjypF3WljMXUSReFS/hcbBSgGzYUPHr3Qo+pg==} - engines: {node: ^14.18.0 || >=16.10.0} - - '@nuxt/schema@3.17.3': - resolution: {integrity: sha512-z4hbeTtg8B2/2I8zqnCAQQ9JmIQA/BfFy/8cRkGKRIMNjOaTOdmAqMnNriSpyp9xfzWGpnvxPFgab/5uSjsAgA==} + '@nuxt/schema@3.17.4': + resolution: {integrity: sha512-bsfJdWjKNYLkVQt7Ykr9YsAql1u8Tuo6iecSUOltTIhsvAIYsknRFPHoNKNmaiv/L6FgCQgUgQppPTPUAXiJQQ==} engines: {node: ^14.18.0 || >=16.10.0} '@nuxt/telemetry@2.6.6': @@ -2027,8 +1743,8 @@ packages: engines: {node: '>=18.12.0'} hasBin: true - '@nuxt/test-utils@3.17.2': - resolution: {integrity: sha512-i1NiWsJx8sv8Zg8z3WD7ITehMi9s8DaR6ArgmDHaKkQ6RJSaVhrPKyGBTv3gzdoF8CHUKa3MNhdX62JWblvLMg==} + '@nuxt/test-utils@3.19.0': + resolution: {integrity: sha512-rhy01aH1Gioh1uCiiESpeI5m6ZCk4k+0FHwooV01NAGtIY2hJaFxgKf0s+6vjiSvHqoIDMzjaQ9g3SoccDJ4kA==} engines: {node: ^18.20.5 || ^20.9.0 || ^22.0.0 || >=23.0.0} peerDependencies: '@cucumber/cucumber': ^10.3.1 || ^11.0.0 @@ -2063,74 +1779,68 @@ packages: vitest: optional: true - '@nuxt/vite-builder@3.16.2': - resolution: {integrity: sha512-HjK3iZb5GAC4hADOkl2ayn2uNUG4K4qizJ7ud4crHLPw6WHPeT/RhB3j7PpsyRftBnHhlZCsL4Gj/i3rmdcVJw==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0.0} - peerDependencies: - vue: ^3.3.4 - - '@nuxt/vite-builder@3.17.3': - resolution: {integrity: sha512-WK1ESdzbJGRwLGz6s+oyVwM3Ore4V/eYMyquUYsdckFC0rTOnRlV88jdGf0D8Yav0DkrNrG5nZEkL8k+zuXlwQ==} + '@nuxt/vite-builder@3.17.4': + resolution: {integrity: sha512-MRcGe02nEDpu+MnRJcmgVfHdzgt9tWvxVdJbhfd6oyX19plw/CANjgHedlpUNUxqeWXC6CQfGvoVJXn3bQlEqA==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0.0} peerDependencies: vue: ^3.3.4 - '@nx/nx-darwin-arm64@18.2.4': - resolution: {integrity: sha512-RYhMImghdyHmwnbNoR2CkLz4Opj9EmuHY3lMfsorg+T4wIOql/iXACrqjnreN7Hy9myJDo1EIbYZ4x8VSxFWtA==} + '@nx/nx-darwin-arm64@20.8.1': + resolution: {integrity: sha512-Gat4Io66cV70Oa1CjrMJPsEx5ICpAGayv9hejOtBUEDb6XjR12L2e4wV+4EHliF0UbEcuZAr8/lTROEPk0RGWQ==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@nx/nx-darwin-x64@18.2.4': - resolution: {integrity: sha512-2mXMslSRD/ZoI/oaX+0Mh9J/hucXtNgdwC4YFbp1u8UKquAaQ6hf4uo0s4i+AfLX0F7roMtkFPaG/+MQUJE1Rw==} + '@nx/nx-darwin-x64@20.8.1': + resolution: {integrity: sha512-TB9mZk7neGFKgBr2wSBgY6c4kFF9vvChNSp3TrEeXR3FppFcYG5eK4AaKfzWCpYb0wMtseAm7NMX1Lu74utClQ==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@nx/nx-freebsd-x64@18.2.4': - resolution: {integrity: sha512-QUiYLvyUT0PS7D8erf49xa1Jyw4Gfev5gtYfME34Twmn/JPx/99ZkBG4wHbzLqRGwlO5K6m6P4qs30Pzfwtw7A==} + '@nx/nx-freebsd-x64@20.8.1': + resolution: {integrity: sha512-7UQu0/Afna5Af2GagEQ6rbKfUh75NfUn+g66wsoQoUGBvDW0U7B8P3Ph5Bk4Urub0BSfMVcNg2X7CgfypLFN/g==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] - '@nx/nx-linux-arm-gnueabihf@18.2.4': - resolution: {integrity: sha512-+fjFciSUhvDV8dPa97Brwb83k3Xa4gHPI2Un8wlpp28Cv4horeGruRZrrifR1VmD2wp2UBIMl5n7YsDP8KvYhQ==} + '@nx/nx-linux-arm-gnueabihf@20.8.1': + resolution: {integrity: sha512-Tjh8JkTP+x1jSrzx+ofx1pKpkhIbXd7bi0bPdpYt6NI1lZz2HB/dv8vtdzP80jXEDztHf0AeGnEJVgJKsgI6yg==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@nx/nx-linux-arm64-gnu@18.2.4': - resolution: {integrity: sha512-lfaTc+AvV56Uv5mXROiRwh2REiI/7IsqeRDfL+prcuuvJ5Oxi2wYVgnmqcHL+ryQnk0Qn7/d+j/BmYHX5Ve5jQ==} + '@nx/nx-linux-arm64-gnu@20.8.1': + resolution: {integrity: sha512-2+qPIwav2vrytH6pe7fukBe8+yN5JGbEDCnDO8wKQsHeeZMLAQJiZ7EJH/+vynRkI7oWf87mihIKNQME19+w6A==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@nx/nx-linux-arm64-musl@18.2.4': - resolution: {integrity: sha512-U6eoLTQmbxUWU9kZxx6hsYN4zmmOrsDDeW+i3aj5aeahfYlmyz6TsT0V3FSB70WGJC5aMVgEi4RkntQMKkm5vQ==} + '@nx/nx-linux-arm64-musl@20.8.1': + resolution: {integrity: sha512-DsKc+DiMsuHqpBWchUUUg6zv4OaexRqpFXys6auZlrpFpn80kSqLQ3S4zZ5AUu+26wxZqEVJs+uxHGwFbhEssQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@nx/nx-linux-x64-gnu@18.2.4': - resolution: {integrity: sha512-q8WcJhmcRNORkKjax6WcUwMJe/1mQs+RYlUkGqmi7tD7lfcLSqdLPJVjqVmQAwmy1Wh/MHPsbqRwSerUnCxB1A==} + '@nx/nx-linux-x64-gnu@20.8.1': + resolution: {integrity: sha512-Kzru44beVKAmSG84ShuMIIfyu2Uu5r8gsHdtiQPBIOGkZa0Z/e6YtUxcN3w1UZ7yvvzoQ4pQLvqU6UZRSWZtEg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@nx/nx-linux-x64-musl@18.2.4': - resolution: {integrity: sha512-0MDuoPgHa6kkBrjg7hwZ2qQivhJbh3lk7r3q4osDrqZcGxq5XVJqeAmYFyChQy4dbQfUm4hhYkEfzpU8M2lnvQ==} + '@nx/nx-linux-x64-musl@20.8.1': + resolution: {integrity: sha512-cSVVb7DVMhrxCaj/n55okBZS6lZoP5a5vynOBGIV4z3/OJLev+xI9A+3imn/aXnBl8iS69HogYyrW0YTXv4Xaw==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@nx/nx-win32-arm64-msvc@18.2.4': - resolution: {integrity: sha512-uLhSRtfnXzN000Qf27GOjEPXzd4/jBWqv2x419IMh+AEtKHuCEpQNBUAyLvBbQ79SMr+FmCXHB8AeeJ7bEUiRw==} + '@nx/nx-win32-arm64-msvc@20.8.1': + resolution: {integrity: sha512-gte5HcvI24CN6b9I6IYTXh/A0CtRfnlAFaJomPpfT8Wcq637aOZzS0arAEZVoU8QZty1350hj6sfu+wSIjoP7A==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@nx/nx-win32-x64-msvc@18.2.4': - resolution: {integrity: sha512-Y52Afz02Ub1kRZXd6NUTwPMjKQqBKZ35e5dUEpl14na2fWvdgdMz4bYOBPUcmQrovlxBGhmFXtFzxkdW3zyRbQ==} + '@nx/nx-win32-x64-msvc@20.8.1': + resolution: {integrity: sha512-6c2fVEPdPwJdnRbckBatRDF/g6JAp6p3Mfl90DpuaEF2DZC5pmCXKOsXE0aSIZ+gODom2JIchM++2KmDZPJUoA==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -2138,183 +1848,91 @@ packages: '@one-ini/wasm@0.1.1': resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} - '@oxc-parser/binding-darwin-arm64@0.56.5': - resolution: {integrity: sha512-rj4WZqQVJQgLnGnDu2ciIOC5SqcBPc4x11RN0NwuedSGzny5mtBdNVLwt0+8iB15lIjrOKg5pjYJ8GQVPca5HA==} + '@oxc-parser/binding-darwin-arm64@0.71.0': + resolution: {integrity: sha512-7R7TuHWL2hZ8BbRdxXlVJTE0os7TM6LL2EX2OkIz41B3421JeIU+2YH+IV55spIUy5E5ynesLk0IdpSSPVZ25Q==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [darwin] - '@oxc-parser/binding-darwin-arm64@0.69.0': - resolution: {integrity: sha512-4kmSjKARywwCxQ9udJy8T6XJwe7LzfAf0Yy38O1DsRyK05twKgBGWBca2vfaNi4V8jpNaA6SPJi+KJE5IKLLpw==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [darwin] - - '@oxc-parser/binding-darwin-x64@0.56.5': - resolution: {integrity: sha512-Rr7aMkqcxGIM6fgkpaj9SJj0u1O1g+AT7mJwmdi5PLSQRPR4CkDKfztEnAj5k+d2blWvh9nPZH8G0OCwxIHk1Q==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [darwin] - - '@oxc-parser/binding-darwin-x64@0.69.0': - resolution: {integrity: sha512-RQgFiCbv5wTXxFEKgVcUcU2l62zTZZRVXZPUiLtOf4EY0/P/H6pSK6/ATiTVAZVqy72xDE0lWONZbFcUMPwnHw==} + '@oxc-parser/binding-darwin-x64@0.71.0': + resolution: {integrity: sha512-Q7QshRy7cDvpvWAH+qy2U8O9PKo5yEKFqPruD2OSOM8igy/GLIC21dAd6iCcqXRZxaqzN9c4DaXFtEZfq4NWsw==} engines: {node: '>=14.0.0'} cpu: [x64] os: [darwin] - '@oxc-parser/binding-freebsd-x64@0.69.0': - resolution: {integrity: sha512-LGmg4kVxq910jrvZJLT2vJYScz6+ANMoYSR2EWEbhA4HALo3I3/055dgZ8GV001ALaPPz/L6AbvxaYPVAGPRfQ==} + '@oxc-parser/binding-freebsd-x64@0.71.0': + resolution: {integrity: sha512-z8NNBBseLriz2p+eJ8HWC+A8P+MsO8HCtXie9zaVlVcXSiUuBroRWeXopvHN4r+tLzmN2iLXlXprJdNhXNgobQ==} engines: {node: '>=14.0.0'} cpu: [x64] os: [freebsd] - '@oxc-parser/binding-linux-arm-gnueabihf@0.56.5': - resolution: {integrity: sha512-jcFCThrWUt5k1GM43tdmI1m2dEnWUPPHHTWKBJbZBXzXLrJJzkqv5OU87Spf1004rYj9swwpa13kIldFwMzglA==} + '@oxc-parser/binding-linux-arm-gnueabihf@0.71.0': + resolution: {integrity: sha512-QZQcWMduFRWddqvjgLvsWoeellFjvWqvdI0O1m5hoMEykv2/Ag8d7IZbBwRwFqKBuK4UzpBNt4jZaYzRsv1irg==} engines: {node: '>=14.0.0'} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm-gnueabihf@0.69.0': - resolution: {integrity: sha512-Q5jWCHy82c9vYBZVQVSB8ZARLAxU5bMgVDZBHRMDB/gQJhphJaZ23wqPQ2b8b2XSoJhssQhYMV0bF600TzAfpg==} + '@oxc-parser/binding-linux-arm-musleabihf@0.71.0': + resolution: {integrity: sha512-lTDc2WCzllVFXugUHQGR904CksA5BiHc35mcH6nJm6h0FCdoyn9zefW8Pelku5ET39JgO1OENEm/AyNvf/FzIw==} engines: {node: '>=14.0.0'} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm64-gnu@0.56.5': - resolution: {integrity: sha512-zo/9RDgWvugKxCpHHcAC5EW0AqoEvODJ4Iv4aT1Xonv6kcydbyPSXJBQhhZUvTXTAFIlQKl6INHl+Xki9Qs3fw==} + '@oxc-parser/binding-linux-arm64-gnu@0.71.0': + resolution: {integrity: sha512-mAA6JGS+MB+gbN5y/KuQ095EHYGF7a/FaznM7klk5CaCap/UdiRWCVinVV6xXmejOPZMnrkr6R5Kqi6dHRsm2g==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [linux] - '@oxc-parser/binding-linux-arm64-gnu@0.69.0': - resolution: {integrity: sha512-PsuAduOi5Cz+YdpL3LyVBvN+h5fjHAgMCibaAfGa7ru2zr6tb6r5IAfBBj3KHkFYoyl7ztodQSnWsA2Fka3QPw==} + '@oxc-parser/binding-linux-arm64-musl@0.71.0': + resolution: {integrity: sha512-PaPmIEM0yldXSrO1Icrx6/DwnMXpEOv0bDVa0LFtwy2I+aiTiX7OVRB3pJCg8FEV9P+L48s9XW0Oaz+Dz3o3sQ==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [linux] - '@oxc-parser/binding-linux-arm64-musl@0.56.5': - resolution: {integrity: sha512-SCIqrL5apVbrtMoqOpKX/Ez+c46WmW0Tyhtu+Xby281biH+wYu70m+fux9ZsGmbHc2ojd4FxUcaUdCZtb5uTOQ==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [linux] - - '@oxc-parser/binding-linux-arm64-musl@0.69.0': - resolution: {integrity: sha512-vOxh5Hk22YlfxuQvxRmkzT+VrAd901sDz1gkPUf2u+HCNyDMXq+O/jXn68wFQQgbkDKpAfP0z2dZfOJFkkL2Ag==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [linux] - - '@oxc-parser/binding-linux-riscv64-gnu@0.69.0': - resolution: {integrity: sha512-5xQpOPaGgxqyUa8T7yOeXPI/tO4o7pmRV++od1XFH+HR8GvidS0J0rC7F69aqz39+i6x6rc5ZxwWADLPtR45rQ==} + '@oxc-parser/binding-linux-riscv64-gnu@0.71.0': + resolution: {integrity: sha512-+AEGO6gOSSEqWTrCCYayNMMPe/qi83o1czQ5bytEFQtyvWdgLwliqqShpJtgSLj1SNWi94HiA/VOfqqZnGE1AQ==} engines: {node: '>=14.0.0'} cpu: [riscv64] os: [linux] - '@oxc-parser/binding-linux-s390x-gnu@0.69.0': - resolution: {integrity: sha512-btrmwQ/mds4We2nS/GSg03wj9iClgQkbgf6c8WWXhr4l5GmpxLH6t1LnS4s+tHpTWSY7jpegRfOwQalS5D3Y6g==} + '@oxc-parser/binding-linux-s390x-gnu@0.71.0': + resolution: {integrity: sha512-zqFnheBACFzrRl401ylXufNl1YsOdVa8jwS2iSCwJFx4/JdQhE6Y4YWoEjQ/pzeRZXwI5FX4C607rQe2YdhggQ==} engines: {node: '>=14.0.0'} cpu: [s390x] os: [linux] - '@oxc-parser/binding-linux-x64-gnu@0.56.5': - resolution: {integrity: sha512-I2mpX35NWo83hay4wrnzFLk3VuGK1BBwHaqvEdqsCode8iG8slYJRJPICVbCEWlkR3rotlTQ+608JcRU0VqZ5Q==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [linux] - - '@oxc-parser/binding-linux-x64-gnu@0.69.0': - resolution: {integrity: sha512-IfFNgUcdzISFausz7k6gdo1zUydJLExVrwpoCRyDYnsPovgOJHhxVZZ6sbuYbufcRh6PV/aA7G8RIvNmOVjIwQ==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [linux] - - '@oxc-parser/binding-linux-x64-musl@0.56.5': - resolution: {integrity: sha512-xfzUHGYOh3PGWZdBuY5r1czvE8EGWPAmhTWHqkw3/uAfUVWN/qrrLjMojiaiWyUgl/9XIFg05m5CJH9dnngh5Q==} + '@oxc-parser/binding-linux-x64-gnu@0.71.0': + resolution: {integrity: sha512-steSQTwv3W+/hpES4/9E3vNohou1FXJLNWLDbYHDaBI9gZdYJp6zwALC8EShCz0NoQvCu4THD3IBsTBHvFBNyw==} engines: {node: '>=14.0.0'} cpu: [x64] os: [linux] - '@oxc-parser/binding-linux-x64-musl@0.69.0': - resolution: {integrity: sha512-dEOj+Lnwy2GNiAzon05Mo1DP1ptpQNbm12Bz+ZVm/vDNHY0Zbgjf7i3MpnnEywFL8NZJ1c6vSDmtDqTdnm2EBw==} + '@oxc-parser/binding-linux-x64-musl@0.71.0': + resolution: {integrity: sha512-mV8j/haQBZRU2QnwZe0UIpnhpPBL9dFk1tgNVSH9tV7cV4xUZPn7pFDqMriAmpD7GLfmxbZMInDkujokd63M7Q==} engines: {node: '>=14.0.0'} cpu: [x64] os: [linux] - '@oxc-parser/binding-wasm32-wasi@0.56.5': - resolution: {integrity: sha512-+z3Ofmc1v5kcu8fXgG5vn7T1f52P47ceTTmTXsm5HPY7rq5EMYRUaBnxH6cesXwY1OVVCwYlIZbCiy8Pm1w8zQ==} + '@oxc-parser/binding-wasm32-wasi@0.71.0': + resolution: {integrity: sha512-P8ScINpuihkkBX8BrN/4x4ka2+izncHh7/hHxxuPZDZTVMyNNnL1uSoI80tN9yN7NUtUKoi9aQUaF4h22RQcIA==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@oxc-parser/binding-wasm32-wasi@0.69.0': - resolution: {integrity: sha512-M7HM82ZIeIIYN3DrbN6gsM6Z2RTv/nEe2CsQdeblxmM9CfXCyi55YOxtxo1+8iYoy8NV5EGUeCOwY7YR1JAt6A==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@oxc-parser/binding-win32-arm64-msvc@0.56.5': - resolution: {integrity: sha512-pRg8QrbMh8PgnXBreiONoJBR306u+JN19BXQC7oKIaG4Zxt9Mn8XIyuhUv3ytqjLudSiG2ERWQUoCGLs+yfW0A==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [win32] - - '@oxc-parser/binding-win32-arm64-msvc@0.69.0': - resolution: {integrity: sha512-M5W0p0WGjshiCGUNugoHs+8XWgd5J2CrSHY8rYrEmp632LhHRQUGC9AwI45B6IYvnRXiK6E4zcGj/Bey2Dqhyg==} + '@oxc-parser/binding-win32-arm64-msvc@0.71.0': + resolution: {integrity: sha512-4jrJSdBXHmLYaghi1jvbuJmWu117wxqCpzHHgpEV9xFiRSngtClqZkNqyvcD4907e/VriEwluZ3PO3Mlp0y9cw==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [win32] - '@oxc-parser/binding-win32-x64-msvc@0.56.5': - resolution: {integrity: sha512-VALZNcuyw/6rwsxOACQ2YS6rey2d/ym4cNfXqJrHB/MZduAPj4xvij72gHGu3Ywm31KVGLVWk/mrMRiM9CINcA==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [win32] - - '@oxc-parser/binding-win32-x64-msvc@0.69.0': - resolution: {integrity: sha512-flBEF+3dJOi3Nm3b7kNxVGrtuSBGN7RNs/qWPHvq/FUP6xFEsT3hvcdNBUnzB15hPsyExptlKyihgZjYhfpgpA==} + '@oxc-parser/binding-win32-x64-msvc@0.71.0': + resolution: {integrity: sha512-zF7xF19DOoANym/xwVClYH1tiW3S70W8ZDrMHdrEB7gZiTYLCIKIRMrpLVKaRia6LwEo7X0eduwdBa5QFawxOw==} engines: {node: '>=14.0.0'} cpu: [x64] os: [win32] - '@oxc-parser/wasm@0.60.0': - resolution: {integrity: sha512-Dkf9/D87WGBCW3L0+1DtpAfL4SrNsgeRvxwjpKCtbH7Kf6K+pxrT0IridaJfmWKu1Ml+fDvj+7HEyBcfUC/TXQ==} - - '@oxc-project/types@0.56.5': - resolution: {integrity: sha512-skY3kOJwp22W4RkaadH1hZ3hqFHjkRrIIE0uQ4VUg+/Chvbl+2pF+B55IrIk2dgsKXS57YEUsJuN6I6s4rgFjA==} - - '@oxc-project/types@0.60.0': - resolution: {integrity: sha512-prhfNnb3ATFHOCv7mzKFfwLij5RzoUz6Y1n525ZhCEqfq5wreCXL+DyVoq3ShukPo7q45ZjYIdjFUgjj+WKzng==} - - '@oxc-project/types@0.69.0': - resolution: {integrity: sha512-bu3gzdAlLgncoaqyqWVpMAKx4axo+j3ewvvdAt5iCLtvHB/n3Qeif67NU+2TM/ami1nV5/KVO9lxCH8paPATBA==} - - '@oxygen-ui/primitives@1.15.2': - resolution: {integrity: sha512-THqdYgUn8E9hyktiejSnoq1TtuVGjUj0SBEQwxYPePj5/IBSl20Q/vPDvguSOQuDEScmw6iCv2BYDMsHUP5LYA==} - - '@oxygen-ui/react-icons@1.15.2': - resolution: {integrity: sha512-Ptl7BB0ble/nVuna+jlo3DvCFjycMViaAbWsOXRGYPya/h9K5+g5p90F1mPFbYVyj7GebTZGvu5V8oDpihYDNQ==} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - typescript: '>=4.0.0' - peerDependenciesMeta: - typescript: - optional: true - - '@oxygen-ui/react@1.15.2': - resolution: {integrity: sha512-xPVoPVDRoYPU63gAv2k78Q5EIGmYnHvjuUwZzvkF9Kr6r+e264Y5IWrM7AgwRbwHofFU2bLKbP5Rb2VLjv8wPA==} - peerDependencies: - '@emotion/react': ^11.10.5 - '@emotion/styled': ^11.10.5 - '@mui/icons-material': ^5.10.16 - '@mui/lab': 5.0.0-alpha.110 - '@mui/material': ^5.10.16 - '@mui/system': ^5.10.16 - '@mui/utils': ^5.10.16 - react: '>=18.0.0' - react-dom: '>=18.0.0' - typescript: '>=4.0.0' - peerDependenciesMeta: - typescript: - optional: true + '@oxc-project/types@0.71.0': + resolution: {integrity: sha512-5CwQ4MI+P4MQbjLWXgNurA+igGwu/opNetIE13LBs9+V93R64MLvDKOOLZIXSzEfovU3Zef3q3GjPnMTgJTn2w==} '@parcel/watcher-android-arm64@2.5.1': resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} @@ -2408,19 +2026,12 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@pkgr/core@0.1.1': - resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@pkgr/core@0.2.4': resolution: {integrity: sha512-ROFF39F6ZrnzSUEmQQZUar0Jt4xVoP9WnDRdWwF4NNcXs3xBTLgBUDoOwW141y1jP+S8nahIbdxbFC7IShw9Iw==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@polka/url@1.0.0-next.28': - resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} - - '@popperjs/core@2.11.8': - resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} '@poppinss/colors@4.1.4': resolution: {integrity: sha512-FA+nTU8p6OcSH4tLDY5JilGYr1bVWHpNmcLr7xmMEdbWmKHa+3QZ+DqefrXKmdjO/brHTnQZo20lLSjaO7ydog==} @@ -2433,6 +2044,9 @@ packages: resolution: {integrity: sha512-aQypoot0HPSJa6gDPEPTntc1GT6QINrSbgRlRhadGW2WaYqUK3tK4Bw9SBMZXhmxd3GeAlZjVcODHgiu+THY7A==} engines: {node: '>=18'} + '@rolldown/pluginutils@1.0.0-beta.9': + resolution: {integrity: sha512-e9MeMtVWo186sgvFFJOPGy7/d2j2mZhLJIdVW0C/xDluuOvymEATqz6zKsP0ZmXGzQtqlyjz5sC1sYQUoJG98w==} + '@rollup/plugin-alias@5.1.1': resolution: {integrity: sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ==} engines: {node: '>=14.0.0'} @@ -2460,15 +2074,6 @@ packages: rollup: optional: true - '@rollup/plugin-dynamic-import-vars@2.1.5': - resolution: {integrity: sha512-Mymi24fd9hlRifdZV/jYIFj1dn99F34imiYu3KzlAcgBcRi3i9SucgW/VRo5SQ9K4NuQ7dCep6pFWgNyhRdFHQ==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - '@rollup/plugin-image@3.0.3': resolution: {integrity: sha512-qXWQwsXpvD4trSb8PeFPFajp8JLpRtqqOeNYRUKnEQNHm7e5UP7fuSRcbjQAJ7wDZBbnJvSdY5ujNBQd9B1iFg==} engines: {node: '>=14.0.0'} @@ -2558,59 +2163,19 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.35.0': - resolution: {integrity: sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm-eabi@4.39.0': - resolution: {integrity: sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==} - cpu: [arm] - os: [android] - '@rollup/rollup-android-arm-eabi@4.40.2': resolution: {integrity: sha512-JkdNEq+DFxZfUwxvB58tHMHBHVgX23ew41g1OQinthJ+ryhdRk67O31S7sYw8u2lTjHUPFxwar07BBt1KHp/hg==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.35.0': - resolution: {integrity: sha512-FtKddj9XZudurLhdJnBl9fl6BwCJ3ky8riCXjEw3/UIbjmIY58ppWwPEvU3fNu+W7FUsAsB1CdH+7EQE6CXAPA==} + '@rollup/rollup-android-arm64@4.40.2': + resolution: {integrity: sha512-13unNoZ8NzUmnndhPTkWPWbX3vtHodYmy+I9kuLxN+F+l+x3LdVF7UCu8TWVMt1POHLh6oDHhnOA04n8oJZhBw==} cpu: [arm64] os: [android] - '@rollup/rollup-android-arm64@4.39.0': - resolution: {integrity: sha512-It9+M1zE31KWfqh/0cJLrrsCPiF72PoJjIChLX+rEcujVRCb4NLQ5QzFkzIZW8Kn8FTbvGQBY5TkKBau3S8cCQ==} + '@rollup/rollup-darwin-arm64@4.40.2': + resolution: {integrity: sha512-Gzf1Hn2Aoe8VZzevHostPX23U7N5+4D36WJNHK88NZHCJr7aVMG4fadqkIf72eqVPGjGc0HJHNuUaUcxiR+N/w==} cpu: [arm64] - os: [android] - - '@rollup/rollup-android-arm64@4.40.2': - resolution: {integrity: sha512-13unNoZ8NzUmnndhPTkWPWbX3vtHodYmy+I9kuLxN+F+l+x3LdVF7UCu8TWVMt1POHLh6oDHhnOA04n8oJZhBw==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.35.0': - resolution: {integrity: sha512-Uk+GjOJR6CY844/q6r5DR/6lkPFOw0hjfOIzVx22THJXMxktXG6CbejseJFznU8vHcEBLpiXKY3/6xc+cBm65Q==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-arm64@4.39.0': - resolution: {integrity: sha512-lXQnhpFDOKDXiGxsU9/l8UEGGM65comrQuZ+lDcGUx+9YQ9dKpF3rSEGepyeR5AHZ0b5RgiligsBhWZfSSQh8Q==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-arm64@4.40.2': - resolution: {integrity: sha512-Gzf1Hn2Aoe8VZzevHostPX23U7N5+4D36WJNHK88NZHCJr7aVMG4fadqkIf72eqVPGjGc0HJHNuUaUcxiR+N/w==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.35.0': - resolution: {integrity: sha512-3IrHjfAS6Vkp+5bISNQnPogRAW5GAV1n+bNCrDwXmfMHbPl5EhTmWtfmwlJxFRUCBZ+tZ/OxDyU08aF6NI/N5Q==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.39.0': - resolution: {integrity: sha512-mKXpNZLvtEbgu6WCkNij7CGycdw9cJi2k9v0noMb++Vab12GZjFgUXD69ilAbBh034Zwn95c2PNSz9xM7KYEAQ==} - cpu: [x64] os: [darwin] '@rollup/rollup-darwin-x64@4.40.2': @@ -2618,236 +2183,81 @@ packages: cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.35.0': - resolution: {integrity: sha512-sxjoD/6F9cDLSELuLNnY0fOrM9WA0KrM0vWm57XhrIMf5FGiN8D0l7fn+bpUeBSU7dCgPV2oX4zHAsAXyHFGcQ==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-arm64@4.39.0': - resolution: {integrity: sha512-jivRRlh2Lod/KvDZx2zUR+I4iBfHcu2V/BA2vasUtdtTN2Uk3jfcZczLa81ESHZHPHy4ih3T/W5rPFZ/hX7RtQ==} - cpu: [arm64] - os: [freebsd] - '@rollup/rollup-freebsd-arm64@4.40.2': resolution: {integrity: sha512-8t6aL4MD+rXSHHZUR1z19+9OFJ2rl1wGKvckN47XFRVO+QL/dUSpKA2SLRo4vMg7ELA8pzGpC+W9OEd1Z/ZqoQ==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.35.0': - resolution: {integrity: sha512-2mpHCeRuD1u/2kruUiHSsnjWtHjqVbzhBkNVQ1aVD63CcexKVcQGwJ2g5VphOd84GvxfSvnnlEyBtQCE5hxVVw==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.39.0': - resolution: {integrity: sha512-8RXIWvYIRK9nO+bhVz8DwLBepcptw633gv/QT4015CpJ0Ht8punmoHU/DuEd3iw9Hr8UwUV+t+VNNuZIWYeY7Q==} - cpu: [x64] - os: [freebsd] - '@rollup/rollup-freebsd-x64@4.40.2': resolution: {integrity: sha512-C+AyHBzfpsOEYRFjztcYUFsH4S7UsE9cDtHCtma5BK8+ydOZYgMmWg1d/4KBytQspJCld8ZIujFMAdKG1xyr4Q==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.35.0': - resolution: {integrity: sha512-mrA0v3QMy6ZSvEuLs0dMxcO2LnaCONs1Z73GUDBHWbY8tFFocM6yl7YyMu7rz4zS81NDSqhrUuolyZXGi8TEqg==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-gnueabihf@4.39.0': - resolution: {integrity: sha512-mz5POx5Zu58f2xAG5RaRRhp3IZDK7zXGk5sdEDj4o96HeaXhlUwmLFzNlc4hCQi5sGdR12VDgEUqVSHer0lI9g==} - cpu: [arm] - os: [linux] - '@rollup/rollup-linux-arm-gnueabihf@4.40.2': resolution: {integrity: sha512-de6TFZYIvJwRNjmW3+gaXiZ2DaWL5D5yGmSYzkdzjBDS3W+B9JQ48oZEsmMvemqjtAFzE16DIBLqd6IQQRuG9Q==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.35.0': - resolution: {integrity: sha512-DnYhhzcvTAKNexIql8pFajr0PiDGrIsBYPRvCKlA5ixSS3uwo/CWNZxB09jhIapEIg945KOzcYEAGGSmTSpk7A==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.39.0': - resolution: {integrity: sha512-+YDwhM6gUAyakl0CD+bMFpdmwIoRDzZYaTWV3SDRBGkMU/VpIBYXXEvkEcTagw/7VVkL2vA29zU4UVy1mP0/Yw==} - cpu: [arm] - os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.40.2': resolution: {integrity: sha512-urjaEZubdIkacKc930hUDOfQPysezKla/O9qV+O89enqsqUmQm8Xj8O/vh0gHg4LYfv7Y7UsE3QjzLQzDYN1qg==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.35.0': - resolution: {integrity: sha512-uagpnH2M2g2b5iLsCTZ35CL1FgyuzzJQ8L9VtlJ+FckBXroTwNOaD0z0/UF+k5K3aNQjbm8LIVpxykUOQt1m/A==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.39.0': - resolution: {integrity: sha512-EKf7iF7aK36eEChvlgxGnk7pdJfzfQbNvGV/+l98iiMwU23MwvmV0Ty3pJ0p5WQfm3JRHOytSIqD9LB7Bq7xdQ==} - cpu: [arm64] - os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.40.2': resolution: {integrity: sha512-KlE8IC0HFOC33taNt1zR8qNlBYHj31qGT1UqWqtvR/+NuCVhfufAq9fxO8BMFC22Wu0rxOwGVWxtCMvZVLmhQg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.35.0': - resolution: {integrity: sha512-XQxVOCd6VJeHQA/7YcqyV0/88N6ysSVzRjJ9I9UA/xXpEsjvAgDTgH3wQYz5bmr7SPtVK2TsP2fQ2N9L4ukoUg==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.39.0': - resolution: {integrity: sha512-vYanR6MtqC7Z2SNr8gzVnzUul09Wi1kZqJaek3KcIlI/wq5Xtq4ZPIZ0Mr/st/sv/NnaPwy/D4yXg5x0B3aUUA==} - cpu: [arm64] - os: [linux] - '@rollup/rollup-linux-arm64-musl@4.40.2': resolution: {integrity: sha512-j8CgxvfM0kbnhu4XgjnCWJQyyBOeBI1Zq91Z850aUddUmPeQvuAy6OiMdPS46gNFgy8gN1xkYyLgwLYZG3rBOg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.35.0': - resolution: {integrity: sha512-5pMT5PzfgwcXEwOaSrqVsz/LvjDZt+vQ8RT/70yhPU06PTuq8WaHhfT1LW+cdD7mW6i/J5/XIkX/1tCAkh1W6g==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-loongarch64-gnu@4.39.0': - resolution: {integrity: sha512-NMRUT40+h0FBa5fb+cpxtZoGAggRem16ocVKIv5gDB5uLDgBIwrIsXlGqYbLwW8YyO3WVTk1FkFDjMETYlDqiw==} - cpu: [loong64] - os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.40.2': resolution: {integrity: sha512-Ybc/1qUampKuRF4tQXc7G7QY9YRyeVSykfK36Y5Qc5dmrIxwFhrOzqaVTNoZygqZ1ZieSWTibfFhQ5qK8jpWxw==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.35.0': - resolution: {integrity: sha512-c+zkcvbhbXF98f4CtEIP1EBA/lCic5xB0lToneZYvMeKu5Kamq3O8gqrxiYYLzlZH6E3Aq+TSW86E4ay8iD8EA==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-powerpc64le-gnu@4.39.0': - resolution: {integrity: sha512-0pCNnmxgduJ3YRt+D+kJ6Ai/r+TaePu9ZLENl+ZDV/CdVczXl95CbIiwwswu4L+K7uOIGf6tMo2vm8uadRaICQ==} - cpu: [ppc64] - os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.40.2': resolution: {integrity: sha512-3FCIrnrt03CCsZqSYAOW/k9n625pjpuMzVfeI+ZBUSDT3MVIFDSPfSUgIl9FqUftxcUXInvFah79hE1c9abD+Q==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.35.0': - resolution: {integrity: sha512-s91fuAHdOwH/Tad2tzTtPX7UZyytHIRR6V4+2IGlV0Cej5rkG0R61SX4l4y9sh0JBibMiploZx3oHKPnQBKe4g==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.39.0': - resolution: {integrity: sha512-t7j5Zhr7S4bBtksT73bO6c3Qa2AV/HqiGlj9+KB3gNF5upcVkx+HLgxTm8DK4OkzsOYqbdqbLKwvGMhylJCPhQ==} - cpu: [riscv64] - os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.40.2': resolution: {integrity: sha512-QNU7BFHEvHMp2ESSY3SozIkBPaPBDTsfVNGx3Xhv+TdvWXFGOSH2NJvhD1zKAT6AyuuErJgbdvaJhYVhVqrWTg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.39.0': - resolution: {integrity: sha512-m6cwI86IvQ7M93MQ2RF5SP8tUjD39Y7rjb1qjHgYh28uAPVU8+k/xYWvxRO3/tBN2pZkSMa5RjnPuUIbrwVxeA==} - cpu: [riscv64] - os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.40.2': resolution: {integrity: sha512-5W6vNYkhgfh7URiXTO1E9a0cy4fSgfE4+Hl5agb/U1sa0kjOLMLC1wObxwKxecE17j0URxuTrYZZME4/VH57Hg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.35.0': - resolution: {integrity: sha512-hQRkPQPLYJZYGP+Hj4fR9dDBMIM7zrzJDWFEMPdTnTy95Ljnv0/4w/ixFw3pTBMEuuEuoqtBINYND4M7ujcuQw==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.39.0': - resolution: {integrity: sha512-iRDJd2ebMunnk2rsSBYlsptCyuINvxUfGwOUldjv5M4tpa93K8tFMeYGpNk2+Nxl+OBJnBzy2/JCscGeO507kA==} - cpu: [s390x] - os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.40.2': resolution: {integrity: sha512-B7LKIz+0+p348JoAL4X/YxGx9zOx3sR+o6Hj15Y3aaApNfAshK8+mWZEf759DXfRLeL2vg5LYJBB7DdcleYCoQ==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.35.0': - resolution: {integrity: sha512-Pim1T8rXOri+0HmV4CdKSGrqcBWX0d1HoPnQ0uw0bdp1aP5SdQVNBy8LjYncvnLgu3fnnCt17xjWGd4cqh8/hA==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.39.0': - resolution: {integrity: sha512-t9jqYw27R6Lx0XKfEFe5vUeEJ5pF3SGIM6gTfONSMb7DuG6z6wfj2yjcoZxHg129veTqU7+wOhY6GX8wmf90dA==} - cpu: [x64] - os: [linux] - '@rollup/rollup-linux-x64-gnu@4.40.2': resolution: {integrity: sha512-lG7Xa+BmBNwpjmVUbmyKxdQJ3Q6whHjMjzQplOs5Z+Gj7mxPtWakGHqzMqNER68G67kmCX9qX57aRsW5V0VOng==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.35.0': - resolution: {integrity: sha512-QysqXzYiDvQWfUiTm8XmJNO2zm9yC9P/2Gkrwg2dH9cxotQzunBHYr6jk4SujCTqnfGxduOmQcI7c2ryuW8XVg==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.39.0': - resolution: {integrity: sha512-ThFdkrFDP55AIsIZDKSBWEt/JcWlCzydbZHinZ0F/r1h83qbGeenCt/G/wG2O0reuENDD2tawfAj2s8VK7Bugg==} - cpu: [x64] - os: [linux] - '@rollup/rollup-linux-x64-musl@4.40.2': resolution: {integrity: sha512-tD46wKHd+KJvsmije4bUskNuvWKFcTOIM9tZ/RrmIvcXnbi0YK/cKS9FzFtAm7Oxi2EhV5N2OpfFB348vSQRXA==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.35.0': - resolution: {integrity: sha512-OUOlGqPkVJCdJETKOCEf1mw848ZyJ5w50/rZ/3IBQVdLfR5jk/6Sr5m3iO2tdPgwo0x7VcncYuOvMhBWZq8ayg==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-arm64-msvc@4.39.0': - resolution: {integrity: sha512-jDrLm6yUtbOg2TYB3sBF3acUnAwsIksEYjLeHL+TJv9jg+TmTwdyjnDex27jqEMakNKf3RwwPahDIt7QXCSqRQ==} - cpu: [arm64] - os: [win32] - '@rollup/rollup-win32-arm64-msvc@4.40.2': resolution: {integrity: sha512-Bjv/HG8RRWLNkXwQQemdsWw4Mg+IJ29LK+bJPW2SCzPKOUaMmPEppQlu/Fqk1d7+DX3V7JbFdbkh/NMmurT6Pg==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.35.0': - resolution: {integrity: sha512-2/lsgejMrtwQe44glq7AFFHLfJBPafpsTa6JvP2NGef/ifOa4KBoglVf7AKN7EV9o32evBPRqfg96fEHzWo5kw==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.39.0': - resolution: {integrity: sha512-6w9uMuza+LbLCVoNKL5FSLE7yvYkq9laSd09bwS0tMjkwXrmib/4KmoJcrKhLWHvw19mwU+33ndC69T7weNNjQ==} - cpu: [ia32] - os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.40.2': resolution: {integrity: sha512-dt1llVSGEsGKvzeIO76HToiYPNPYPkmjhMHhP00T9S4rDern8P2ZWvWAQUEJ+R1UdMWJ/42i/QqJ2WV765GZcA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.35.0': - resolution: {integrity: sha512-PIQeY5XDkrOysbQblSW7v3l1MDZzkTEzAfTPkj5VAu3FW8fS4ynyLg2sINp0fp3SjZ8xkRYpLqoKcYqAkhU1dw==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.39.0': - resolution: {integrity: sha512-yAkUOkIKZlK5dl7u6dg897doBgLXmUHhIINM2c+sND3DZwnrdQkkSiDh7N75Ll4mM4dxSkYfXqU9fW3lLkMFug==} - cpu: [x64] - os: [win32] - '@rollup/rollup-win32-x64-msvc@4.40.2': resolution: {integrity: sha512-bwspbWB04XJpeElvsp+DCylKfF4trJDa2Y9Go8O6A7YLX2LIKGcNK/CYImJN6ZP4DcuOHB4Utl3iCbnR62DudA==} cpu: [x64] @@ -2856,8 +2266,8 @@ packages: '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - '@sec-ant/readable-stream@0.4.1': - resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + '@rushstack/eslint-patch@1.11.0': + resolution: {integrity: sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==} '@shikijs/core@2.5.0': resolution: {integrity: sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==} @@ -2894,60 +2304,63 @@ packages: resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} engines: {node: '>=18'} - '@sindresorhus/merge-streams@4.0.0': - resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} - engines: {node: '>=18'} - '@speed-highlight/core@1.2.7': resolution: {integrity: sha512-0dxmVj4gxg3Jg879kvFS/msl4s9F3T9UXC1InxgOf7t5NvcPD97u/WTA5vL/IxWHMn7qSxBozqrnnE2wvl1m8g==} - '@stylistic/eslint-plugin@4.2.0': - resolution: {integrity: sha512-8hXezgz7jexGHdo5WN6JBEIPHCSFyyU4vgbxevu4YLVS5vl+sxqAAGyXSzfNDyR6xMNSH5H1x67nsXcYMOHtZA==} + '@stylistic/eslint-plugin@4.4.0': + resolution: {integrity: sha512-bIh/d9X+OQLCAMdhHtps+frvyjvAM4B1YlSJzcEEhl7wXLIqPar3ngn9DrHhkBOrTA/z9J0bUMtctAspe0dxdQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: '>=9.0.0' + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + + '@testing-library/dom@10.4.0': + resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} + engines: {node: '>=18'} + + '@testing-library/user-event@14.6.1': + resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + '@trysound/sax@0.2.0': resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} - '@tsconfig/node22@22.0.0': - resolution: {integrity: sha512-twLQ77zevtxobBOD4ToAtVmuYrpeYUh3qh+TEp+08IWhpsrIflVHqQ1F1CiPxQGL7doCdBIOOCF+1Tm833faNg==} - '@tybys/wasm-util@0.9.0': resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - '@types/babel__generator@7.6.8': - resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} '@types/babel__template@7.4.4': resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - '@types/babel__traverse@7.20.6': - resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + '@types/babel__traverse@7.20.7': + resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} '@types/cssnano@5.1.3': resolution: {integrity: sha512-BahAZSSvuFXyhgJiwQgsfsNlStE9K/ULGL+YEzK4mmL2Vf02Pjl2yZs+KmbkAg3MxkC9WwMuFwuwnwvrg7CqvQ==} deprecated: This is a stub types definition. cssnano provides its own type definitions, so you do not need this installed. - '@types/doctrine@0.0.9': - resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==} - - '@types/estree@1.0.6': - resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} - '@types/estree@1.0.7': resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - '@types/jsdom@21.1.7': - resolution: {integrity: sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==} - '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -2957,15 +2370,6 @@ packages: '@types/linkify-it@5.0.0': resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} - '@types/lodash.isempty@4.4.9': - resolution: {integrity: sha512-DPSFfnT2JmZiAWNWOU8IRZws/Ha6zyGF5m06TydfsY+0dVoQqby2J61Na2QU4YtwiZ+moC6cJS6zWYBJq4wBVw==} - - '@types/lodash.merge@4.6.9': - resolution: {integrity: sha512-23sHDPmzd59kUgWyKGiOMO2Qb9YtqRO/x4IhkgNUiPQ1+5MUVqi6bCZeq9nBJ17msjIMbEIO5u+XW4Kz6aGUhQ==} - - '@types/lodash@4.17.16': - resolution: {integrity: sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==} - '@types/markdown-it@14.1.2': resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} @@ -2981,54 +2385,38 @@ packages: '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - '@types/node@20.17.24': - resolution: {integrity: sha512-d7fGCyB96w9BnWQrOsJtpyiSaBcAYYr75bnK6ZRjDbql2cGLj/3GsL5OYmLPNq76l7Gf2q4Rv9J2o6h5CrD9sA==} - - '@types/node@22.13.10': - resolution: {integrity: sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==} - - '@types/node@22.14.1': - resolution: {integrity: sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==} + '@types/node@20.17.50': + resolution: {integrity: sha512-Mxiq0ULv/zo1OzOhwPqOA13I81CV/W3nvd3ChtQZRT5Cwz3cr0FKo/wMSsbTqL3EXpaBAEQhva2B8ByRkOIh9A==} '@types/node@22.15.18': resolution: {integrity: sha512-v1DKRfUdyW+jJhZNEI1PYy29S2YRxMV5AOO/x/SjKmW0acCIOqmbj6Haf9eHAhsPmrhlHSxEhv/1WszcLWV4cg==} + '@types/node@22.15.29': + resolution: {integrity: sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ==} + '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} - '@types/parse-path@7.0.3': - resolution: {integrity: sha512-LriObC2+KYZD3FzCrgWGv/qufdUy4eXrxcLgQMfYXgPbLIecKIsVBaQgUPmxSSLcjmYbDTQbMgr6qr6l/eb7Bg==} - - '@types/prop-types@15.7.14': - resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} - - '@types/randombytes@2.0.3': - resolution: {integrity: sha512-+NRgihTfuURllWCiIAhm1wsJqzsocnqXM77V/CalsdJIYSRGEHMnritxh+6EsBklshC+clo1KgnN14qgSGeQdw==} - - '@types/react-dom@18.3.5': - resolution: {integrity: sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==} - peerDependencies: - '@types/react': ^18.0.0 + '@types/parse-path@7.1.0': + resolution: {integrity: sha512-EULJ8LApcVEPbrfND0cRQqutIOdiIgJ1Mgrhpy755r14xMohPTEpkV/k28SJvuOs9bHRFW8x+KeDAEPiGQPB9Q==} + deprecated: This is a stub types definition. parse-path provides its own type definitions, so you do not need this installed. - '@types/react-transition-group@4.4.12': - resolution: {integrity: sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==} + '@types/react-dom@19.1.5': + resolution: {integrity: sha512-CMCjrWucUBZvohgZxkjd6S9h0nZxXjzus6yDfUb+xLxYM7VvjKNH1tQrE9GWLql1XoOP4/Ds3bwFqShHUYraGg==} peerDependencies: - '@types/react': '*' + '@types/react': ^19.0.0 - '@types/react@18.3.18': - resolution: {integrity: sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==} + '@types/react@19.1.5': + resolution: {integrity: sha512-piErsCVVbpMMT2r7wbawdZsq4xMvIAhQuac2gedQHysu1TZYEigE6pnFfgZT+/jQnrRuF5r+SHzuehFjfRjr4g==} '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} - '@types/semver@7.5.8': - resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} - - '@types/tough-cookie@4.0.5': - resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + '@types/semver@7.7.0': + resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==} '@types/triple-beam@1.3.5': resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} @@ -3075,19 +2463,19 @@ packages: typescript: optional: true - '@typescript-eslint/eslint-plugin@8.26.1': - resolution: {integrity: sha512-2X3mwqsj9Bd3Ciz508ZUtoQQYpOhU/kWoUqIf49H8Z0+Vbh6UF/y0OEYp0Q0axOGzaBGs7QxRwq0knSQ8khQNA==} + '@typescript-eslint/eslint-plugin@8.32.1': + resolution: {integrity: sha512-6u6Plg9nP/J1GRpe/vcjjabo6Uc5YQPAMxsgQyGC/I0RuukiG1wIe3+Vtg3IrSCVJDmqK3j8adrtzXSENRtFgg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/eslint-plugin@8.30.1': - resolution: {integrity: sha512-v+VWphxMjn+1t48/jO4t950D6KR8JaJuNXzi33Ve6P8sEmPr5k6CEXjdGwT6+LodVnEa91EQCtwjWNUCPweo+Q==} + '@typescript-eslint/eslint-plugin@8.33.1': + resolution: {integrity: sha512-TDCXj+YxLgtvxvFlAvpoRv9MAncDLBV2oT9Bd7YBGC/b/sEURoOYuIwLI99rjWOfY3QtDzO+mk0n4AmdFExW8A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + '@typescript-eslint/parser': ^8.33.1 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' @@ -3127,20 +2515,26 @@ packages: typescript: optional: true - '@typescript-eslint/parser@8.26.1': - resolution: {integrity: sha512-w6HZUV4NWxqd8BdeFf81t07d7/YV9s7TCWrQQbG5uhuvGUAW+fq1usZ1Hmz9UPNLniFnD8GLSsDpjP0hm1S4lQ==} + '@typescript-eslint/parser@8.32.1': + resolution: {integrity: sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/parser@8.30.1': - resolution: {integrity: sha512-H+vqmWwT5xoNrXqWs/fesmssOW70gxFlgcMlYcBaWNPIEWDgLa4W9nkSPmhuOgLnXq9QYgkZ31fhDyLhleCsAg==} + '@typescript-eslint/parser@8.33.1': + resolution: {integrity: sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/project-service@8.33.1': + resolution: {integrity: sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/scope-manager@5.62.0': resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3153,13 +2547,19 @@ packages: resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/scope-manager@8.26.1': - resolution: {integrity: sha512-6EIvbE5cNER8sqBu6V7+KeMZIC1664d2Yjt+B9EWUXrsyWpxx4lEZrmvxgSKRC6gX+efDL/UY9OpPZ267io3mg==} + '@typescript-eslint/scope-manager@8.32.1': + resolution: {integrity: sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/scope-manager@8.33.1': + resolution: {integrity: sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.30.1': - resolution: {integrity: sha512-+C0B6ChFXZkuaNDl73FJxRYT0G7ufVPOSQkqkpM/U198wUwUFOtgo1k/QzFh1KjpBitaK7R1tgjVz6o9HmsRPg==} + '@typescript-eslint/tsconfig-utils@8.33.1': + resolution: {integrity: sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' '@typescript-eslint/type-utils@5.62.0': resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} @@ -3191,15 +2591,15 @@ packages: typescript: optional: true - '@typescript-eslint/type-utils@8.26.1': - resolution: {integrity: sha512-Kcj/TagJLwoY/5w9JGEFV0dclQdyqw9+VMndxOJKtoFSjfZhLXhYjzsQEeyza03rwHx2vFEGvrJWJBXKleRvZg==} + '@typescript-eslint/type-utils@8.32.1': + resolution: {integrity: sha512-mv9YpQGA8iIsl5KyUPi+FGLm7+bA4fgXaeRcFKRDRwDMu4iwrSHeDPipwueNXhdIIZltwCJv+NkxftECbIZWfA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/type-utils@8.30.1': - resolution: {integrity: sha512-64uBF76bfQiJyHgZISC7vcNz3adqQKIccVoKubyQcOnNcdJBvYOILV1v22Qhsw3tw3VQu5ll8ND6hycgAR5fEA==} + '@typescript-eslint/type-utils@8.33.1': + resolution: {integrity: sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -3217,12 +2617,12 @@ packages: resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/types@8.26.1': - resolution: {integrity: sha512-n4THUQW27VmQMx+3P+B0Yptl7ydfceUj4ON/AQILAASwgYdZ/2dhfymRMh5egRUrvK5lSmaOm77Ry+lmXPOgBQ==} + '@typescript-eslint/types@8.32.1': + resolution: {integrity: sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.30.1': - resolution: {integrity: sha512-81KawPfkuulyWo5QdyG/LOKbspyyiW+p4vpn4bYO7DM/hZImlVnFwrpCTnmNMOt8CvLRr5ojI9nU1Ekpw4RcEw==} + '@typescript-eslint/types@8.33.1': + resolution: {integrity: sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@5.62.0': @@ -3252,14 +2652,14 @@ packages: typescript: optional: true - '@typescript-eslint/typescript-estree@8.26.1': - resolution: {integrity: sha512-yUwPpUHDgdrv1QJ7YQal3cMVBGWfnuCdKbXw1yyjArax3353rEJP1ZA+4F8nOlQ3RfS2hUN/wze3nlY+ZOhvoA==} + '@typescript-eslint/typescript-estree@8.32.1': + resolution: {integrity: sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/typescript-estree@8.30.1': - resolution: {integrity: sha512-kQQnxymiUy9tTb1F2uep9W6aBiYODgq5EMSk6Nxh4Z+BDUoYUSa029ISs5zTzKBFnexQEh71KqwjKnRz58lusQ==} + '@typescript-eslint/typescript-estree@8.33.1': + resolution: {integrity: sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.9.0' @@ -3282,15 +2682,15 @@ packages: peerDependencies: eslint: ^8.56.0 - '@typescript-eslint/utils@8.26.1': - resolution: {integrity: sha512-V4Urxa/XtSUroUrnI7q6yUTD3hDtfJ2jzVfeT3VK0ciizfK2q/zGC0iDh1lFMUZR8cImRrep6/q0xd/1ZGPQpg==} + '@typescript-eslint/utils@8.32.1': + resolution: {integrity: sha512-DsSFNIgLSrc89gpq1LJB7Hm1YpuhK086DRDJSNrewcGvYloWW1vZLHBTIvarKZDcAORIy/uWNx8Gad+4oMpkSA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/utils@8.30.1': - resolution: {integrity: sha512-T/8q4R9En2tcEsWPQgB5BQ0XJVOtfARcUvOa8yJP3fh9M/mXraLxZrkCfGb6ChrO/V3W+Xbd04RacUEqk1CFEQ==} + '@typescript-eslint/utils@8.33.1': + resolution: {integrity: sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -3308,150 +2708,125 @@ packages: resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/visitor-keys@8.26.1': - resolution: {integrity: sha512-AjOC3zfnxd6S4Eiy3jwktJPclqhFHNyd8L6Gycf9WUPoKZpgM5PjkxY1X7uSy61xVpiJDhhk7XT2NVsN3ALTWg==} + '@typescript-eslint/visitor-keys@8.32.1': + resolution: {integrity: sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.30.1': - resolution: {integrity: sha512-aEhgas7aJ6vZnNFC7K4/vMGDGyOiqWcYZPpIWrTKuTAlsvDNKy2GFDqh9smL+iq069ZvR0YzEeq0B8NJlLzjFA==} + '@typescript-eslint/visitor-keys@8.33.1': + resolution: {integrity: sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - '@unhead/vue@2.0.5': - resolution: {integrity: sha512-csjNmBHvJGzSestlpApOpgxqaTdXSN2zwNIPFuWB+C4rtLX4x3+Tm7C5rQwU0iYy3CNJGjJT9cCcSyV55Jg4EQ==} - peerDependencies: - vue: '>=3.5.13' - - '@unhead/vue@2.0.8': - resolution: {integrity: sha512-e30+CfCl1avR+hzFtpvnBSesZ5TN2KbShStdT2Z+zs5WIBUvobQwVxSR0arX43To6KfwtCXAfi0iOOIH0kufHQ==} + '@unhead/vue@2.0.10': + resolution: {integrity: sha512-lV7E1sXX6/te8+IiUwlMysBAyJT/WM5Je47cRnpU5hsvDRziSIGfim9qMWbsTouH+paavRJz1i8gk5hRzjvkcw==} peerDependencies: vue: '>=3.5.13' - '@unrs/resolver-binding-darwin-arm64@1.5.0': - resolution: {integrity: sha512-YmocNlEcX/AgJv8gI41bhjMOTcKcea4D2nRIbZj+MhRtSH5+vEU8r/pFuTuoF+JjVplLsBueU+CILfBPVISyGQ==} + '@unrs/resolver-binding-darwin-arm64@1.7.2': + resolution: {integrity: sha512-vxtBno4xvowwNmO/ASL0Y45TpHqmNkAaDtz4Jqb+clmcVSSl8XCG/PNFFkGsXXXS6AMjP+ja/TtNCFFa1QwLRg==} cpu: [arm64] os: [darwin] - '@unrs/resolver-binding-darwin-x64@1.5.0': - resolution: {integrity: sha512-qpUrXgH4e/0xu1LOhPEdfgSY3vIXOxDQv370NEL8npN8h40HcQDA+Pl2r4HBW6tTXezWIjxUFcP7tj529RZtDw==} + '@unrs/resolver-binding-darwin-x64@1.7.2': + resolution: {integrity: sha512-qhVa8ozu92C23Hsmv0BF4+5Dyyd5STT1FolV4whNgbY6mj3kA0qsrGPe35zNR3wAN7eFict3s4Rc2dDTPBTuFQ==} cpu: [x64] os: [darwin] - '@unrs/resolver-binding-freebsd-x64@1.5.0': - resolution: {integrity: sha512-3tX8r8vgjvZzaJZB4jvxUaaFCDCb3aWDCpZN3EjhGnnwhztslI05KSG5NY/jNjlcZ5QWZ7dEZZ/rNBFsmTaSPw==} + '@unrs/resolver-binding-freebsd-x64@1.7.2': + resolution: {integrity: sha512-zKKdm2uMXqLFX6Ac7K5ElnnG5VIXbDlFWzg4WJ8CGUedJryM5A3cTgHuGMw1+P5ziV8CRhnSEgOnurTI4vpHpg==} cpu: [x64] os: [freebsd] - '@unrs/resolver-binding-linux-arm-gnueabihf@1.5.0': - resolution: {integrity: sha512-FH+ixzBKaUU9fWOj3TYO+Yn/eO6kYvMLV9eNJlJlkU7OgrxkCmiMS6wUbyT0KA3FOZGxnEQ2z3/BHgYm2jqeLA==} + '@unrs/resolver-binding-linux-arm-gnueabihf@1.7.2': + resolution: {integrity: sha512-8N1z1TbPnHH+iDS/42GJ0bMPLiGK+cUqOhNbMKtWJ4oFGzqSJk/zoXFzcQkgtI63qMcUI7wW1tq2usZQSb2jxw==} cpu: [arm] os: [linux] - '@unrs/resolver-binding-linux-arm-musleabihf@1.5.0': - resolution: {integrity: sha512-pxCgXMgwB/4PfqFQg73lMhmWwcC0j5L+dNXhZoz/0ek0iS/oAWl65fxZeT/OnU7fVs52MgdP2q02EipqJJXHSg==} + '@unrs/resolver-binding-linux-arm-musleabihf@1.7.2': + resolution: {integrity: sha512-tjYzI9LcAXR9MYd9rO45m1s0B/6bJNuZ6jeOxo1pq1K6OBuRMMmfyvJYval3s9FPPGmrldYA3mi4gWDlWuTFGA==} cpu: [arm] os: [linux] - '@unrs/resolver-binding-linux-arm64-gnu@1.5.0': - resolution: {integrity: sha512-FX2FV7vpLE/+Z0NZX9/1pwWud5Wocm/2PgpUXbT5aSV3QEB10kBPJAzssOQylvdj8mOHoKl5pVkXpbCwww/T2g==} + '@unrs/resolver-binding-linux-arm64-gnu@1.7.2': + resolution: {integrity: sha512-jon9M7DKRLGZ9VYSkFMflvNqu9hDtOCEnO2QAryFWgT6o6AXU8du56V7YqnaLKr6rAbZBWYsYpikF226v423QA==} cpu: [arm64] os: [linux] - '@unrs/resolver-binding-linux-arm64-musl@1.5.0': - resolution: {integrity: sha512-+gF97xst1BZb28T3nwwzEtq2ewCoMDGKsenYsZuvpmNrW0019G1iUAunZN+FG55L21y+uP7zsGX06OXDQ/viKw==} + '@unrs/resolver-binding-linux-arm64-musl@1.7.2': + resolution: {integrity: sha512-c8Cg4/h+kQ63pL43wBNaVMmOjXI/X62wQmru51qjfTvI7kmCy5uHTJvK/9LrF0G8Jdx8r34d019P1DVJmhXQpA==} cpu: [arm64] os: [linux] - '@unrs/resolver-binding-linux-ppc64-gnu@1.5.0': - resolution: {integrity: sha512-5bEmVcQw9js8JYM2LkUBw5SeELSIxX+qKf9bFrfFINKAp4noZ//hUxLpbF7u/3gTBN1GsER6xOzIZlw/VTdXtA==} + '@unrs/resolver-binding-linux-ppc64-gnu@1.7.2': + resolution: {integrity: sha512-A+lcwRFyrjeJmv3JJvhz5NbcCkLQL6Mk16kHTNm6/aGNc4FwPHPE4DR9DwuCvCnVHvF5IAd9U4VIs/VvVir5lg==} cpu: [ppc64] os: [linux] - '@unrs/resolver-binding-linux-riscv64-gnu@1.5.0': - resolution: {integrity: sha512-GGk/8TPUsf1Q99F+lzMdjE6sGL26uJCwQ9TlvBs8zR3cLQNw/MIumPN7zrs3GFGySjnwXc8gA6J3HKbejywmqA==} + '@unrs/resolver-binding-linux-riscv64-gnu@1.7.2': + resolution: {integrity: sha512-hQQ4TJQrSQW8JlPm7tRpXN8OCNP9ez7PajJNjRD1ZTHQAy685OYqPrKjfaMw/8LiHCt8AZ74rfUVHP9vn0N69Q==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-musl@1.7.2': + resolution: {integrity: sha512-NoAGbiqrxtY8kVooZ24i70CjLDlUFI7nDj3I9y54U94p+3kPxwd2L692YsdLa+cqQ0VoqMWoehDFp21PKRUoIQ==} cpu: [riscv64] os: [linux] - '@unrs/resolver-binding-linux-s390x-gnu@1.5.0': - resolution: {integrity: sha512-5uRkFYYVNAeVaA4W/CwugjFN3iDOHCPqsBLCCOoJiMfFMMz4evBRsg+498OFa9w6VcTn2bD5aI+RRayaIgk2Sw==} + '@unrs/resolver-binding-linux-s390x-gnu@1.7.2': + resolution: {integrity: sha512-KaZByo8xuQZbUhhreBTW+yUnOIHUsv04P8lKjQ5otiGoSJ17ISGYArc+4vKdLEpGaLbemGzr4ZeUbYQQsLWFjA==} cpu: [s390x] os: [linux] - '@unrs/resolver-binding-linux-x64-gnu@1.5.0': - resolution: {integrity: sha512-j905CZH3nehYy6NimNqC2B14pxn4Ltd7guKMyPTzKehbFXTUgihQS/ZfHQTdojkMzbSwBOSgq1dOrY+IpgxDsA==} + '@unrs/resolver-binding-linux-x64-gnu@1.7.2': + resolution: {integrity: sha512-dEidzJDubxxhUCBJ/SHSMJD/9q7JkyfBMT77Px1npl4xpg9t0POLvnWywSk66BgZS/b2Hy9Y1yFaoMTFJUe9yg==} cpu: [x64] os: [linux] - '@unrs/resolver-binding-linux-x64-musl@1.5.0': - resolution: {integrity: sha512-dmLevQTuzQRwu5A+mvj54R5aye5I4PVKiWqGxg8tTaYP2k2oTs/3Mo8mgnhPk28VoYCi0fdFYpgzCd4AJndQvQ==} + '@unrs/resolver-binding-linux-x64-musl@1.7.2': + resolution: {integrity: sha512-RvP+Ux3wDjmnZDT4XWFfNBRVG0fMsc+yVzNFUqOflnDfZ9OYujv6nkh+GOr+watwrW4wdp6ASfG/e7bkDradsw==} cpu: [x64] os: [linux] - '@unrs/resolver-binding-wasm32-wasi@1.5.0': - resolution: {integrity: sha512-LtJMhwu7avhoi+kKfAZOKN773RtzLBVVF90YJbB0wyMpUj9yQPeA+mteVUI9P70OG/opH47FeV5AWeaNWWgqJg==} + '@unrs/resolver-binding-wasm32-wasi@1.7.2': + resolution: {integrity: sha512-y797JBmO9IsvXVRCKDXOxjyAE4+CcZpla2GSoBQ33TVb3ILXuFnMrbR/QQZoauBYeOFuu4w3ifWLw52sdHGz6g==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@unrs/resolver-binding-win32-arm64-msvc@1.5.0': - resolution: {integrity: sha512-FTZBxLL4SO1mgIM86KykzJmPeTPisBDHQV6xtfDXbTMrentuZ6SdQKJUV5BWaoUK3p8kIULlrCcucqdCnk8Npg==} + '@unrs/resolver-binding-win32-arm64-msvc@1.7.2': + resolution: {integrity: sha512-gtYTh4/VREVSLA+gHrfbWxaMO/00y+34htY7XpioBTy56YN2eBjkPrY1ML1Zys89X3RJDKVaogzwxlM1qU7egg==} cpu: [arm64] os: [win32] - '@unrs/resolver-binding-win32-ia32-msvc@1.5.0': - resolution: {integrity: sha512-i5bB7vJ1waUsFciU/FKLd4Zw0VnAkvhiJ4//jYQXyDUuiLKodmtQZVTcOPU7pp97RrNgCFtXfC1gnvj/DHPJTw==} + '@unrs/resolver-binding-win32-ia32-msvc@1.7.2': + resolution: {integrity: sha512-Ywv20XHvHTDRQs12jd3MY8X5C8KLjDbg/jyaal/QLKx3fAShhJyD4blEANInsjxW3P7isHx1Blt56iUDDJO3jg==} cpu: [ia32] os: [win32] - '@unrs/resolver-binding-win32-x64-msvc@1.5.0': - resolution: {integrity: sha512-wAvXp4k7jhioi4SebXW/yfzzYwsUCr9kIX4gCsUFKpCTUf8Mi7vScJXI3S+kupSUf0LbVHudR8qBbe2wFMSNUw==} + '@unrs/resolver-binding-win32-x64-msvc@1.7.2': + resolution: {integrity: sha512-friS8NEQfHaDbkThxopGk+LuE5v3iY0StruifjQEt7SLbA46OnfgMO15sOTkbpJkol6RB+1l1TYPXh0sCddpvA==} cpu: [x64] os: [win32] - '@vercel/nft@0.27.7': - resolution: {integrity: sha512-FG6H5YkP4bdw9Ll1qhmbxuE8KwW2E/g8fJpM183fWQLeVDGqzeywMIeJ9h2txdWZ03psgWMn6QymTxaDLmdwUg==} - engines: {node: '>=16'} - hasBin: true - - '@vercel/nft@0.29.2': - resolution: {integrity: sha512-A/Si4mrTkQqJ6EXJKv5EYCDQ3NL6nJXxG8VGXePsaiQigsomHYQC9xSpX8qGk7AEZk4b1ssbYIqJ0ISQQ7bfcA==} + '@vercel/nft@0.29.3': + resolution: {integrity: sha512-aVV0E6vJpuvImiMwU1/5QKkw2N96BRFE7mBYGS7FhXUoS6V7SarQ+8tuj33o7ofECz8JtHpmQ9JW+oVzOoB7MA==} engines: {node: '>=18'} hasBin: true - '@vitejs/plugin-basic-ssl@1.2.0': - resolution: {integrity: sha512-mkQnxTkcldAzIsomk1UuLfAu9n+kpQ3JbHcpCp7d2Oo6ITtji8pHS3QToOWjhPFvNQSnhlkAjmGbhv2QvwO/7Q==} - engines: {node: '>=14.21.3'} - peerDependencies: - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 - - '@vitejs/plugin-react@4.3.4': - resolution: {integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==} + '@vitejs/plugin-react@4.5.1': + resolution: {integrity: sha512-uPZBqSI0YD4lpkIru6M35sIfylLGTyhGHvDZbNLuMA73lMlwJKz5xweH7FajfcCAc2HnINciejA9qTz0dr0M7A==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 - '@vitejs/plugin-vue-jsx@4.1.2': - resolution: {integrity: sha512-4Rk0GdE0QCdsIkuMmWeg11gmM4x8UmTnZR/LWPm7QJ7+BsK4tq08udrN0isrrWqz5heFy9HLV/7bOLgFS8hUjA==} + '@vitejs/plugin-vue-jsx@4.2.0': + resolution: {integrity: sha512-DSTrmrdLp+0LDNF77fqrKfx7X0ErRbOcUAgJL/HbSesqQwoUvUQ4uYQqaex+rovqgGcoPqVk+AwUh3v9CuiYIw==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: vite: ^5.0.0 || ^6.0.0 vue: ^3.0.0 - '@vitejs/plugin-vue@5.2.1': - resolution: {integrity: sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==} - engines: {node: ^18.0.0 || >=20.0.0} - peerDependencies: - vite: ^5.0.0 || ^6.0.0 - vue: ^3.2.25 - - '@vitejs/plugin-vue@5.2.3': - resolution: {integrity: sha512-IYSLEQj4LgZZuoVpdSUCw3dIynTWQgPlaRP6iAvMle4My0HdYwr5g5wQAfwOeHQBmYwEkqF70nRpSilr6PoUDg==} - engines: {node: ^18.0.0 || >=20.0.0} - peerDependencies: - vite: ^5.0.0 || ^6.0.0 - vue: ^3.2.25 - '@vitejs/plugin-vue@5.2.4': resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -3459,47 +2834,35 @@ packages: vite: ^5.0.0 || ^6.0.0 vue: ^3.2.25 - '@vitest/coverage-v8@3.0.8': - resolution: {integrity: sha512-y7SAKsQirsEJ2F8bulBck4DoluhI2EEgTimHd6EEUgJBGKy9tC25cpywh1MH4FvDGoG2Unt7+asVd1kj4qOSAw==} + '@vitest/browser@3.1.3': + resolution: {integrity: sha512-Dgyez9LbHJHl9ObZPo5mu4zohWLo7SMv8zRWclMF+dxhQjmOtEP0raEX13ac5ygcvihNoQPBZXdya5LMSbcCDQ==} peerDependencies: - '@vitest/browser': 3.0.8 - vitest: 3.0.8 + playwright: '*' + safaridriver: '*' + vitest: 3.1.3 + webdriverio: ^7.0.0 || ^8.0.0 || ^9.0.0 peerDependenciesMeta: - '@vitest/browser': + playwright: optional: true - - '@vitest/eslint-plugin@1.1.31': - resolution: {integrity: sha512-xlsLr+e+AXZ/00eVZCtNmMeCJoJaRCoLDiAgLcxgQjSS1EertieB2MUHf8xIqPKs9lECc/UpL+y1xDcpvi02hw==} - peerDependencies: - '@typescript-eslint/utils': '>= 8.0' - eslint: '>= 8.57.0' - typescript: '>= 5.0.0' - vitest: '*' - peerDependenciesMeta: - typescript: + safaridriver: optional: true - vitest: + webdriverio: optional: true - '@vitest/expect@3.0.8': - resolution: {integrity: sha512-Xu6TTIavTvSSS6LZaA3EebWFr6tsoXPetOWNMOlc7LO88QVVBwq2oQWBoDiLCN6YTvNYsGSjqOO8CAdjom5DCQ==} - - '@vitest/expect@3.1.1': - resolution: {integrity: sha512-q/zjrW9lgynctNbwvFtQkGK9+vvHA5UzVi2V8APrp1C6fG6/MuYYkmlx4FubuqLycCeSdHD5aadWfua/Vr0EUA==} - - '@vitest/mocker@3.0.8': - resolution: {integrity: sha512-n3LjS7fcW1BCoF+zWZxG7/5XvuYH+lsFg+BDwwAz0arIwHQJFUEsKBQ0BLU49fCxuM/2HSeBPHQD8WjgrxMfow==} + '@vitest/coverage-v8@3.0.8': + resolution: {integrity: sha512-y7SAKsQirsEJ2F8bulBck4DoluhI2EEgTimHd6EEUgJBGKy9tC25cpywh1MH4FvDGoG2Unt7+asVd1kj4qOSAw==} peerDependencies: - msw: ^2.4.9 - vite: ^5.0.0 || ^6.0.0 + '@vitest/browser': 3.0.8 + vitest: 3.0.8 peerDependenciesMeta: - msw: - optional: true - vite: + '@vitest/browser': optional: true - '@vitest/mocker@3.1.1': - resolution: {integrity: sha512-bmpJJm7Y7i9BBELlLuuM1J1Q6EQ6K5Ye4wcyOpOMXMcePYKSIYlpcrCm4l/O6ja4VJA5G2aMJiuZkZdnxlC3SA==} + '@vitest/expect@3.1.3': + resolution: {integrity: sha512-7FTQQuuLKmN1Ig/h+h/GO+44Q1IlglPlR2es4ab7Yvfx+Uk5xsv+Ykk+MEt/M2Yn/xGmzaLKxGw2lgy2bwuYqg==} + + '@vitest/mocker@3.1.3': + resolution: {integrity: sha512-PJbLjonJK82uCWHjzgBJZuR7zmAOrSvKk1QBxrennDIgtH4uK0TB1PvYmc0XBCigxxtiAVPfWtAdy4lpz8SQGQ==} peerDependencies: msw: ^2.4.9 vite: ^5.0.0 || ^6.0.0 @@ -3509,49 +2872,34 @@ packages: vite: optional: true - '@vitest/pretty-format@3.0.8': - resolution: {integrity: sha512-BNqwbEyitFhzYMYHUVbIvepOyeQOSFA/NeJMIP9enMntkkxLgOcgABH6fjyXG85ipTgvero6noreavGIqfJcIg==} - - '@vitest/pretty-format@3.1.1': - resolution: {integrity: sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==} + '@vitest/pretty-format@3.1.3': + resolution: {integrity: sha512-i6FDiBeJUGLDKADw2Gb01UtUNb12yyXAqC/mmRWuYl+m/U9GS7s8us5ONmGkGpUUo7/iAYzI2ePVfOZTYvUifA==} - '@vitest/runner@3.0.8': - resolution: {integrity: sha512-c7UUw6gEcOzI8fih+uaAXS5DwjlBaCJUo7KJ4VvJcjL95+DSR1kova2hFuRt3w41KZEFcOEiq098KkyrjXeM5w==} + '@vitest/runner@3.1.3': + resolution: {integrity: sha512-Tae+ogtlNfFei5DggOsSUvkIaSuVywujMj6HzR97AHK6XK8i3BuVyIifWAm/sE3a15lF5RH9yQIrbXYuo0IFyA==} - '@vitest/runner@3.1.1': - resolution: {integrity: sha512-X/d46qzJuEDO8ueyjtKfxffiXraPRfmYasoC4i5+mlLEJ10UvPb0XH5M9C3gWuxd7BAQhpK42cJgJtq53YnWVA==} + '@vitest/snapshot@3.1.3': + resolution: {integrity: sha512-XVa5OPNTYUsyqG9skuUkFzAeFnEzDp8hQu7kZ0N25B1+6KjGm4hWLtURyBbsIAOekfWQ7Wuz/N/XXzgYO3deWQ==} - '@vitest/snapshot@3.0.8': - resolution: {integrity: sha512-x8IlMGSEMugakInj44nUrLSILh/zy1f2/BgH0UeHpNyOocG18M9CWVIFBaXPt8TrqVZWmcPjwfG/ht5tnpba8A==} + '@vitest/spy@3.1.3': + resolution: {integrity: sha512-x6w+ctOEmEXdWaa6TO4ilb7l9DxPR5bwEb6hILKuxfU1NqWT2mpJD9NJN7t3OTfxmVlOMrvtoFJGdgyzZ605lQ==} - '@vitest/snapshot@3.1.1': - resolution: {integrity: sha512-bByMwaVWe/+1WDf9exFxWWgAixelSdiwo2p33tpqIlM14vW7PRV5ppayVXtfycqze4Qhtwag5sVhX400MLBOOw==} + '@vitest/utils@3.1.3': + resolution: {integrity: sha512-2Ltrpht4OmHO9+c/nmHtF09HWiyWdworqnHIwjfvDyWjuwKbdkcS9AnhsDn+8E2RM4x++foD1/tNuLPVvWG1Rg==} - '@vitest/spy@3.0.8': - resolution: {integrity: sha512-MR+PzJa+22vFKYb934CejhR4BeRpMSoxkvNoDit68GQxRLSf11aT6CTj3XaqUU9rxgWJFnqicN/wxw6yBRkI1Q==} - - '@vitest/spy@3.1.1': - resolution: {integrity: sha512-+EmrUOOXbKzLkTDwlsc/xrwOlPDXyVk3Z6P6K4oiCndxz7YLpp/0R0UsWVOKT0IXWjjBJuSMk6D27qipaupcvQ==} - - '@vitest/utils@3.0.8': - resolution: {integrity: sha512-nkBC3aEhfX2PdtQI/QwAWp8qZWwzASsU4Npbcd5RdMPBSSLCpkZp52P3xku3s3uA0HIEhGvEcF8rNkBsz9dQ4Q==} - - '@vitest/utils@3.1.1': - resolution: {integrity: sha512-1XIjflyaU2k3HMArJ50bwSh3wKWPD6Q47wz/NUSmRV0zNywPc4w79ARjg/i/aNINHwA+mIALhUVqD9/aUvZNgg==} - - '@vitest/web-worker@3.0.8': - resolution: {integrity: sha512-7XO1wID/LB2srFtD3tleBNl0dfNsJRqzX83nA7XxP/bmQ49woE2tcvprAv7JWPRJbBvgTFw9Q3+YvkHuv9bTmg==} + '@vitest/web-worker@3.1.4': + resolution: {integrity: sha512-Bm2r4y3Gpl81qIz/7lvUy43fhGRiBqXOgfE/FzQtfRKKDfpsRu7ZfbcGFHe20oyE9fb55we1IXRSq1lsBwB1hA==} peerDependencies: - vitest: 3.0.8 + vitest: 3.1.4 - '@volar/language-core@2.4.12': - resolution: {integrity: sha512-RLrFdXEaQBWfSnYGVxvR2WrO6Bub0unkdHYIdC31HzIEqATIuuhRRzYu76iGPZ6OtA4Au1SnW0ZwIqPP217YhA==} + '@volar/language-core@2.4.14': + resolution: {integrity: sha512-X6beusV0DvuVseaOEy7GoagS4rYHgDHnTrdOj5jeUb49fW5ceQyP9Ej5rBhqgz2wJggl+2fDbbojq1XKaxDi6w==} - '@volar/source-map@2.4.12': - resolution: {integrity: sha512-bUFIKvn2U0AWojOaqf63ER0N/iHIBYZPpNGogfLPQ68F5Eet6FnLlyho7BS0y2HJ1jFhSif7AcuTx1TqsCzRzw==} + '@volar/source-map@2.4.14': + resolution: {integrity: sha512-5TeKKMh7Sfxo8021cJfmBzcjfY1SsXsPMMjMvjY7ivesdnybqqS+GxGAoXHAOUawQTwtdUxgP65Im+dEmvWtYQ==} - '@volar/typescript@2.4.12': - resolution: {integrity: sha512-HJB73OTJDgPc80K30wxi3if4fSsZZAOScbj2fcicMuOPoOkcf9NNAINb33o+DzhBdF9xTKC1gnPmIRDous5S0g==} + '@volar/typescript@2.4.14': + resolution: {integrity: sha512-p8Z6f/bZM3/HyCdRNFZOEEzts51uV8WHeN8Tnfnm2EBv6FDB2TQLzfVx7aJvnl8ofKAOnS64B2O8bImBFaauRw==} '@vue-macros/common@1.16.1': resolution: {integrity: sha512-Pn/AWMTjoMYuquepLZP813BIcq8DTZiNCoaceuNlvaYuOTd8DqBZWc5u0uOMQZMInwME1mdSmmBAcTluiV9Jtg==} @@ -3578,17 +2926,17 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@vue/compiler-core@3.5.13': - resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} + '@vue/compiler-core@3.5.14': + resolution: {integrity: sha512-k7qMHMbKvoCXIxPhquKQVw3Twid3Kg4s7+oYURxLGRd56LiuHJVrvFKI4fm2AM3c8apqODPfVJGoh8nePbXMRA==} - '@vue/compiler-dom@3.5.13': - resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} + '@vue/compiler-dom@3.5.14': + resolution: {integrity: sha512-1aOCSqxGOea5I80U2hQJvXYpPm/aXo95xL/m/mMhgyPUsKe9jhjwWpziNAw7tYRnbz1I61rd9Mld4W9KmmRoug==} - '@vue/compiler-sfc@3.5.13': - resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} + '@vue/compiler-sfc@3.5.14': + resolution: {integrity: sha512-9T6m/9mMr81Lj58JpzsiSIjBgv2LiVoWjIVa7kuXHICUi8LiDSIotMpPRXYJsXKqyARrzjT24NAwttrMnMaCXA==} - '@vue/compiler-ssr@3.5.13': - resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} + '@vue/compiler-ssr@3.5.14': + resolution: {integrity: sha512-Y0G7PcBxr1yllnHuS/NxNCSPWnRGH4Ogrp0tsLA5QemDZuJLs99YjAKQ7KqkHE0vCg4QTKlQzXLKCMF7WPSl7Q==} '@vue/compiler-vue2@2.7.16': resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} @@ -3596,25 +2944,19 @@ packages: '@vue/devtools-api@6.6.4': resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} - '@vue/devtools-api@7.7.2': - resolution: {integrity: sha512-1syn558KhyN+chO5SjlZIwJ8bV/bQ1nOVTG66t2RbG66ZGekyiYNmRO7X9BJCXQqPsFHlnksqvPhce2qpzxFnA==} + '@vue/devtools-api@7.7.6': + resolution: {integrity: sha512-b2Xx0KvXZObePpXPYHvBRRJLDQn5nhKjXh7vUhMEtWxz1AYNFOVIsh5+HLP8xDGL7sy+Q7hXeUxPHB/KgbtsPw==} - '@vue/devtools-core@7.7.2': - resolution: {integrity: sha512-lexREWj1lKi91Tblr38ntSsy6CvI8ba7u+jmwh2yruib/ltLUcsIzEjCnrkh1yYGGIKXbAuYV2tOG10fGDB9OQ==} + '@vue/devtools-core@7.7.6': + resolution: {integrity: sha512-ghVX3zjKPtSHu94Xs03giRIeIWlb9M+gvDRVpIZ/cRIxKHdW6HE/sm1PT3rUYS3aV92CazirT93ne+7IOvGUWg==} peerDependencies: vue: ^3.0.0 - '@vue/devtools-kit@7.7.2': - resolution: {integrity: sha512-CY0I1JH3Z8PECbn6k3TqM1Bk9ASWxeMtTCvZr7vb+CHi+X/QwQm5F1/fPagraamKMAHVfuuCbdcnNg1A4CYVWQ==} - - '@vue/devtools-shared@7.7.2': - resolution: {integrity: sha512-uBFxnp8gwW2vD6FrJB8JZLUzVb6PNRG0B0jBnHsOH8uKyva2qINY8PTF5Te4QlTbMDqU5K6qtJDr6cNsKWhbOA==} + '@vue/devtools-kit@7.7.6': + resolution: {integrity: sha512-geu7ds7tem2Y7Wz+WgbnbZ6T5eadOvozHZ23Atk/8tksHMFOFylKi1xgGlQlVn0wlkEf4hu+vd5ctj1G4kFtwA==} - '@vue/eslint-config-prettier@10.2.0': - resolution: {integrity: sha512-GL3YBLwv/+b86yHcNNfPJxOTtVFJ4Mbc9UU3zR+KVoG7SwGTjPT+32fXamscNumElhcpXW3mT0DgzS9w32S7Bw==} - peerDependencies: - eslint: '>= 8.21.0' - prettier: '>= 3.0.0' + '@vue/devtools-shared@7.7.6': + resolution: {integrity: sha512-yFEgJZ/WblEsojQQceuyK6FzpFDx4kqrz2ohInxNj5/DnhoX023upTv4OD6lNPLAA5LLkbwPVb10o/7b+Y4FVA==} '@vue/eslint-config-prettier@8.0.0': resolution: {integrity: sha512-55dPqtC4PM/yBjhAr+yEw6+7KzzdkBuLmnhBrDfp4I48+wy+Giqqj9yUr5T2uD/BkBROjjmqnLZmXRdOx/VtQg==} @@ -3633,56 +2975,34 @@ packages: typescript: optional: true - '@vue/eslint-config-typescript@14.5.0': - resolution: {integrity: sha512-5oPOyuwkw++AP5gHDh5YFmST50dPfWOcm3/W7Nbh42IK5O3H74ytWAw0TrCRTaBoD/02khnWXuZf1Bz1xflavQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^9.10.0 - eslint-plugin-vue: ^9.28.0 || ^10.0.0 - typescript: '>=4.8.4' - peerDependenciesMeta: - typescript: - optional: true - - '@vue/language-core@2.2.8': - resolution: {integrity: sha512-rrzB0wPGBvcwaSNRriVWdNAbHQWSf0NlGqgKHK5mEkXpefjUlVRP62u03KvwZpvKVjRnBIQ/Lwre+Mx9N6juUQ==} + '@vue/language-core@2.2.10': + resolution: {integrity: sha512-+yNoYx6XIKuAO8Mqh1vGytu8jkFEOH5C8iOv3i8Z/65A7x9iAOXA97Q+PqZ3nlm2lxf5rOJuIGI/wDtx/riNYw==} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true - '@vue/reactivity@3.5.13': - resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} + '@vue/reactivity@3.5.14': + resolution: {integrity: sha512-7cK1Hp343Fu/SUCCO52vCabjvsYu7ZkOqyYu7bXV9P2yyfjUMUXHZafEbq244sP7gf+EZEz+77QixBTuEqkQQw==} - '@vue/runtime-core@3.5.13': - resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==} + '@vue/runtime-core@3.5.14': + resolution: {integrity: sha512-w9JWEANwHXNgieAhxPpEpJa+0V5G0hz3NmjAZwlOebtfKyp2hKxKF0+qSh0Xs6/PhfGihuSdqMprMVcQU/E6ag==} - '@vue/runtime-dom@3.5.13': - resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==} + '@vue/runtime-dom@3.5.14': + resolution: {integrity: sha512-lCfR++IakeI35TVR80QgOelsUIdcKjd65rWAMfdSlCYnaEY5t3hYwru7vvcWaqmrK+LpI7ZDDYiGU5V3xjMacw==} - '@vue/server-renderer@3.5.13': - resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==} + '@vue/server-renderer@3.5.14': + resolution: {integrity: sha512-Rf/ISLqokIvcySIYnv3tNWq40PLpNLDLSJwwVWzG6MNtyIhfbcrAxo5ZL9nARJhqjZyWWa40oRb2IDuejeuv6w==} peerDependencies: - vue: 3.5.13 + vue: 3.5.14 - '@vue/shared@3.5.13': - resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} + '@vue/shared@3.5.14': + resolution: {integrity: sha512-oXTwNxVfc9EtP1zzXAlSlgARLXNC84frFYkS0HHz0h3E4WZSP9sywqjqzGCP9Y34M8ipNmd380pVgmMuwELDyQ==} '@vue/test-utils@2.4.6': resolution: {integrity: sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==} - '@vue/tsconfig@0.7.0': - resolution: {integrity: sha512-ku2uNz5MaZ9IerPPUyOHzyjhXoX2kVJaVf7hL315DC17vS6IiZRmmCPfggNbU16QTvM80+uYYy3eYJB59WCtvg==} - peerDependencies: - typescript: 5.x - vue: ^3.4.0 - peerDependenciesMeta: - typescript: - optional: true - vue: - optional: true - '@vueuse/core@12.8.2': resolution: {integrity: sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==} @@ -3737,12 +3057,12 @@ packages: resolution: {integrity: sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw==} engines: {node: '>=18.0.0'} - '@whatwg-node/fetch@0.10.7': - resolution: {integrity: sha512-sL31zX8BqZovZc38ovBFmKEfao9AzZ/24sWSHKNhDhcnzIO/PYAX2xF6vYtgU9hinrEGlvScTTyKSMynHGdfEA==} + '@whatwg-node/fetch@0.10.8': + resolution: {integrity: sha512-Rw9z3ctmeEj8QIB9MavkNJqekiu9usBCSMZa+uuAvM0lF3v70oQVCXNppMIqaV6OTZbdaHF1M2HLow58DEw+wg==} engines: {node: '>=18.0.0'} - '@whatwg-node/node-fetch@0.7.19': - resolution: {integrity: sha512-ippPt75epj7Tg6H5znI9lBBQ4gi+x23QsIF7UN1Z02MUqzhbkjhGsUtNnYGS3osrqvyKtbGKmEya6IqIPRmtdw==} + '@whatwg-node/node-fetch@0.7.21': + resolution: {integrity: sha512-QC16IdsEyIW7kZd77aodrMO7zAoDyyqRCTLg+qG4wqtP4JV9AA+p7/lgqMdD29XyiYdVvIdFrfI9yh7B1QvRvw==} engines: {node: '>=18.0.0'} '@whatwg-node/promise-helpers@1.3.2': @@ -3753,8 +3073,8 @@ packages: resolution: {integrity: sha512-ueFCcIPaMgtuYDS9u0qlUoEvj6GiSsKrwnOLPp9SshqjtcRaR1IEHRjoReq3sXNydsF5i0ZnmuYgXq9dV53t0g==} engines: {node: '>=18.0.0'} - '@wso2/eslint-plugin@https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/eslint-plugin?4ee6f6be232d7631999d709a86b91612f1d34ce7': - resolution: {tarball: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/eslint-plugin?4ee6f6be232d7631999d709a86b91612f1d34ce7} + '@wso2/eslint-plugin@https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/eslint-plugin?a1fc6eb570653c999828aea9f5027cba06af4391': + resolution: {tarball: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/eslint-plugin?a1fc6eb570653c999828aea9f5027cba06af4391} version: 0.1.0 engines: {node: ^14.17.0 || ^16.0.0 || >= 18.0.0} peerDependencies: @@ -3764,8 +3084,8 @@ packages: typescript: optional: true - '@wso2/prettier-config@https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/prettier-config?4ee6f6be232d7631999d709a86b91612f1d34ce7': - resolution: {tarball: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/prettier-config?4ee6f6be232d7631999d709a86b91612f1d34ce7} + '@wso2/prettier-config@https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/prettier-config?a1fc6eb570653c999828aea9f5027cba06af4391': + resolution: {tarball: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/prettier-config?a1fc6eb570653c999828aea9f5027cba06af4391} version: 0.1.0 engines: {node: '>=14.0.0'} peerDependencies: @@ -3775,8 +3095,8 @@ packages: typescript: optional: true - '@wso2/stylelint-config@https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/stylelint-config?4ee6f6be232d7631999d709a86b91612f1d34ce7': - resolution: {tarball: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/stylelint-config?4ee6f6be232d7631999d709a86b91612f1d34ce7} + '@wso2/stylelint-config@https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/stylelint-config?a1fc6eb570653c999828aea9f5027cba06af4391': + resolution: {tarball: https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/stylelint-config?a1fc6eb570653c999828aea9f5027cba06af4391} version: 0.1.0 engines: {node: '>=14.0.0'} peerDependencies: @@ -3789,23 +3109,20 @@ packages: '@yarnpkg/lockfile@1.1.0': resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} - '@yarnpkg/parsers@3.0.0-rc.46': - resolution: {integrity: sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==} - engines: {node: '>=14.15.0'} + '@yarnpkg/parsers@3.0.2': + resolution: {integrity: sha512-/HcYgtUSiJiot/XWGLOlGxPYUG65+/31V8oqk17vZLW1xlCoR4PampyePljOxY2n8/3jz9+tIFzICsyGujJZoA==} + engines: {node: '>=18.12.0'} - '@zkochan/js-yaml@0.0.6': - resolution: {integrity: sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg==} + '@zkochan/js-yaml@0.0.7': + resolution: {integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==} hasBin: true - abbrev@1.1.1: - resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} - abbrev@2.0.0: resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - abbrev@3.0.0: - resolution: {integrity: sha512-+/kfrslGQ7TNV2ecmQwMJj/B65g5KVq1/L3SGVZ3tCYGqlzFuFCGBZJtMP99wH3NpEUyAjn0zPdPUg0D+DwrOA==} + abbrev@3.0.1: + resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} engines: {node: ^18.17.0 || >=20.5.0} abort-controller@3.0.0: @@ -3827,10 +3144,6 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} - agent-base@7.1.3: resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} engines: {node: '>= 14'} @@ -3841,12 +3154,12 @@ packages: ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} - algoliasearch@5.21.0: - resolution: {integrity: sha512-hexLq2lSO1K5SW9j21Ubc+q9Ptx7dyRTY7se19U8lhIlVMLCNXWCyQ6C22p9ez8ccX0v7QVmwkl2l1CnuGoO2Q==} + algoliasearch@5.25.0: + resolution: {integrity: sha512-n73BVorL4HIwKlfJKb4SEzAYkR3Buwfwbh+MYxg2mloFph2fFGV58E90QTzdbfzWrLn4HE5Czx/WTjI8fcHaMg==} engines: {node: '>= 14.0.0'} - alien-signals@1.0.4: - resolution: {integrity: sha512-DJqqQD3XcsaQcQ1s+iE2jDUZmmQpXwHiR6fCAim/w87luaW+vmLY8fMlrdkmRwzaFXhkxf3rqPCR59tKVv1MDw==} + alien-signals@1.0.13: + resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==} ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} @@ -3880,25 +3193,10 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} - aproba@2.0.0: - resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} - - archiver-utils@2.1.0: - resolution: {integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==} - engines: {node: '>= 6'} - - archiver-utils@3.0.4: - resolution: {integrity: sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==} - engines: {node: '>= 10'} - archiver-utils@5.0.2: resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} engines: {node: '>= 14'} - archiver@5.3.2: - resolution: {integrity: sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==} - engines: {node: '>= 10'} - archiver@7.0.1: resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==} engines: {node: '>= 14'} @@ -3907,17 +3205,15 @@ packages: resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} engines: {node: '>=14'} - are-we-there-yet@2.0.0: - resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} - engines: {node: '>=10'} - deprecated: This package is no longer supported. - argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + aria-query@5.3.2: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} @@ -3965,20 +3261,17 @@ packages: asn1.js@4.10.1: resolution: {integrity: sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==} - assert@2.1.0: - resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==} - assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} - ast-kit@1.4.2: - resolution: {integrity: sha512-lvGehj1XsrIoQrD5CfPduIzQbcpuX2EPjlk/vDMDQF9U9HLRB6WwMTdighj5n52hdhh8xg9VgPTU7Q25MuJ/rw==} + ast-kit@1.4.3: + resolution: {integrity: sha512-MdJqjpodkS5J149zN0Po+HPshkTdUyrvF7CKTafUgv69vBSPtncrj+3IiUgqdd7ElIEkbeXCsEouBUwLrw9Ilg==} engines: {node: '>=16.14.0'} - ast-module-types@5.0.0: - resolution: {integrity: sha512-JvqziE0Wc0rXQfma0HZC/aY7URXHFuZV84fJRtP8u+lhp0JYCNd5wJzVXP45t0PH0Mej3ynlzvdyITYIu0G4LQ==} - engines: {node: '>=14'} + ast-module-types@6.0.1: + resolution: {integrity: sha512-WHw67kLXYbZuHTmcdbIrVArCq5wxo6NEuj3hiYAWr8mwJeC+C2mMCIBIWCiDoCye/OF/xelc+teJ1ERoWmnEIA==} + engines: {node: '>=18'} ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} @@ -3991,10 +3284,6 @@ packages: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} - astring@1.9.0: - resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} - hasBin: true - async-function@1.0.0: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} @@ -4029,11 +3318,8 @@ packages: axios@0.26.1: resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==} - axios@1.8.3: - resolution: {integrity: sha512-iP4DebzoNlP/YN2dpwCgb8zoCmhtkajzS48JvwmkSkXvPI3DHc7m+XYL5tGnSlJtR6nImXZmdCuN5aP8dh1d8A==} - - axios@1.8.4: - resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==} + axios@1.9.0: + resolution: {integrity: sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==} axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} @@ -4042,10 +3328,6 @@ packages: b4a@1.6.7: resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} - babel-plugin-macros@3.1.0: - resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} - engines: {node: '>=10', npm: '>=6'} - balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -4069,20 +3351,17 @@ packages: bindings@1.5.0: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - birpc@0.2.19: - resolution: {integrity: sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==} - birpc@2.3.0: resolution: {integrity: sha512-ijbtkn/F3Pvzb6jHypHRyve2QApOCZDR25D/VnkY2G/lBNcXCTsnsCxgY4k4PkVB7zfwzYbY3O9Lcqe3xufS5g==} bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - bn.js@4.12.1: - resolution: {integrity: sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==} + bn.js@4.12.2: + resolution: {integrity: sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==} - bn.js@5.2.1: - resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + bn.js@5.2.2: + resolution: {integrity: sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==} boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -4100,9 +3379,6 @@ packages: brorand@1.1.0: resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} - browser-resolve@2.0.0: - resolution: {integrity: sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==} - browserify-aes@1.2.0: resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} @@ -4120,14 +3396,6 @@ packages: resolution: {integrity: sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==} engines: {node: '>= 0.12'} - browserify-zlib@0.2.0: - resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} - - browserslist@4.24.4: - resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - browserslist@4.24.5: resolution: {integrity: sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -4160,15 +3428,16 @@ packages: resolution: {integrity: sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==} engines: {node: '>=18.20'} - builtin-status-codes@3.0.0: - resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==} - bundle-name@4.1.0: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} engines: {node: '>=18'} - c12@3.0.3: - resolution: {integrity: sha512-uC3MacKBb0Z15o5QWCHvHWj5Zv34pGQj9P+iXKSpTuSGFS0KKhUWf4t9AJ+gWjYOdmWCPEGpEzm8sS0iqbpo1w==} + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + + c12@3.0.4: + resolution: {integrity: sha512-t5FaZTYbbCtvxuZq9xxIruYydrAGsJ+8UdP0pZzMiK2xl/gNiSOy0OxhLzHUEEb0m1QXYqfzfvyIFEmz/g9lqg==} peerDependencies: magicast: ^0.3.5 peerDependenciesMeta: @@ -4209,9 +3478,6 @@ packages: caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - caniuse-lite@1.0.30001704: - resolution: {integrity: sha512-+L2IgBbV6gXB4ETf0keSvLr7JUrRVbIaB/lrQ1+z8mRcQiisG5k+lG6O4n6Y5q6f5EuNfaYXKgymucphlEXQew==} - caniuse-lite@1.0.30001718: resolution: {integrity: sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==} @@ -4247,10 +3513,6 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} - chownr@2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} - engines: {node: '>=10'} - chownr@3.0.0: resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} engines: {node: '>=18'} @@ -4282,6 +3544,9 @@ packages: resolution: {integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==} engines: {node: '>=6'} + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + clipboardy@4.0.0: resolution: {integrity: sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w==} engines: {node: '>=18'} @@ -4294,10 +3559,6 @@ packages: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} - clsx@1.2.1: - resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} - engines: {node: '>=6'} - clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -4322,13 +3583,13 @@ packages: color-string@1.9.1: resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} - color-support@1.1.3: - resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} - hasBin: true - color@3.2.1: resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + colord@2.9.3: resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} @@ -4346,6 +3607,10 @@ packages: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -4363,16 +3628,9 @@ packages: commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - compatx@0.1.8: - resolution: {integrity: sha512-jcbsEAR81Bt5s1qOFymBufmCbXCXbk0Ql+K5ouj6gCyx2yHlu6AgmGIi9HxfKixpUDO5bCFJUHQ5uM6ecbTebw==} - compatx@0.2.0: resolution: {integrity: sha512-6gLRNt4ygsi5NyMVhceOCFv14CIdDFN7fQjX1U4+47qVE/+kjPoXMK65KWK+dWxmFzMTuKazoQ9sch6pM0p5oA==} - compress-commons@4.1.2: - resolution: {integrity: sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==} - engines: {node: '>= 10'} - compress-commons@6.0.2: resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} engines: {node: '>= 14'} @@ -4396,21 +3654,9 @@ packages: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} - console-browserify@1.2.0: - resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==} - - console-control-strings@1.1.0: - resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} - - constants-browserify@1.0.0: - resolution: {integrity: sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==} - convert-gitmoji@0.1.5: resolution: {integrity: sha512-4wqOafJdk2tqZC++cjcbGcaJ13BZ3kwldf06PTiAQRAB76Z1KJwZNL1SaRZMi2w1FM9RYTgZ6QErS8NUl/GBmQ==} - convert-source-map@1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} @@ -4428,8 +3674,15 @@ packages: resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} engines: {node: '>=12.13'} - core-js-compat@3.41.0: - resolution: {integrity: sha512-RFsU9LySVue9RTwdDVX/T0e2Y6jRYWXERKElIjpuEOEnxaXffI0X7RUwVzfYLfzuLXSNJDYoRYUAmRUcyln20A==} + copy-file@11.0.0: + resolution: {integrity: sha512-mFsNh/DIANLqFt5VHZoGirdg7bK5+oTWlhnGu6tgRhzBlnEKWaPX2xrFaLltii/6rmhqFMJqffUgknuRdpYlHw==} + engines: {node: '>=18'} + + core-js-compat@3.42.0: + resolution: {integrity: sha512-bQasjMfyDGyaeWKBIu33lHh9qlSR0MFE/Nmc6nMjf/iU9b3rSMdAYz1Baxrv4lPdGUsTqZudHA4jIGSJy0SWZQ==} + + core-js@3.42.0: + resolution: {integrity: sha512-Sz4PP4ZA+Rq4II21qkNqOEDTDrCvcANId3xpIgB34NDkWc3UduWj2dqEtN9yZIq8Dk3HyPI33x9sqqU5C8sr0g==} core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -4447,19 +3700,11 @@ packages: typescript: optional: true - cp-file@10.0.0: - resolution: {integrity: sha512-vy2Vi1r2epK5WqxOLnskeKeZkdZvTKfFZQCplE3XWsP+SUJyd5XAUFC9lFgTjjXJF2GMne/UML14iEmkAaDfFg==} - engines: {node: '>=14.16'} - crc-32@1.2.2: resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} engines: {node: '>=0.8'} hasBin: true - crc32-stream@4.0.3: - resolution: {integrity: sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==} - engines: {node: '>= 10'} - crc32-stream@6.0.0: resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} engines: {node: '>= 14'} @@ -4473,9 +3718,6 @@ packages: create-hmac@1.1.7: resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} - create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - cron-parser@4.9.0: resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==} engines: {node: '>=12.0.0'} @@ -4487,13 +3729,13 @@ packages: cross-fetch@3.2.0: resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} + cross-fetch@4.1.0: + resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - crossws@0.3.4: - resolution: {integrity: sha512-uj0O1ETYX1Bh6uSgktfPvwDiPYGQ3aI4qVsaC/LWpkIzGj1nUYm5FK3K+t11oOlpN01lGbprFCH4wBlKdJjVgw==} - crossws@0.3.5: resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} @@ -4550,12 +3792,6 @@ packages: peerDependencies: postcss: ^8.2.15 - cssnano-preset-default@7.0.6: - resolution: {integrity: sha512-ZzrgYupYxEvdGGuqL+JKOY70s7+saoNlHSCK/OGn1vB2pQK8KSET8jvenzItcY+kA7NoWvfbb/YhlzuzNKjOhQ==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - cssnano-preset-default@7.0.7: resolution: {integrity: sha512-jW6CG/7PNB6MufOrlovs1TvBTEVmhY45yz+bd0h6nw3h6d+1e+/TX+0fflZ+LzvZombbT5f+KC063w9VoHeHow==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -4568,12 +3804,6 @@ packages: peerDependencies: postcss: ^8.2.15 - cssnano-utils@5.0.0: - resolution: {integrity: sha512-Uij0Xdxc24L6SirFr25MlwC2rCFX6scyUmuKpzI+JQ7cyqDEwD42fJ0xfB3yLfOnRDU5LKGgjQ9FA6LYh76GWQ==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - cssnano-utils@5.0.1: resolution: {integrity: sha512-ZIP71eQgG9JwjVZsTPSqhc6GHgEr53uJ7tK5///VfyWj6Xp2DBmixWHqJgPno+PqATzn48pL42ww9x5SSGmhZg==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -4586,12 +3816,6 @@ packages: peerDependencies: postcss: ^8.2.15 - cssnano@7.0.6: - resolution: {integrity: sha512-54woqx8SCbp8HwvNZYn68ZFAepuouZW4lTwiMVnBErM3VkO7/Sd4oTOt3Zz3bPx3kxQ36aISppyXj2Md4lg8bw==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - cssnano@7.0.7: resolution: {integrity: sha512-evKu7yiDIF7oS+EIpwFlMF730ijRyLFaM2o5cTxRGJR9OKHKkc+qP443ZEVR9kZG0syaAJJCPJyfv5pbrxlSng==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -4606,8 +3830,8 @@ packages: resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} - cssstyle@4.3.0: - resolution: {integrity: sha512-6r0NiY0xizYqfBvWp1G7WXJ06/bZyrk7Dc6PHql82C/pKGUTKu4yAX4Y8JPamb1ob9nBKuxWzCGTRuGwU3yxJQ==} + cssstyle@4.3.1: + resolution: {integrity: sha512-ZgW+Jgdd7i52AaLYCriF8Mxqft0gD/R9i9wi6RWBhs1pqdPEzPjym7rvRKi397WmQFf3SlyUsszhw+VVCbx79Q==} engines: {node: '>=18'} csstype@3.1.3: @@ -4639,29 +3863,6 @@ packages: dataloader@1.4.0: resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} - db0@0.3.1: - resolution: {integrity: sha512-3RogPLE2LLq6t4YiFCREyl572aBjkfMvfwPyN51df00TbPbryL3XqBYuJ/j6mgPssPK8AKfYdLxizaO5UG10sA==} - peerDependencies: - '@electric-sql/pglite': '*' - '@libsql/client': '*' - better-sqlite3: '*' - drizzle-orm: '*' - mysql2: '*' - sqlite3: '*' - peerDependenciesMeta: - '@electric-sql/pglite': - optional: true - '@libsql/client': - optional: true - better-sqlite3: - optional: true - drizzle-orm: - optional: true - mysql2: - optional: true - sqlite3: - optional: true - db0@0.3.2: resolution: {integrity: sha512-xzWNQ6jk/+NtdfLyXEipbX55dmDSeteLFt/ayF+wZUU5bzKgmrDOxmInUTbyVRp46YwnJdkDA1KhB7WIXFofJw==} peerDependencies: @@ -4688,14 +3889,6 @@ packages: de-indent@1.0.2: resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} - debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -4704,8 +3897,8 @@ packages: supports-color: optional: true - debug@4.4.0: - resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -4776,9 +3969,6 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} - delegates@1.0.0: - resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} - denque@2.1.0: resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} engines: {node: '>=0.10'} @@ -4797,10 +3987,6 @@ packages: destr@2.0.5: resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} - destroy@1.2.0: - resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - detect-indent@6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} @@ -4810,42 +3996,52 @@ packages: engines: {node: '>=0.10'} hasBin: true - detect-libc@2.0.3: - resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + detect-libc@2.0.4: + resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} engines: {node: '>=8'} - detective-amd@5.0.2: - resolution: {integrity: sha512-XFd/VEQ76HSpym80zxM68ieB77unNuoMwopU2TFT/ErUk5n4KvUTwW4beafAVUugrjV48l4BmmR0rh2MglBaiA==} - engines: {node: '>=14'} + detective-amd@6.0.1: + resolution: {integrity: sha512-TtyZ3OhwUoEEIhTFoc1C9IyJIud3y+xYkSRjmvCt65+ycQuc3VcBrPRTMWoO/AnuCyOB8T5gky+xf7Igxtjd3g==} + engines: {node: '>=18'} hasBin: true - detective-cjs@5.0.1: - resolution: {integrity: sha512-6nTvAZtpomyz/2pmEmGX1sXNjaqgMplhQkskq2MLrar0ZAIkHMrDhLXkRiK2mvbu9wSWr0V5/IfiTrZqAQMrmQ==} - engines: {node: '>=14'} + detective-cjs@6.0.1: + resolution: {integrity: sha512-tLTQsWvd2WMcmn/60T2inEJNhJoi7a//PQ7DwRKEj1yEeiQs4mrONgsUtEJKnZmrGWBBmE0kJ1vqOG/NAxwaJw==} + engines: {node: '>=18'} - detective-es6@4.0.1: - resolution: {integrity: sha512-k3Z5tB4LQ8UVHkuMrFOlvb3GgFWdJ9NqAa2YLUU/jTaWJIm+JJnEh4PsMc+6dfT223Y8ACKOaC0qcj7diIhBKw==} - engines: {node: '>=14'} + detective-es6@5.0.1: + resolution: {integrity: sha512-XusTPuewnSUdoxRSx8OOI6xIA/uld/wMQwYsouvFN2LAg7HgP06NF1lHRV3x6BZxyL2Kkoih4ewcq8hcbGtwew==} + engines: {node: '>=18'} - detective-postcss@6.1.3: - resolution: {integrity: sha512-7BRVvE5pPEvk2ukUWNQ+H2XOq43xENWbH0LcdCE14mwgTBEAMoAx+Fc1rdp76SmyZ4Sp48HlV7VedUnP6GA1Tw==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + detective-postcss@7.0.1: + resolution: {integrity: sha512-bEOVpHU9picRZux5XnwGsmCN4+8oZo7vSW0O0/Enq/TO5R2pIAP2279NsszpJR7ocnQt4WXU0+nnh/0JuK4KHQ==} + engines: {node: ^14.0.0 || >=16.0.0} + peerDependencies: + postcss: ^8.4.47 - detective-sass@5.0.3: - resolution: {integrity: sha512-YsYT2WuA8YIafp2RVF5CEfGhhyIVdPzlwQgxSjK+TUm3JoHP+Tcorbk3SfG0cNZ7D7+cYWa0ZBcvOaR0O8+LlA==} - engines: {node: '>=14'} + detective-sass@6.0.1: + resolution: {integrity: sha512-jSGPO8QDy7K7pztUmGC6aiHkexBQT4GIH+mBAL9ZyBmnUIOFbkfZnO8wPRRJFP/QP83irObgsZHCoDHZ173tRw==} + engines: {node: '>=18'} - detective-scss@4.0.3: - resolution: {integrity: sha512-VYI6cHcD0fLokwqqPFFtDQhhSnlFWvU614J42eY6G0s8c+MBhi9QAWycLwIOGxlmD8I/XvGSOUV1kIDhJ70ZPg==} - engines: {node: '>=14'} + detective-scss@5.0.1: + resolution: {integrity: sha512-MAyPYRgS6DCiS6n6AoSBJXLGVOydsr9huwXORUlJ37K3YLyiN0vYHpzs3AdJOgHobBfispokoqrEon9rbmKacg==} + engines: {node: '>=18'} - detective-stylus@4.0.0: - resolution: {integrity: sha512-TfPotjhszKLgFBzBhTOxNHDsutIxx9GTWjrL5Wh7Qx/ydxKhwUrlSFeLIn+ZaHPF+h0siVBkAQSuy6CADyTxgQ==} - engines: {node: '>=14'} + detective-stylus@5.0.1: + resolution: {integrity: sha512-Dgn0bUqdGbE3oZJ+WCKf8Dmu7VWLcmRJGc6RCzBgG31DLIyai9WAoEhYRgIHpt/BCRMrnXLbGWGPQuBUrnF0TA==} + engines: {node: '>=18'} - detective-typescript@11.2.0: - resolution: {integrity: sha512-ARFxjzizOhPqs1fYC/2NMC3N4jrQ6HvVflnXBTRqNEqJuXwyKLRr9CrJwkRcV/SnZt1sNXgsF6FPm0x57Tq0rw==} - engines: {node: ^14.14.0 || >=16.0.0} + detective-typescript@14.0.0: + resolution: {integrity: sha512-pgN43/80MmWVSEi5LUuiVvO/0a9ss5V7fwVfrJ4QzAQRd3cwqU1SfWGXJFcNKUqoD5cS+uIovhw5t/0rSeC5Mw==} + engines: {node: '>=18'} + peerDependencies: + typescript: ^5.4.4 + + detective-vue2@2.2.0: + resolution: {integrity: sha512-sVg/t6O2z1zna8a/UIV6xL5KUa2cMTQbdTIIvqNM0NIPswp52fe43Nwmbahzj3ww4D844u/vC2PYfiGLvD3zFA==} + engines: {node: '>=18'} + peerDependencies: + typescript: ^5.4.4 devalue@5.1.1: resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==} @@ -4876,8 +4072,8 @@ packages: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} - dom-helpers@5.2.1: - resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} dom-serializer@1.4.1: resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} @@ -4888,10 +4084,6 @@ packages: dom-walk@0.1.2: resolution: {integrity: sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==} - domain-browser@4.22.0: - resolution: {integrity: sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw==} - engines: {node: '>=10'} - domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} @@ -4913,18 +4105,18 @@ packages: resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==} engines: {node: '>=18'} - dotenv-expand@10.0.0: - resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} - engines: {node: '>=12'} - - dotenv@16.3.2: - resolution: {integrity: sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ==} + dotenv-expand@11.0.7: + resolution: {integrity: sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==} engines: {node: '>=12'} dotenv@16.4.7: resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} engines: {node: '>=12'} + dotenv@16.5.0: + resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} + engines: {node: '>=12'} + dotenv@8.6.0: resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} engines: {node: '>=10'} @@ -4947,9 +4139,6 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.118: - resolution: {integrity: sha512-yNDUus0iultYyVoEFLnQeei7LOQkL8wg8GQpkPCRrOlJXlcCwa6eGKZkxQ9ciHsqZyYbj8Jd94X1CTPzGm+uIA==} - electron-to-chromium@1.5.155: resolution: {integrity: sha512-ps5KcGGmwL8VaeJlvlDlu4fORQpv3+GIcF5I3f9tUKUlJ/wsysh6HU8P5L1XWRYeXfA0oJd4PyM8ds8zTFf6Ng==} @@ -4968,10 +4157,6 @@ packages: enabled@2.0.0: resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} - encodeurl@1.0.2: - resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} - engines: {node: '>= 0.8'} - encodeurl@2.0.0: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} @@ -4998,6 +4183,10 @@ packages: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} + entities@6.0.0: + resolution: {integrity: sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==} + engines: {node: '>=0.12'} + env-paths@3.0.0: resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -5005,9 +4194,6 @@ packages: error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - error-stack-parser-es@0.1.5: - resolution: {integrity: sha512-xHku1X40RO+fO8yJ8Wh2f2rZWVjqyhb1zgq1yZ8aZRQkv6OOKhKWRUaht3eSCUbAOBaKIgM+ykwFLE+QUxgGeg==} - error-stack-parser-es@1.0.5: resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} @@ -5030,9 +4216,6 @@ packages: resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} engines: {node: '>= 0.4'} - es-module-lexer@1.6.0: - resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} - es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} @@ -5052,21 +4235,28 @@ packages: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} + esbuild-plugin-polyfill-node@0.3.0: + resolution: {integrity: sha512-SHG6CKUfWfYyYXGpW143NEZtcVVn8S/WHcEOxk62LuDXnY4Zpmc+WmxJKN6GMTgTClXJXhEM5KQlxKY6YjbucQ==} + peerDependencies: + esbuild: '*' + + esbuild-plugin-preserve-directives@0.0.11: + resolution: {integrity: sha512-OolFhx1h/1ADEEoPjVi0hYWru1pTZBHki7XozawYVkhRhO63mwZT6isLylbwPs7dJ72doVQJGHCT2I1l9z8DcA==} + engines: {node: '>=18.0.0'} + peerDependencies: + esbuild: ^0.21.0 + + esbuild-plugins-node-modules-polyfill@1.7.0: + resolution: {integrity: sha512-Z81w5ReugIBAgufGeGWee+Uxzgs5Na4LprUAK3XlJEh2ktY3LkNuEGMaZyBXxQxGK8SQDS5yKLW5QKGF5qLjYA==} + engines: {node: '>=14.0.0'} + peerDependencies: + esbuild: '>=0.14.0 <=0.25.x' + esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} hasBin: true - esbuild@0.25.1: - resolution: {integrity: sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==} - engines: {node: '>=18'} - hasBin: true - - esbuild@0.25.2: - resolution: {integrity: sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==} - engines: {node: '>=18'} - hasBin: true - esbuild@0.25.4: resolution: {integrity: sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==} engines: {node: '>=18'} @@ -5126,11 +4316,14 @@ packages: peerDependencies: eslint: ^9.5.0 - eslint-config-prettier@10.1.1: - resolution: {integrity: sha512-4EQQr6wXwS+ZJSzaR5ZCrYgLxqvUjdXctaEtBqHcbkW944B1NQyO4qpdHQbXBONfwxXdkAY81HH4+LUfrg+zPw==} - hasBin: true + eslint-config-next@15.3.2: + resolution: {integrity: sha512-FerU4DYccO4FgeYFFglz0SnaKRe1ejXQrDb8kWUkTAg036YWi+jUsgg4sIGNCDhAsDITsZaL4MzBWKB6f4G1Dg==} peerDependencies: - eslint: '>=7.0.0' + eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 + typescript: '>=3.3.1' + peerDependenciesMeta: + typescript: + optional: true eslint-config-prettier@8.10.0: resolution: {integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==} @@ -5138,12 +4331,25 @@ packages: peerDependencies: eslint: '>=7.0.0' - eslint-flat-config-utils@2.0.1: - resolution: {integrity: sha512-brf0eAgQ6JlKj3bKfOTuuI7VcCZvi8ZCD1MMTVoEvS/d38j8cByZViLFALH/36+eqB17ukmfmKq3bWzGvizejA==} + eslint-flat-config-utils@2.1.0: + resolution: {integrity: sha512-6fjOJ9tS0k28ketkUcQ+kKptB4dBZY2VijMZ9rGn8Cwnn1SH0cZBoPXT8AHBFHxmHcLFQK9zbELDinZ2Mr1rng==} eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + eslint-import-resolver-typescript@3.10.1: + resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + eslint-merge-processors@2.0.0: resolution: {integrity: sha512-sUuhSf3IrJdGooquEUB5TNpGNpBoQccbnaLHsb1XkBLUPPqCNivCpY05ZcpCOiV9uHwO2yxXEWVczVclzMxYlA==} peerDependencies: @@ -5187,8 +4393,8 @@ packages: peerDependencies: eslint: '>=7.7.0' - eslint-plugin-import-x@4.10.5: - resolution: {integrity: sha512-cmteCl8P5q1lkuL/4qqQw1uvnQHytpv2fjHFZ2UIqSfkM0RwWm/KLgasXKIqDRjgMnmUJTeyP8+9hDpJJuiZgg==} + eslint-plugin-import-x@4.12.2: + resolution: {integrity: sha512-0jVUgJQipbs0yUfLe7LwYD6p8rIGqCysWZdyJFgkPzDyJgiKpuCaXlywKUAWgJ6u1nLpfrdt21B60OUkupyBrQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -5216,8 +4422,8 @@ packages: jest: optional: true - eslint-plugin-jsdoc@50.6.9: - resolution: {integrity: sha512-7/nHu3FWD4QRG8tCVqcv+BfFtctUtEDWc29oeDXB4bwmDM2/r1ndl14AG/2DUntdqH7qmpvdemJKwb3R97/QEw==} + eslint-plugin-jsdoc@50.6.17: + resolution: {integrity: sha512-hq+VQylhd12l8qjexyriDsejZhqiP33WgMTy2AmaGZ9+MrMWVqPECsM87GPxgHfQn0zw+YTuhqjUfk1f+q67aQ==} engines: {node: '>=18'} peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 @@ -5245,13 +4451,13 @@ packages: eslint-config-prettier: optional: true - eslint-plugin-prettier@5.2.3: - resolution: {integrity: sha512-qJ+y0FfCp/mQYQ/vWQ3s7eUlFEL4PyKfAJxsnYTJ4YT73nsJBWqmEpFryxV9OeUiqmsTsYJ5Y+KDNaeP31wrRw==} + eslint-plugin-prettier@5.4.0: + resolution: {integrity: sha512-BvQOvUhkVQM1i63iMETK9Hjud9QhqBnbtT1Zc642p9ynzBuCe5pybkOnvqZIBypXmMlsGcnU4HZ8sCTPfpAexA==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: '@types/eslint': '>=8.0.0' eslint: '>=8.0.0' - eslint-config-prettier: '*' + eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' prettier: '>=3.0.0' peerDependenciesMeta: '@types/eslint': @@ -5265,13 +4471,19 @@ packages: peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - eslint-plugin-react-refresh@0.4.19: - resolution: {integrity: sha512-eyy8pcr/YxSYjBoqIFSrlbn9i/xvxUFa8CjzAYo9cFjgGXqq1hyjihcpZvxRLalpaWmueWR81xn7vuKmAFijDQ==} + eslint-plugin-react-hooks@5.2.0: + resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react-refresh@0.4.20: + resolution: {integrity: sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==} peerDependencies: eslint: '>=8.40' - eslint-plugin-react@7.37.4: - resolution: {integrity: sha512-BGP0jRmfYyvOyvMoRX/uoUeW+GqNj9y16bPQzqAHf3AYII/tDs+jMN0dBVkl88/OZwNGwrVFxE7riHsXVfy/LQ==} + eslint-plugin-react@7.37.5: + resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} engines: {node: '>=4'} peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 @@ -5299,25 +4511,19 @@ packages: eslint: ^5 || ^6 || ^7 || ^8 typescript: ^3 || ^4 || ^5 - eslint-plugin-unicorn@58.0.0: - resolution: {integrity: sha512-fc3iaxCm9chBWOHPVjn+Czb/wHS0D2Mko7wkOdobqo9R2bbFObc4LyZaLTNy0mhZOP84nKkLhTUQxlLOZ7EjKw==} + eslint-plugin-unicorn@59.0.1: + resolution: {integrity: sha512-EtNXYuWPUmkgSU2E7Ttn57LbRREQesIP1BiLn7OZLKodopKfDXfBUkC/0j6mpw2JExwf43Uf3qLSvrSvppgy8Q==} engines: {node: ^18.20.0 || ^20.10.0 || >=21.0.0} peerDependencies: eslint: '>=9.22.0' - eslint-plugin-vue@10.0.0: - resolution: {integrity: sha512-XKckedtajqwmaX6u1VnECmZ6xJt+YvlmMzBPZd+/sI3ub2lpYZyFnsyWo7c3nMOQKJQudeyk1lw/JxdgeKT64w==} + eslint-plugin-vue@10.1.0: + resolution: {integrity: sha512-/VTiJ1eSfNLw6lvG9ENySbGmcVvz6wZ9nA7ZqXlLBY2RkaF15iViYKxglWiIch12KiLAj0j1iXPYU6W4wTROFA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 vue-eslint-parser: ^10.0.0 - eslint-plugin-vue@9.33.0: - resolution: {integrity: sha512-174lJKuNsuDIlLpjeXc5E2Tss8P44uIimAfGD0b90k0NoirJqpG7stLuU9Vp/9ioTOrQdWVREc4mRd1BD+CvGw==} - engines: {node: ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 - eslint-processor-vue-blocks@2.0.0: resolution: {integrity: sha512-u4W0CJwGoWY3bjXAuFpc/b6eK3NQEI8MoeW7ritKj3G3z/WtHrKjkqf+wk8mPEy5rlMGS+k6AZYOw2XBoN/02Q==} peerDependencies: @@ -5362,12 +4568,22 @@ packages: resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@8.57.1: - resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} + eslint@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true + eslint@9.28.0: + resolution: {integrity: sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + espree@10.3.0: resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -5425,25 +4641,14 @@ packages: evp_bytestokey@1.0.3: resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} - execa@7.2.0: - resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} - engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} - execa@8.0.1: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} - execa@9.5.2: - resolution: {integrity: sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q==} - engines: {node: ^18.19.0 || >=20.5.0} - - expect-type@1.2.0: - resolution: {integrity: sha512-80F22aiJ3GLyVnS/B3HzgR6RelZVumzj9jkL0Rhz4h0xYbNW9PjlQz5h3J/SShErbXBc295vseR4/MIbVmUbeA==} + expect-type@1.2.1: + resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} engines: {node: '>=12.0.0'} - exsolve@1.0.4: - resolution: {integrity: sha512-xsZH6PXaER4XoV+NiT7JHp1bJodJVT+cxeSH1G0f0tlT0lJqYuHUP3bUx2HtfTDvOagMINYp8rsqusxud3RXhw==} - exsolve@1.0.5: resolution: {integrity: sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==} @@ -5462,8 +4667,8 @@ packages: engines: {node: '>= 10.17.0'} hasBin: true - fake-indexeddb@6.0.0: - resolution: {integrity: sha512-YEboHE5VfopUclOck7LncgIqskAqnv4q0EWbYCaxKKjAvO93c+TJIaBuGy8CBFdbg9nKdpN3AuPRwVBJ4k7NrQ==} + fake-indexeddb@6.0.1: + resolution: {integrity: sha512-He2AjQGHe46svIFq5+L2Nx/eHDTI1oKgoevBP+TthnjymXiKkeJQ3+ITeWey99Y5+2OaPFbI1qEsx/5RsGtWnQ==} engines: {node: '>=18'} fast-deep-equal@3.1.3: @@ -5475,6 +4680,10 @@ packages: fast-fifo@1.3.2: resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} @@ -5485,8 +4694,8 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - fast-npm-meta@0.4.2: - resolution: {integrity: sha512-BDN/yv8MN3fjh504wa7/niZojPtf/brWBsLKlw7Fv+Xh8Df+6ZEAFpp3zaal4etgDxxav1CuzKX5H0YVM9urEQ==} + fast-npm-meta@0.4.3: + resolution: {integrity: sha512-eUzR/uVx61fqlHBjG/eQx5mQs7SQObehMTTdq8FAkdCB4KuZSQ6DiZMIrAq4kcibB3WFLQ9c4dT26Vwkix1RKg==} fast-sha256@1.3.0: resolution: {integrity: sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==} @@ -5504,14 +4713,6 @@ packages: fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} - fdir@6.4.3: - resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - fdir@6.4.4: resolution: {integrity: sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==} peerDependencies: @@ -5531,14 +4732,14 @@ packages: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} engines: {node: '>=8'} - figures@6.1.0: - resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} - engines: {node: '>=18'} - file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} @@ -5550,12 +4751,9 @@ packages: resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} engines: {node: '>=0.10.0'} - filter-obj@5.1.0: - resolution: {integrity: sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==} - engines: {node: '>=14.16'} - - find-root@1.1.0: - resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + filter-obj@6.1.0: + resolution: {integrity: sha512-xdMtCAODmPloU9qtmPcdBV9Kd27NtMse+4ayThxqIHUES5Z2S6bGpap5PpdmNM56ub7y3i1eyr+vJJIIgWGKmA==} + engines: {node: '>=18'} find-up-simple@1.0.1: resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} @@ -5569,10 +4767,6 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - find-up@6.3.0: - resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - find-up@7.0.0: resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==} engines: {node: '>=18'} @@ -5584,6 +4778,10 @@ packages: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + flat@5.0.2: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true @@ -5625,14 +4823,13 @@ packages: fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} - fresh@0.5.2: - resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} - engines: {node: '>= 0.6'} - fresh@2.0.0: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} + front-matter@4.0.2: + resolution: {integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==} + fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} @@ -5640,10 +4837,6 @@ packages: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} - fs-extra@11.3.0: - resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==} - engines: {node: '>=14.14'} - fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} @@ -5652,13 +4845,14 @@ packages: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} - fs-minipass@2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} - fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -5678,18 +4872,13 @@ packages: resolution: {integrity: sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==} engines: {node: '>=10'} - gauge@3.0.2: - resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} - engines: {node: '>=10'} - deprecated: This package is no longer supported. - gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} - get-amd-module-type@5.0.1: - resolution: {integrity: sha512-jb65zDeHyDjFR1loOVk0HQGM5WNwoGB8aLWy3LKCieMKol0/ProHkhO2X1JxojuN10vbz1qNn09MJ7tNp7qMzw==} - engines: {node: '>=14'} + get-amd-module-type@6.0.1: + resolution: {integrity: sha512-MtjsmYiCXcYDDrGqtNbeIYdAl85n+5mSv2r3FbzER/YV3ZILw4HNNIw34HuV5pyl0jzs6GFYU1VHVEefhgcNHQ==} + engines: {node: '>=18'} get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} @@ -5710,38 +4899,34 @@ packages: resolution: {integrity: sha512-lMyPjQyl0cNNdDf2oR+IQ/fM3itDvpoHy45Ymo2r0L1EjazeSl13SfbKZs7KtZ/3MDCeueiaJiuOEfKqRTsSgA==} engines: {node: 10 || 12 || >=14} + get-random-values@3.0.0: + resolution: {integrity: sha512-mNznaBdYcpz7UAdnOtDGcLdNwAa79mXl5htEyyZ51YaeAWNf2g4x/2yCVBdNNTbi35wX0Stc2PJXM7G6rcONOA==} + engines: {node: 18 || >=20} + get-stream@5.2.0: resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} engines: {node: '>=8'} - get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - get-stream@8.0.1: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} - get-stream@9.0.1: - resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} - engines: {node: '>=18'} - get-symbol-description@1.1.0: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} - get-tsconfig@4.10.0: - resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} + get-tsconfig@4.10.1: + resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} giget@2.0.0: resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} hasBin: true - git-up@8.1.0: - resolution: {integrity: sha512-cT2f5ERrhFDMPS5wLHURcjRiacC8HonX0zIAWBTwHv1fS6HheP902l6pefOX/H9lNmvCHDwomw0VeN7nhg5bxg==} + git-up@8.1.1: + resolution: {integrity: sha512-FDenSF3fVqBYSaJoYy1KSc2wosx0gCvKP+c+PRBht7cAaiCeQlBtfBDX9vgnNOHmdePlSFITVcn4pFfcgNvx3g==} - git-url-parse@16.0.1: - resolution: {integrity: sha512-mcD36GrhAzX5JVOsIO52qNpgRyFzYWRbU1VSRFCvJt1IJvqfvH427wWw/CFqkWvjVPtdG5VTx4MKUeC5GeFPDQ==} + git-url-parse@16.1.0: + resolution: {integrity: sha512-cPLz4HuK86wClEW7iDdeAKcCVlWXmrLpb2L+G9goW0Z1dtpNS6BXXSOckUTlJT/LDQViE1QZKstNORzHsLnobw==} glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} @@ -5755,6 +4940,11 @@ packages: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true + glob@11.0.2: + resolution: {integrity: sha512-YT7U7Vye+t5fZ/QMkBFrTJ7ZQxInIUjwyAjVj84CYXqgBdv30MFUPGnBR6sQaVq6Is15wYJUsnzTuWaGRBhBAQ==} + engines: {node: 20 || >=22} + hasBin: true + glob@7.1.7: resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} deprecated: Glob versions prior to v9 are no longer supported @@ -5791,8 +4981,12 @@ packages: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} - globals@16.0.0: - resolution: {integrity: sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==} + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@16.1.0: + resolution: {integrity: sha512-aibexHNbb/jiUSObBgpHLj+sIuUmJnYcgXBlrfsiDZ9rt4aF2TFRbyLgZ2iFQuVZ1K5Mx3FVkbKRSgKrbK3K2g==} engines: {node: '>=18'} globalthis@1.0.4: @@ -5829,9 +5023,6 @@ packages: resolution: {integrity: sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - h3@1.15.1: - resolution: {integrity: sha512-+ORaOBttdUm1E2Uu/obAyCguiI7MbBvsLTndc3gyK3zU+SYLoZXlyCP9Xgy0gikkGufFLTZXCXD6+4BsufnmHA==} - h3@1.15.3: resolution: {integrity: sha512-z6GknHqyX0h9aQaTx22VZDf6QyZn+0Nh+Ym8O/u0SGSkyF5cuTJYKlc8MkzW3Nzf9LE1ivcpmYC3FUGpywhuUQ==} @@ -5862,9 +5053,6 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} - has-unicode@2.0.1: - resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} - hash-base@3.0.5: resolution: {integrity: sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==} engines: {node: '>= 0.10'} @@ -5889,9 +5077,6 @@ packages: hmac-drbg@1.0.1: resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} - hoist-non-react-statics@3.3.2: - resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} - hookable@5.5.3: resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} @@ -5932,13 +5117,6 @@ packages: resolution: {integrity: sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - https-browserify@1.0.0: - resolution: {integrity: sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==} - - https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} - https-proxy-agent@7.0.6: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} @@ -5950,18 +5128,10 @@ packages: resolution: {integrity: sha512-3gKm/gCSUipeLsRYZbbdA1BD83lBoWUkZ7G9VFrhWPAU76KwYo5KR8V28bpoPm/ygy0x5/GCbpRQdY7VLYCoIg==} hasBin: true - human-signals@4.3.1: - resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} - engines: {node: '>=14.18.0'} - human-signals@5.0.0: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} - human-signals@8.0.0: - resolution: {integrity: sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==} - engines: {node: '>=18.18.0'} - iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -5983,10 +5153,6 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - ignore@7.0.3: - resolution: {integrity: sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==} - engines: {node: '>= 4'} - ignore@7.0.4: resolution: {integrity: sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==} engines: {node: '>= 4'} @@ -5994,8 +5160,8 @@ packages: image-meta@0.2.1: resolution: {integrity: sha512-K6acvFaelNxx8wc2VjbIzXKDVB0Khs0QT35U6NkGfTdCmjLNcO2945m7RFNR9/RPVFm48hq7QPzK8uGH18HCGw==} - immutable@5.0.3: - resolution: {integrity: sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==} + immutable@5.1.2: + resolution: {integrity: sha512-qHKXW1q6liAk1Oys6umoaZbDRqjcjgSrbnrifHsfsttza7zcvRAsL7mMV6xWcyhwQy7Xj5v4hhbr6b+iDYwlmQ==} import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} @@ -6005,8 +5171,8 @@ packages: resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} engines: {node: '>=8'} - impound@0.2.2: - resolution: {integrity: sha512-9CNg+Ly8QjH4FwCUoE9nl1zeqY1NPK1s1P6Btp4L8lJxn8oZLN/0p6RZhitnyEL0BnVWrcVPfbs0Q3x+O/ucHg==} + import-meta-resolve@3.1.1: + resolution: {integrity: sha512-qeywsE/KC3w9Fd2ORrRDUw6nS/nLwZpXgfrOc2IILvZYnCaEMd+D56Vfg9k4G29gIeVi3XKql1RQatME8iYsiw==} impound@1.0.0: resolution: {integrity: sha512-8lAJ+1Arw2sMaZ9HE2ZmL5zOcMnt18s6+7Xqgq2aUVy4P1nlzAyPtzCDxsk51KVFwHEEdc6OWvUyqwHwhRYaug==} @@ -6045,10 +5211,6 @@ packages: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} - ioredis@5.6.0: - resolution: {integrity: sha512-tBZlIIWbndeWBWCXWZiqtOF/yxf6yZX3tAlTJ7nfo5jhd6dctNxF7QnYlZLZ1a0o0pDoen7CgZqO+zjNaFbJAg==} - engines: {node: '>=12.22.0'} - ioredis@5.6.1: resolution: {integrity: sha512-UxC0Yv1Y4WRJiGQxQkP0hfdL0/5/6YvdfOOClRgJ0qppSarkhneSa6UvkMkms0AkdGimSH3Ikqm+6mkMmX7vGA==} engines: {node: '>=12.22.0'} @@ -6056,10 +5218,6 @@ packages: iron-webcrypto@1.2.1: resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} - is-arguments@1.2.0: - resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} - engines: {node: '>= 0.4'} - is-array-buffer@3.0.5: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} @@ -6090,6 +5248,9 @@ packages: resolution: {integrity: sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==} engines: {node: '>=18.20'} + is-bun-module@2.0.0: + resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} + is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} @@ -6156,10 +5317,6 @@ packages: is-module@1.0.0: resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} - is-nan@1.3.2: - resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} - engines: {node: '>= 0.4'} - is-number-object@1.1.1: resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} engines: {node: '>= 0.4'} @@ -6184,10 +5341,6 @@ packages: resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} engines: {node: '>=8'} - is-plain-obj@4.1.0: - resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} - engines: {node: '>=12'} - is-plain-object@5.0.0: resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} engines: {node: '>=0.10.0'} @@ -6245,10 +5398,6 @@ packages: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} - is-unicode-supported@2.1.0: - resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} - engines: {node: '>=18'} - is-url-superb@4.0.0: resolution: {integrity: sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA==} engines: {node: '>=10'} @@ -6301,10 +5450,6 @@ packages: resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} engines: {node: '>=16'} - isomorphic-timers-promises@1.0.1: - resolution: {integrity: sha512-u4sej9B1LPSxTGKB/HiuzvEQnXH0ECYkSVQU39koSwmFAxhlEAFl9RdTvLv4TOTQUgBS5O3O5fwUxk6byBZ+IQ==} - engines: {node: '>=10'} - istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} @@ -6328,6 +5473,10 @@ packages: jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jackspeak@4.1.1: + resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} + engines: {node: 20 || >=22} + jest-diff@29.7.0: resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -6353,6 +5502,9 @@ packages: jose@5.10.0: resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} + jose@6.0.11: + resolution: {integrity: sha512-QxG7EaliDARm1O1S8BGakqncGT9s25bKL1WSf6/oa17Tkqwi8D2ZNglqCF+DsYF88/rV66Q/Q2mFAy697E1DUg==} + js-beautify@1.15.4: resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==} engines: {node: '>=14'} @@ -6380,8 +5532,8 @@ packages: resolution: {integrity: sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==} engines: {node: '>=12.0.0'} - jsdom@26.0.0: - resolution: {integrity: sha512-BZYDGVAIriBWTpIxYzrXjv3E/4u8+/pSG5bQdIYCbNCGOvsPkDQfTVLAIXAf9ETdCpduCVTkDe2NNZ8NIwUVzw==} + jsdom@26.1.0: + resolution: {integrity: sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==} engines: {node: '>=18'} peerDependencies: canvas: ^3.0.0 @@ -6405,10 +5557,6 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - json-parse-even-better-errors@4.0.0: - resolution: {integrity: sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==} - engines: {node: ^18.17.0 || >=20.5.0} - json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -6476,9 +5624,6 @@ packages: known-css-properties@0.26.0: resolution: {integrity: sha512-5FZRzrZzNTBruuurWpvZnvP9pum+fe0HcK8z/ooo+U+Hmp4vtbyp1/QDsqmufirXy4egGzbaH/y2uCZf+6W5Kg==} - kolorist@1.8.0: - resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} - kuler@2.0.0: resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} @@ -6516,8 +5661,8 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - lines-and-columns@2.0.4: - resolution: {integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==} + lines-and-columns@2.0.3: + resolution: {integrity: sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} listhen@1.9.0: @@ -6549,21 +5694,12 @@ packages: lodash.defaults@4.2.0: resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} - lodash.difference@4.5.0: - resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} - - lodash.flatten@4.4.0: - resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} - lodash.isarguments@3.1.0: resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} lodash.isempty@4.4.0: resolution: {integrity: sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==} - lodash.isplainobject@4.0.6: - resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} - lodash.memoize@4.1.2: resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} @@ -6576,9 +5712,6 @@ packages: lodash.truncate@4.4.2: resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} - lodash.union@4.6.0: - resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} - lodash.uniq@4.5.0: resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} @@ -6603,6 +5736,10 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@11.1.0: + resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -6614,6 +5751,10 @@ packages: resolution: {integrity: sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ==} engines: {node: '>=12'} + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + magic-regexp@0.8.0: resolution: {integrity: sha512-lOSLWdE156csDYwCTIGiAymOLN7Epu/TU5e/oAnISZfU6qP+pgjkE+xbVjVn3yLPKN8n1G2yIAYTAM5KRk6/ow==} @@ -6627,10 +5768,6 @@ packages: magicast@0.3.5: resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} - make-dir@3.1.0: - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} - engines: {node: '>=8'} - make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} @@ -6671,10 +5808,6 @@ packages: memory-cache@0.2.0: resolution: {integrity: sha512-OcjA+jzjOYzKmKS6IQVALHLVz+rNTMPoJvCztFaZxwG14wtAW7VRZjwTQu06vKCYOxh4jVnik7ya0SXTB0W+xA==} - memorystream@0.3.1: - resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} - engines: {node: '>= 0.10.0'} - meow@9.0.0: resolution: {integrity: sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==} engines: {node: '>=10'} @@ -6732,11 +5865,6 @@ packages: resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} engines: {node: '>= 0.6'} - mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} - hasBin: true - mime@3.0.0: resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} engines: {node: '>=10.0.0'} @@ -6772,6 +5900,10 @@ packages: minimalistic-crypto-utils@1.0.1: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + minimatch@10.0.1: + resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + engines: {node: 20 || >=22} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -6798,14 +5930,6 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@3.3.6: - resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} - engines: {node: '>=8'} - - minipass@5.0.0: - resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} - engines: {node: '>=8'} - minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} @@ -6813,10 +5937,6 @@ packages: minisearch@7.1.2: resolution: {integrity: sha512-R1Pd9eF+MD5JYDDSPAp/q1ougKglm14uEkPMvQ/05RGmx6G9wvmLTrTI/Q5iPNJLYqNdsDQ7qTGIcNWR+FrHmA==} - minizlib@2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} - minizlib@3.0.2: resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==} engines: {node: '>= 18'} @@ -6824,11 +5944,6 @@ packages: mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} - mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - mkdirp@3.0.1: resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} engines: {node: '>=10'} @@ -6861,9 +5976,9 @@ packages: mocked-exports@0.1.1: resolution: {integrity: sha512-aF7yRQr/Q0O2/4pIXm6PZ5G+jAd7QS4Yu8m+WEeEHGnbo+7mE36CbLSDQiXYV8bVL3NfmdeqPJct0tUlnjVSnA==} - module-definition@5.0.1: - resolution: {integrity: sha512-kvw3B4G19IXk+BOXnYq/D/VeO9qfHaapMeuS7w7sNUqmGaA6hywdFHMi+VWeR9wUScXM7XjoryTffCZ5B0/8IA==} - engines: {node: '>=14'} + module-definition@6.0.1: + resolution: {integrity: sha512-FeVc50FTfVVQnolk/WQT8MX+2WVcDnTGiq6Wo+/+lJ2ET1bRVi3HG3YlJUfqagNMc/kUlFSoR96AJkxGpKz13g==} + engines: {node: '>=18'} hasBin: true mri@1.2.0: @@ -6874,53 +5989,63 @@ packages: resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} engines: {node: '>=10'} - ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} muggle-string@0.4.1: resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} - nanoid@3.3.9: - resolution: {integrity: sha512-SppoicMGpZvbF1l3z4x7No3OlIjP7QJvC9XR7AhZr1kL133KHnKPztkKDc+Ir4aJ/1VhTySrtKhrsycmrMQfvg==} + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - nanoid@5.1.3: - resolution: {integrity: sha512-zAbEOEr7u2CbxwoMRlz/pNSpRP0FdAU4pRaYunCdEezWohXFs+a0Xw7RfkKaezMsmSM1vttcLthJtwRnVtOfHQ==} + nanoid@5.1.5: + resolution: {integrity: sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==} engines: {node: ^18 || >=20} hasBin: true nanotar@0.2.0: resolution: {integrity: sha512-9ca1h0Xjvo9bEkE4UOxgAzLV0jHKe6LMaxo37ND2DAhhAtd0j8pR1Wxz+/goMrZO8AEZTWCmyaOsFI/W5AdpCQ==} + napi-postinstall@0.2.4: + resolution: {integrity: sha512-ZEzHJwBhZ8qQSbknHqYcdtQVr8zUgGyM/q6h6qAyhtyVMNrSgDhrC4disf03dYW0e+czXyLnZINnCTEkWy0eJg==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - nested-error-stacks@2.1.1: - resolution: {integrity: sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==} - netlify@13.3.5: resolution: {integrity: sha512-Nc3loyVASW59W+8fLDZT1lncpG7llffyZ2o0UQLx/Fr20i7P8oP+lE7+TEcFvXj9IUWU6LjB9P3BH+iFGyp+mg==} engines: {node: ^14.16.0 || >=16.0.0} - nitropack@2.11.12: - resolution: {integrity: sha512-e2AdQrEY1IVoNTdyjfEQV93xkqz4SQxAMR0xWF8mZUUHxMLm6S4nPzpscjksmT4OdUxl0N8/DCaGjKQ9ghdodA==} - engines: {node: ^16.11.0 || >=17.0.0} + next@15.3.2: + resolution: {integrity: sha512-CA3BatMyHkxZ48sgOCLdVHjFU36N7TF1HhqAHLFOkV6buwZnvMI84Cug8xD56B9mCuKrqXnLn94417GrZ/jjCQ==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} hasBin: true peerDependencies: - xml2js: ^0.6.2 + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 peerDependenciesMeta: - xml2js: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: optional: true - nitropack@2.11.8: - resolution: {integrity: sha512-ummTu4R8Lhd1nO3nWrW7eeiHA2ey3ntbWFKkYakm4rcbvT6meWp+oykyrYBNFQKhobQl9CydmUWlCyztYXFPJw==} + nitropack@2.11.12: + resolution: {integrity: sha512-e2AdQrEY1IVoNTdyjfEQV93xkqz4SQxAMR0xWF8mZUUHxMLm6S4nPzpscjksmT4OdUxl0N8/DCaGjKQ9ghdodA==} engines: {node: ^16.11.0 || >=17.0.0} hasBin: true peerDependencies: @@ -6970,18 +6095,9 @@ packages: node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} - node-source-walk@6.0.2: - resolution: {integrity: sha512-jn9vOIK/nfqoFCcpK89/VCVaLg1IHE6UVfDOzvqmANaJ/rWCTEdH8RZ1V278nv2jr36BJdyQXIAavBLXpzdlag==} - engines: {node: '>=14'} - - node-stdlib-browser@1.3.1: - resolution: {integrity: sha512-X75ZN8DCLftGM5iKwoYLA3rjnrAEs97MkzvSd4q2746Tgpg8b8XWiBGiBG4ZpgcAqBgtgPHTiAc8ZMCvZuikDw==} - engines: {node: '>=10'} - - nopt@5.0.0: - resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} - engines: {node: '>=6'} - hasBin: true + node-source-walk@7.0.1: + resolution: {integrity: sha512-3VW/8JpPqPvnJvseXowjZcirPisssnBuDikk6JIZ8jQzF7KJQX52iPFX4RYYxLycYH7IbMRSPUOga/esVjy5Yg==} + engines: {node: '>=18'} nopt@7.2.1: resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} @@ -7020,15 +6136,6 @@ packages: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} engines: {node: '>=10'} - npm-normalize-package-bin@4.0.0: - resolution: {integrity: sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==} - engines: {node: ^18.17.0 || >=20.5.0} - - npm-run-all2@7.0.2: - resolution: {integrity: sha512-7tXR+r9hzRNOPNTvXegM+QzCuMjzUIIq66VDunL6j60O4RrExx32XUhlrS7UK4VcdGw5/Wxzb3kfNcFix9JKDA==} - engines: {node: ^18.17.0 || >=20.5.0, npm: '>= 9'} - hasBin: true - npm-run-path@4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} @@ -7041,15 +6148,11 @@ packages: resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} engines: {node: '>=18'} - npmlog@5.0.1: - resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} - deprecated: This package is no longer supported. - nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - nuxt@3.16.2: - resolution: {integrity: sha512-yjIC/C4HW8Pd+m0ACGliEF0HnimXYGYvUzjOsTiLQKkDDt2T+djyZ+pCl9BfhQBA8rYmnsym2jUI+ubjv1iClw==} + nuxt@3.17.4: + resolution: {integrity: sha512-49tkp7/+QVhuEOFoTDVvNV6Pc5+aI7wWjZHXzLUrt3tlWLPFh0yYbNXOc3kaxir1FuhRQHHyHZ7azCPmGukfFg==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0.0} hasBin: true peerDependencies: @@ -7061,24 +6164,11 @@ packages: '@types/node': optional: true - nuxt@3.17.3: - resolution: {integrity: sha512-iaRGGcnOiahdz+rhEiDY+Ep/vgsvcCCSs2tIVwKmteHEZk6O2zcpk/U1rHxPWortTyMlluHHaohC2WngYceh+g==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0.0} - hasBin: true - peerDependencies: - '@parcel/watcher': ^2.1.0 - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - peerDependenciesMeta: - '@parcel/watcher': - optional: true - '@types/node': - optional: true - - nwsapi@2.2.18: - resolution: {integrity: sha512-p1TRH/edngVEHVbwqWnxUViEmq5znDvyB+Sik5cmuLpGOIfDf/39zLiq3swPF8Vakqn+gvNiOQAZu8djYlQILA==} + nwsapi@2.2.20: + resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==} - nx@18.2.4: - resolution: {integrity: sha512-GxqJcDOhfLa9jsPmip0jG73CZKA96wCryss2DhixCiCU66I3GLYF4+585ObO8Tx7Z1GqhT92RaNGjCxjMIwaPg==} + nx@20.8.1: + resolution: {integrity: sha512-73Uw8YXpsjeLqHSl7NMCmGdCs+8ynPzoNJFWAqVanPETEY9zPd5wevVQmeyzYtNNQU35uj6Os4iUzYunmwnFaA==} hasBin: true peerDependencies: '@swc-node/register': ^1.8.0 @@ -7102,10 +6192,6 @@ packages: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} - object-is@1.1.6: - resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} - engines: {node: '>= 0.4'} - object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} @@ -7161,8 +6247,8 @@ packages: oniguruma-to-es@3.1.1: resolution: {integrity: sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==} - open@10.1.0: - resolution: {integrity: sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==} + open@10.1.2: + resolution: {integrity: sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==} engines: {node: '>=18'} open@8.4.2: @@ -7177,9 +6263,6 @@ packages: resolution: {integrity: sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==} engines: {node: '>=10'} - os-browserify@0.3.0: - resolution: {integrity: sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==} - os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} @@ -7191,17 +6274,13 @@ packages: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} - oxc-parser@0.56.5: - resolution: {integrity: sha512-MNT32sqiTFeSbQZP2WZIRQ/mlIpNNq4sua+/4hBG4qT5aef2iQe+1/BjezZURPlvucZeSfN1Y6b60l7OgBdyUA==} - engines: {node: '>=14.0.0'} - - oxc-parser@0.69.0: - resolution: {integrity: sha512-6UYcFCyCIoZ2t7gyYdPHxM0BTIjM7Y5MCCTfZ2obVITcLd0lXdkbjVibMBD/qVVG+7cURF7Lw32uykU0YR3QUg==} + oxc-parser@0.71.0: + resolution: {integrity: sha512-RXmu7qi+67RJ8E5UhKZJdliTI+AqD3gncsJecjujcYvjsCZV9KNIfu42fQAnAfLaYZuzOMRdUYh7LzV3F1C0Gw==} engines: {node: '>=14.0.0'} - p-event@5.0.1: - resolution: {integrity: sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-event@6.0.1: + resolution: {integrity: sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==} + engines: {node: '>=16.17'} p-filter@2.1.0: resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} @@ -7251,10 +6330,6 @@ packages: resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} engines: {node: '>=8'} - p-timeout@5.1.0: - resolution: {integrity: sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==} - engines: {node: '>=12'} - p-timeout@6.1.4: resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} engines: {node: '>=14.16'} @@ -7273,11 +6348,8 @@ packages: package-manager-detector@0.2.11: resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} - package-manager-detector@1.1.0: - resolution: {integrity: sha512-Y8f9qUlBzW8qauJjd/eu6jlpJZsuPJm2ZAV0cDVd420o4EdpH5RPdoCv+60/TdJflGatr4sDfpAL6ArWZbM5tA==} - - pako@1.0.11: - resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + package-manager-detector@1.3.0: + resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==} parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} @@ -7291,9 +6363,8 @@ packages: resolution: {integrity: sha512-RmVuCHWsfu0QPNW+mraxh/xjQVw/lhUCUru8Zni3Ctq3AoMhpDTq0OVdKS6iesd6Kqb7viCV3isAL43dciOSog==} engines: {node: '>=14'} - parse-imports@2.2.1: - resolution: {integrity: sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==} - engines: {node: '>= 18'} + parse-imports-exports@0.2.4: + resolution: {integrity: sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==} parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} @@ -7303,19 +6374,18 @@ packages: resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==} engines: {node: '>=18'} - parse-ms@4.0.0: - resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} - engines: {node: '>=18'} + parse-path@7.1.0: + resolution: {integrity: sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==} - parse-path@7.0.1: - resolution: {integrity: sha512-6ReLMptznuuOEzLoGEa+I1oWRSj2Zna5jLWC+l6zlfAI4dbbSaIES29ThzuPkbhNahT65dWzfoZEO6cfJw2Ksg==} + parse-statements@1.0.11: + resolution: {integrity: sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==} parse-url@9.2.0: resolution: {integrity: sha512-bCgsFI+GeGWPAvAiUv63ZorMeif3/U0zaXABGJbOWt5OH2KCaPHF6S+0ok4aqM9RuIPGyZdx9tR9l13PsW4AYQ==} engines: {node: '>=14.13.0'} - parse5@7.2.1: - resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==} + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} @@ -7351,6 +6421,10 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + path-scurry@2.0.0: + resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} + engines: {node: 20 || >=22} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -7390,25 +6464,26 @@ packages: resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} - pidtree@0.6.0: - resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} - engines: {node: '>=0.10'} - hasBin: true - pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} - pkg-dir@5.0.0: - resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} - engines: {node: '>=10'} - pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} pkg-types@2.1.0: resolution: {integrity: sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==} + playwright-core@1.52.0: + resolution: {integrity: sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.52.0: + resolution: {integrity: sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==} + engines: {node: '>=18'} + hasBin: true + pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} @@ -7434,12 +6509,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-colormin@7.0.2: - resolution: {integrity: sha512-YntRXNngcvEvDbEjTdRWGU606eZvB5prmHG4BF0yLmVpamXbpsRJzevyy6MZVyuecgzI2AWAlvFi8DAeCqwpvA==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-colormin@7.0.3: resolution: {integrity: sha512-xZxQcSyIVZbSsl1vjoqZAcMYYdnJsIyG8OvqShuuqf12S88qQboxxEy0ohNCOLwVPXTU+hFHvJPACRL2B5ohTA==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7452,12 +6521,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-convert-values@7.0.4: - resolution: {integrity: sha512-e2LSXPqEHVW6aoGbjV9RsSSNDO3A0rZLCBxN24zvxF25WknMPpX8Dm9UxxThyEbaytzggRuZxaGXqaOhxQ514Q==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-convert-values@7.0.5: resolution: {integrity: sha512-0VFhH8nElpIs3uXKnVtotDJJNX0OGYSZmdt4XfSfvOMrFw1jKfpwpZxfC4iN73CTM/MWakDEmsHQXkISYj4BXw==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7470,12 +6533,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-discard-comments@7.0.3: - resolution: {integrity: sha512-q6fjd4WU4afNhWOA2WltHgCbkRhZPgQe7cXF74fuVB/ge4QbM9HEaOIzGSiMvM+g/cOsNAUGdf2JDzqA2F8iLA==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-discard-comments@7.0.4: resolution: {integrity: sha512-6tCUoql/ipWwKtVP/xYiFf1U9QgJ0PUvxN7pTcsQ8Ns3Fnwq1pU5D5s1MhT/XySeLq6GXNvn37U46Ded0TckWg==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7488,12 +6545,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-discard-duplicates@7.0.1: - resolution: {integrity: sha512-oZA+v8Jkpu1ct/xbbrntHRsfLGuzoP+cpt0nJe5ED2FQF8n8bJtn7Bo28jSmBYwqgqnqkuSXJfSUEE7if4nClQ==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-discard-duplicates@7.0.2: resolution: {integrity: sha512-eTonaQvPZ/3i1ASDHOKkYwAybiM45zFIc7KXils4mQmHLqIswXD9XNOKEVxtTFnsmwYzF66u4LMgSr0abDlh5w==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7506,12 +6557,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-discard-empty@7.0.0: - resolution: {integrity: sha512-e+QzoReTZ8IAwhnSdp/++7gBZ/F+nBq9y6PomfwORfP7q9nBpK5AMP64kOt0bA+lShBFbBDcgpJ3X4etHg4lzA==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-discard-empty@7.0.1: resolution: {integrity: sha512-cFrJKZvcg/uxB6Ijr4l6qmn3pXQBna9zyrPC+sK0zjbkDUZew+6xDltSF7OeB7rAtzaaMVYSdbod+sZOCWnMOg==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7524,12 +6569,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-discard-overridden@7.0.0: - resolution: {integrity: sha512-GmNAzx88u3k2+sBTZrJSDauR0ccpE24omTQCVmaTTZFz1du6AasspjaUPMJ2ud4RslZpoFKyf+6MSPETLojc6w==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-discard-overridden@7.0.1: resolution: {integrity: sha512-7c3MMjjSZ/qYrx3uc1940GSOzN1Iqjtlqe8uoSg+qdVPYyRb0TILSqqmtlSFuE4mTDECwsm397Ya7iXGzfF7lg==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7545,12 +6584,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-merge-longhand@7.0.4: - resolution: {integrity: sha512-zer1KoZA54Q8RVHKOY5vMke0cCdNxMP3KBfDerjH/BYHh4nCIh+1Yy0t1pAEQF18ac/4z3OFclO+ZVH8azjR4A==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-merge-longhand@7.0.5: resolution: {integrity: sha512-Kpu5v4Ys6QI59FxmxtNB/iHUVDn9Y9sYw66D6+SZoIk4QTz1prC4aYkhIESu+ieG1iylod1f8MILMs1Em3mmIw==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7563,12 +6596,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-merge-rules@7.0.4: - resolution: {integrity: sha512-ZsaamiMVu7uBYsIdGtKJ64PkcQt6Pcpep/uO90EpLS3dxJi6OXamIobTYcImyXGoW0Wpugh7DSD3XzxZS9JCPg==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-merge-rules@7.0.5: resolution: {integrity: sha512-ZonhuSwEaWA3+xYbOdJoEReKIBs5eDiBVLAGpYZpNFPzXZcEE5VKR7/qBEQvTZpiwjqhhqEQ+ax5O3VShBj9Wg==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7581,12 +6608,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-minify-font-values@7.0.0: - resolution: {integrity: sha512-2ckkZtgT0zG8SMc5aoNwtm5234eUx1GGFJKf2b1bSp8UflqaeFzR50lid4PfqVI9NtGqJ2J4Y7fwvnP/u1cQog==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-minify-font-values@7.0.1: resolution: {integrity: sha512-2m1uiuJeTplll+tq4ENOQSzB8LRnSUChBv7oSyFLsJRtUgAAJGP6LLz0/8lkinTgxrmJSPOEhgY1bMXOQ4ZXhQ==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7599,12 +6620,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-minify-gradients@7.0.0: - resolution: {integrity: sha512-pdUIIdj/C93ryCHew0UgBnL2DtUS3hfFa5XtERrs4x+hmpMYGhbzo6l/Ir5de41O0GaKVpK1ZbDNXSY6GkXvtg==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-minify-gradients@7.0.1: resolution: {integrity: sha512-X9JjaysZJwlqNkJbUDgOclyG3jZEpAMOfof6PUZjPnPrePnPG62pS17CjdM32uT1Uq1jFvNSff9l7kNbmMSL2A==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7617,12 +6632,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-minify-params@7.0.2: - resolution: {integrity: sha512-nyqVLu4MFl9df32zTsdcLqCFfE/z2+f8GE1KHPxWOAmegSo6lpV2GNy5XQvrzwbLmiU7d+fYay4cwto1oNdAaQ==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-minify-params@7.0.3: resolution: {integrity: sha512-vUKV2+f5mtjewYieanLX0xemxIp1t0W0H/D11u+kQV/MWdygOO7xPMkbK+r9P6Lhms8MgzKARF/g5OPXhb8tgg==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7635,12 +6644,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-minify-selectors@7.0.4: - resolution: {integrity: sha512-JG55VADcNb4xFCf75hXkzc1rNeURhlo7ugf6JjiiKRfMsKlDzN9CXHZDyiG6x/zGchpjQS+UAgb1d4nqXqOpmA==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-minify-selectors@7.0.5: resolution: {integrity: sha512-x2/IvofHcdIrAm9Q+p06ZD1h6FPcQ32WtCRVodJLDR+WMn8EVHI1kvLxZuGKz/9EY5nAmI6lIQIrpo4tBy5+ug==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7683,12 +6686,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-normalize-charset@7.0.0: - resolution: {integrity: sha512-ABisNUXMeZeDNzCQxPxBCkXexvBrUHV+p7/BXOY+ulxkcjUZO0cp8ekGBwvIh2LbCwnWbyMPNJVtBSdyhM2zYQ==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-normalize-charset@7.0.1: resolution: {integrity: sha512-sn413ofhSQHlZFae//m9FTOfkmiZ+YQXsbosqOWRiVQncU2BA3daX3n0VF3cG6rGLSFVc5Di/yns0dFfh8NFgQ==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7701,12 +6698,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-normalize-display-values@7.0.0: - resolution: {integrity: sha512-lnFZzNPeDf5uGMPYgGOw7v0BfB45+irSRz9gHQStdkkhiM0gTfvWkWB5BMxpn0OqgOQuZG/mRlZyJxp0EImr2Q==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-normalize-display-values@7.0.1: resolution: {integrity: sha512-E5nnB26XjSYz/mGITm6JgiDpAbVuAkzXwLzRZtts19jHDUBFxZ0BkXAehy0uimrOjYJbocby4FVswA/5noOxrQ==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7719,12 +6710,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-normalize-positions@7.0.0: - resolution: {integrity: sha512-I0yt8wX529UKIGs2y/9Ybs2CelSvItfmvg/DBIjTnoUSrPxSV7Z0yZ8ShSVtKNaV/wAY+m7bgtyVQLhB00A1NQ==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-normalize-positions@7.0.1: resolution: {integrity: sha512-pB/SzrIP2l50ZIYu+yQZyMNmnAcwyYb9R1fVWPRxm4zcUFCY2ign7rcntGFuMXDdd9L2pPNUgoODDk91PzRZuQ==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7737,12 +6722,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-normalize-repeat-style@7.0.0: - resolution: {integrity: sha512-o3uSGYH+2q30ieM3ppu9GTjSXIzOrRdCUn8UOMGNw7Af61bmurHTWI87hRybrP6xDHvOe5WlAj3XzN6vEO8jLw==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-normalize-repeat-style@7.0.1: resolution: {integrity: sha512-NsSQJ8zj8TIDiF0ig44Byo3Jk9e4gNt9x2VIlJudnQQ5DhWAHJPF4Tr1ITwyHio2BUi/I6Iv0HRO7beHYOloYQ==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7755,12 +6734,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-normalize-string@7.0.0: - resolution: {integrity: sha512-w/qzL212DFVOpMy3UGyxrND+Kb0fvCiBBujiaONIihq7VvtC7bswjWgKQU/w4VcRyDD8gpfqUiBQ4DUOwEJ6Qg==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-normalize-string@7.0.1: resolution: {integrity: sha512-QByrI7hAhsoze992kpbMlJSbZ8FuCEc1OT9EFbZ6HldXNpsdpZr+YXC5di3UEv0+jeZlHbZcoCADgb7a+lPmmQ==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7773,12 +6746,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-normalize-timing-functions@7.0.0: - resolution: {integrity: sha512-tNgw3YV0LYoRwg43N3lTe3AEWZ66W7Dh7lVEpJbHoKOuHc1sLrzMLMFjP8SNULHaykzsonUEDbKedv8C+7ej6g==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-normalize-timing-functions@7.0.1: resolution: {integrity: sha512-bHifyuuSNdKKsnNJ0s8fmfLMlvsQwYVxIoUBnowIVl2ZAdrkYQNGVB4RxjfpvkMjipqvbz0u7feBZybkl/6NJg==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7791,12 +6758,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-normalize-unicode@7.0.2: - resolution: {integrity: sha512-ztisabK5C/+ZWBdYC+Y9JCkp3M9qBv/XFvDtSw0d/XwfT3UaKeW/YTm/MD/QrPNxuecia46vkfEhewjwcYFjkg==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-normalize-unicode@7.0.3: resolution: {integrity: sha512-EcoA29LvG3F+EpOh03iqu+tJY3uYYKzArqKJHxDhUYLa2u58aqGq16K6/AOsXD9yqLN8O6y9mmePKN5cx6krOw==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7809,12 +6770,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-normalize-url@7.0.0: - resolution: {integrity: sha512-+d7+PpE+jyPX1hDQZYG+NaFD+Nd2ris6r8fPTBAjE8z/U41n/bib3vze8x7rKs5H1uEw5ppe9IojewouHk0klQ==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-normalize-url@7.0.1: resolution: {integrity: sha512-sUcD2cWtyK1AOL/82Fwy1aIVm/wwj5SdZkgZ3QiUzSzQQofrbq15jWJ3BA7Z+yVRwamCjJgZJN0I9IS7c6tgeQ==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7827,12 +6782,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-normalize-whitespace@7.0.0: - resolution: {integrity: sha512-37/toN4wwZErqohedXYqWgvcHUGlT8O/m2jVkAfAe9Bd4MzRqlBmXrJRePH0e9Wgnz2X7KymTgTOaaFizQe3AQ==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-normalize-whitespace@7.0.1: resolution: {integrity: sha512-vsbgFHMFQrJBJKrUFJNZ2pgBeBkC2IvvoHjz1to0/0Xk7sII24T0qFOiJzG6Fu3zJoq/0yI4rKWi7WhApW+EFA==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7845,12 +6794,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-ordered-values@7.0.1: - resolution: {integrity: sha512-irWScWRL6nRzYmBOXReIKch75RRhNS86UPUAxXdmW/l0FcAsg0lvAXQCby/1lymxn/o0gVa6Rv/0f03eJOwHxw==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-ordered-values@7.0.2: resolution: {integrity: sha512-AMJjt1ECBffF7CEON/Y0rekRLS6KsePU6PRP08UqYW4UGFRnTXNrByUzYK1h8AC7UWTZdQ9O3Oq9kFIhm0SFEw==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7863,12 +6806,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-reduce-initial@7.0.2: - resolution: {integrity: sha512-pOnu9zqQww7dEKf62Nuju6JgsW2V0KRNBHxeKohU+JkHd/GAH5uvoObqFLqkeB2n20mr6yrlWDvo5UBU5GnkfA==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-reduce-initial@7.0.3: resolution: {integrity: sha512-RFvkZaqiWtGMlVjlUHpaxGqEL27lgt+Q2Ixjf83CRAzqdo+TsDyGPtJUbPx2MuYIJ+sCQc2TrOvRnhcXQfgIVA==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7881,12 +6818,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-reduce-transforms@7.0.0: - resolution: {integrity: sha512-pnt1HKKZ07/idH8cpATX/ujMbtOGhUfE+m8gbqwJE05aTaNw8gbo34a2e3if0xc0dlu75sUOiqvwCGY3fzOHew==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-reduce-transforms@7.0.1: resolution: {integrity: sha512-MhyEbfrm+Mlp/36hvZ9mT9DaO7dbncU0CvWI8V93LRkY6IYlu38OPg3FObnuKTUxJ4qA8HpurdQOo5CyqqO76g==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7922,12 +6853,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-svgo@7.0.1: - resolution: {integrity: sha512-0WBUlSL4lhD9rA5k1e5D8EN5wCEyZD6HJk0jIvRxl+FDVOMlJ7DePHYWGGVc5QRqrJ3/06FTXM0bxjmJpmTPSA==} - engines: {node: ^18.12.0 || ^20.9.0 || >= 18} - peerDependencies: - postcss: ^8.4.31 - postcss-svgo@7.0.2: resolution: {integrity: sha512-5Dzy66JlnRM6pkdOTF8+cGsB1fnERTE8Nc+Eed++fOWo1hdsBptCsbG8UuJkgtZt75bRtMJIrPeZmtfANixdFA==} engines: {node: ^18.12.0 || ^20.9.0 || >= 18} @@ -7940,12 +6865,6 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-unique-selectors@7.0.3: - resolution: {integrity: sha512-J+58u5Ic5T1QjP/LDV9g3Cx4CNOgB5vz+kM6+OxHHhFACdcDeKhBXjQmB7fnIZM12YSTvsL0Opwco83DmacW2g==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - postcss-unique-selectors@7.0.4: resolution: {integrity: sha512-pmlZjsmEAG7cHd7uK3ZiNSW6otSZ13RHuZ/4cDN/bVglS5EpF2r2oxY99SuOHa8m7AWoBCelTS3JPpzsIs8skQ==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -7961,16 +6880,20 @@ packages: peerDependencies: postcss: ^8.2.9 + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + postcss@8.5.3: resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} engines: {node: ^10 || ^12 || >=14} - preact@10.26.4: - resolution: {integrity: sha512-KJhO7LBFTjP71d83trW+Ilnjbo+ySsaAgCfXOXUlmGzJ4ygYPWmysm77yg4emwfmoz3b22yvH5IsVFHbhUaH5w==} + preact@10.26.7: + resolution: {integrity: sha512-43xS+QYc1X1IPbw03faSgY6I6OYWcLrJRv3hU0+qMOfh/XCHcP0MX2CVjNARYR2cC/guu975sta4OcjlczxD7g==} - precinct@11.0.5: - resolution: {integrity: sha512-oHSWLC8cL/0znFhvln26D14KfCQFFn4KOLSw6hmLhd+LQ2SKt9Ljm89but76Pc7flM9Ty1TnXyrA2u16MfRV3w==} - engines: {node: ^14.14.0 || >=16.0.0} + precinct@12.2.0: + resolution: {integrity: sha512-NFBMuwIfaJ4SocE9YXPU/n4AcNSoFMVFjP72nvl3cx69j/ke61/hPOWFREVxLkFhhEGnA8ZuVfTqJBa+PK3b5w==} + engines: {node: '>=18'} hasBin: true prelude-ls@1.2.1: @@ -7995,14 +6918,14 @@ packages: resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} engines: {node: ^14.13.1 || >=16.0.0} + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + pretty-format@29.7.0: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - pretty-ms@9.2.0: - resolution: {integrity: sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==} - engines: {node: '>=18'} - process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} @@ -8017,8 +6940,8 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - property-information@7.0.0: - resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==} + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} @@ -8035,9 +6958,6 @@ packages: pump@3.0.2: resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} - punycode@1.4.1: - resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -8046,17 +6966,13 @@ packages: resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} engines: {node: '>=0.6'} - quansync@0.2.8: - resolution: {integrity: sha512-4+saucphJMazjt7iOM27mbFCk+D9dd/zmgMDCzRZ8MEoBfYp7lAvoN38et/phRQF6wOPMy/OROBGgoWeSKyluA==} + quansync@0.2.10: + resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==} query-string@7.1.3: resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} engines: {node: '>=6'} - querystring-es3@0.2.1: - resolution: {integrity: sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==} - engines: {node: '>=0.4.x'} - queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -8083,43 +6999,28 @@ packages: rc9@2.1.2: resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} - react-dom@18.3.1: - resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + react-dom@19.1.0: + resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} peerDependencies: - react: ^18.3.1 + react: ^19.1.0 react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - react-is@19.0.0: - resolution: {integrity: sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==} - - react-refresh@0.14.2: - resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} + react-refresh@0.17.0: + resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} engines: {node: '>=0.10.0'} - react-transition-group@4.4.5: - resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} - peerDependencies: - react: '>=16.6.0' - react-dom: '>=16.6.0' - - react-world-flags@1.6.0: - resolution: {integrity: sha512-eutSeAy5YKoVh14js/JUCSlA6EBk1n4k+bDaV+NkNB50VhnG+f4QDTpYycnTUTsZ5cqw/saPmk0Z4Fa0VVZ1Iw==} - peerDependencies: - react: '>=0.14' - - react@18.3.1: - resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + react@19.1.0: + resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} engines: {node: '>=0.10.0'} - read-package-json-fast@4.0.0: - resolution: {integrity: sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg==} - engines: {node: ^18.17.0 || >=20.5.0} - read-package-up@11.0.0: resolution: {integrity: sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==} engines: {node: '>=18'} @@ -8178,9 +7079,6 @@ packages: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} - regenerator-runtime@0.14.1: - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - regex-recursion@6.0.2: resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} @@ -8228,9 +7126,6 @@ packages: resolution: {integrity: sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==} engines: {node: '>=0.10.5'} - reselect@4.1.8: - resolution: {integrity: sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==} - resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -8242,6 +7137,10 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve.exports@2.0.3: + resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} + engines: {node: '>=10'} + resolve@1.19.0: resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==} @@ -8270,11 +7169,16 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true + rimraf@6.0.1: + resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==} + engines: {node: 20 || >=22} + hasBin: true + ripemd160@2.0.2: resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} - rollup-plugin-dts@6.1.1: - resolution: {integrity: sha512-aSHRcJ6KG2IHIioYlvAOcEq6U99sVtqDDKVhnwt70rW6tsz3tv5OSjEiWcgzfsHdLyGXZ/3b/7b/+Za3Y6r1XA==} + rollup-plugin-dts@6.2.1: + resolution: {integrity: sha512-sR3CxYUl7i2CHa0O7bA45mCrgADyAQ0tVtGSqi3yvH28M+eg1+g5d7kQ9hLvEz5dorK3XVsH5L2jwHLQf72DzA==} engines: {node: '>=16'} peerDependencies: rollup: ^3.29.4 || ^4 @@ -8304,16 +7208,6 @@ packages: rollup: optional: true - rollup@4.35.0: - resolution: {integrity: sha512-kg6oI4g+vc41vePJyO6dHt/yl0Rz3Thv0kJeVQ3D1kS3E5XSuKbPc29G4IpT/Kv1KQwgHVcN+HtyS+HYLNSvQg==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - rollup@4.39.0: - resolution: {integrity: sha512-thI8kNc02yNvnmJp8dr3fNWJ9tCONDhp6TV35X6HkKGGs9E6q7YWCHbe5vKiTa7TAiNcFEmXKj3X/pG2b3ci0g==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - rollup@4.40.2: resolution: {integrity: sha512-tfUOg6DTP4rhQ3VjOO6B4wyrJnGOX85requAXvqYTHsOgb2TFJdZ3aWpT8W2kPoypSGP7dZUyzxJ9ee4buM5Fg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -8354,8 +7248,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sass@1.85.1: - resolution: {integrity: sha512-Uk8WpxM5v+0cMR0XjX9KfRIacmSG86RH4DCCZjLU2rFh5tyutt9siAXJ7G+YfxQ99Q6wrRMbMlVl6KqUms71ag==} + sass@1.89.0: + resolution: {integrity: sha512-ld+kQU8YTdGNjOLfRWBzewJpU5cwEv/h5yyqlSeJcj6Yh8U4TDA9UA5FPicqDz/xgRPWRSYIQNiFks21TbA9KQ==} engines: {node: '>=14.0.0'} hasBin: true @@ -8363,8 +7257,8 @@ packages: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} - scheduler@0.23.2: - resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + scheduler@0.26.0: + resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} scslre@0.3.0: resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==} @@ -8380,10 +7274,18 @@ packages: resolution: {integrity: sha512-ssbk1VShojCe2rgqdz0ULu6ikrJDNuUfsUaqpSTid2n7xUiRFlatfvSLNN8BVqOdfliJptsoqu5NXbOZWpme4A==} engines: {node: 12 || 14 || >=16} + secure-random-bytes@5.0.1: + resolution: {integrity: sha512-48nvkahmdyoRbHW/x1HTGIk+i2/84MHFBB+rZ50cg1y/p2RjKG+fhTMQKZx4QD6T6/o2M2WHLPkncqQpjMMsUw==} + engines: {node: 18 || >=20} + secure-random-octet@2.0.0: resolution: {integrity: sha512-6LuHtdATut7HD0KRehBOTdpRvGoGBTd9eL3ZtA68bpOCP2xOK6ywDncxmqEa4dRXz4skCc42Q/SxPwcwZpZ8kQ==} engines: {node: 12 || 14 || >=16} + secure-random-octet@4.0.1: + resolution: {integrity: sha512-KEeg9wGi/96Q8Edp97gt5Z5dYCcvG7vPKdKFq6rPLCHtaaHwZKbhbC+gY74O7OjX8Fnels49wqc8IgkNhBJZfw==} + engines: {node: 18 || >=20} + semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -8392,20 +7294,11 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.7.1: - resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} - engines: {node: '>=10'} - hasBin: true - semver@7.7.2: resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} engines: {node: '>=10'} hasBin: true - send@0.19.0: - resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} - engines: {node: '>= 0.8.0'} - send@1.2.0: resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} engines: {node: '>= 18'} @@ -8416,17 +7309,10 @@ packages: serve-placeholder@2.0.2: resolution: {integrity: sha512-/TMG8SboeiQbZJWRlfTCqMs2DD3SZgWp0kDQePz9yUuCnDfDh/92gf7/PxGhzXTKBIPASIHxFcZndoNbp6QOLQ==} - serve-static@1.16.2: - resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} - engines: {node: '>= 0.8.0'} - serve-static@2.2.0: resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} engines: {node: '>= 18'} - set-blocking@2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -8439,9 +7325,6 @@ packages: resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} engines: {node: '>= 0.4'} - setimmediate@1.0.5: - resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} - setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} @@ -8449,6 +7332,10 @@ packages: resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} hasBin: true + sharp@0.34.2: + resolution: {integrity: sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -8511,9 +7398,6 @@ packages: resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} engines: {node: '>=14.16'} - slashes@3.0.12: - resolution: {integrity: sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==} - slice-ansi@4.0.0: resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} engines: {node: '>=10'} @@ -8528,10 +7412,6 @@ packages: source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - source-map@0.5.7: - resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} - engines: {node: '>=0.10.0'} - source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} @@ -8592,17 +7472,15 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} - std-env@3.8.1: - resolution: {integrity: sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==} - std-env@3.9.0: resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} stream-browserify@3.0.0: resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} - stream-http@3.2.0: - resolution: {integrity: sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==} + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} streamx@2.22.0: resolution: {integrity: sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==} @@ -8667,10 +7545,6 @@ packages: resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} engines: {node: '>=12'} - strip-final-newline@4.0.0: - resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} - engines: {node: '>=18'} - strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -8686,29 +7560,31 @@ packages: strip-literal@3.0.0: resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} - strong-log-transformer@2.1.0: - resolution: {integrity: sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==} - engines: {node: '>=4'} - hasBin: true - structured-clone-es@1.0.0: resolution: {integrity: sha512-FL8EeKFFyNQv5cMnXI31CIMCsFarSVI2bF0U0ImeNE3g/F1IvJQyqzOXxPBRXiwQfyBTlbNe88jh1jFW0O/jiQ==} style-search@0.1.0: resolution: {integrity: sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==} + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + stylehacks@5.1.1: resolution: {integrity: sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - stylehacks@7.0.4: - resolution: {integrity: sha512-i4zfNrGMt9SB4xRK9L83rlsFCgdGANfeDAYacO1pkqcE7cRHPdWHwnKZVz7WY17Veq/FvyYsRAU++Ga+qDFIww==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - stylehacks@7.0.5: resolution: {integrity: sha512-5kNb7V37BNf0Q3w+1pxfa+oiNPS++/b4Jil9e/kPDgrk1zjEd6uR7SZeJiYaLYH6RRSC1XX2/37OTeU/4FvuIA==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -8753,9 +7629,6 @@ packages: engines: {node: ^14.13.1 || >=16.0.0} hasBin: true - stylis@4.2.0: - resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} - superjson@2.2.2: resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==} engines: {node: '>=16'} @@ -8776,9 +7649,6 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - svg-country-flags@1.2.10: - resolution: {integrity: sha512-xrqwo0TYf/h2cfPvGpjdSuSguUbri4vNNizBnwzoZnX0xGo3O5nGJMlbYEp7NOYcnPGBm6LE2axqDWSB847bLw==} - svg-tags@1.0.0: resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} @@ -8795,8 +7665,8 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - synckit@0.9.2: - resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==} + synckit@0.11.6: + resolution: {integrity: sha512-2pR2ubZSV64f/vqm9eLPz/KOvR9Dm+Co/5ChLgeHl0yEDRc6h5hXHoxEQH8Y5Ljycozd3p1k5TTSVdzYGkPvLw==} engines: {node: ^14.18.0 || >=16.0.0} system-architecture@0.1.0: @@ -8810,8 +7680,8 @@ packages: resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} engines: {node: '>=10.0.0'} - tapable@2.2.1: - resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + tapable@2.2.2: + resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} engines: {node: '>=6'} tar-stream@2.2.0: @@ -8821,10 +7691,6 @@ packages: tar-stream@3.1.7: resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} - tar@6.2.1: - resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} - engines: {node: '>=10'} - tar@7.4.3: resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} engines: {node: '>=18'} @@ -8833,8 +7699,8 @@ packages: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} - terser@5.39.0: - resolution: {integrity: sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==} + terser@5.39.2: + resolution: {integrity: sha512-yEPUmWve+VA78bI71BW70Dh0TuV4HHd+I5SHOAfS1+QBOmvmCiiffgjR8ryyEd3KIfvPGFqoADt8LdQ6XpXIvg==} engines: {node: '>=10'} hasBin: true @@ -8851,13 +7717,6 @@ packages: text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - - timers-browserify@2.0.12: - resolution: {integrity: sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==} - engines: {node: '>=0.6.0'} - tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} @@ -8870,10 +7729,6 @@ packages: tinyexec@1.0.1: resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} - tinyglobby@0.2.12: - resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} - engines: {node: '>=12.0.0'} - tinyglobby@0.2.13: resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==} engines: {node: '>=12.0.0'} @@ -8890,11 +7745,11 @@ packages: resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} engines: {node: '>=14.0.0'} - tldts-core@6.1.84: - resolution: {integrity: sha512-NaQa1W76W2aCGjXybvnMYzGSM4x8fvG2AN/pla7qxcg0ZHbooOPhA8kctmOZUDfZyhDL27OGNbwAeig8P4p1vg==} + tldts-core@6.1.86: + resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} - tldts@6.1.84: - resolution: {integrity: sha512-aRGIbCIF3teodtUFAYSdQONVmDRy21REM3o6JnqWn5ZkQBJJ4gHxhw6OfwQ+WkSAi3ASamrS4N4nyazWx6uTYg==} + tldts@6.1.86: + resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} hasBin: true tmp-promise@3.0.3: @@ -8930,8 +7785,8 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - tr46@5.1.0: - resolution: {integrity: sha512-IUWnUK7ADYR5Sl1fZlO1INDUhVhatWl7BtJWsIhwJ0UAK7ilzzIa8uIqOO/aYVWHZPJkKbEL+362wrzoeRF7bw==} + tr46@5.1.1: + resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} engines: {node: '>=18'} trim-lines@3.0.1: @@ -8951,14 +7806,14 @@ packages: peerDependencies: typescript: '>=4.2.0' - ts-api-utils@2.0.1: - resolution: {integrity: sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==} + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' - tsconfck@3.1.5: - resolution: {integrity: sha512-CLDfGgUp7XPswWnezWwsCRxNmgQjhYq3VXHM0/XIRxhVrKw0M1if9agzryh1QS3nxjCROvV+xWxoJO1YctzzWg==} + tsconfck@3.1.6: + resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} engines: {node: ^18 || >=20} hasBin: true peerDependencies: @@ -8986,9 +7841,6 @@ packages: peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - tty-browserify@0.0.1: - resolution: {integrity: sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==} - type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -9009,8 +7861,8 @@ packages: resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} engines: {node: '>=8'} - type-fest@4.39.1: - resolution: {integrity: sha512-uW9qzd66uyHYxwyVBYiwS4Oi0qZyUqwjU+Oevr6ZogYiXt99EOYtwvzMSLw1c3lYo2HzJsep/NB23iEVEgjG/w==} + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} type-level-regexp@0.1.17: @@ -9032,8 +7884,8 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typescript-eslint@8.26.1: - resolution: {integrity: sha512-t/oIs9mYyrwZGRpDv3g+3K6nZ5uhKEMt2oNmAPwaY4/ye0+EH4nXIPYNtkYFS6QHm+1DFg34DbglYBz5P9Xysg==} + typescript-eslint@8.33.1: + resolution: {integrity: sha512-AgRnV4sKkWOiZ0Kjbnf5ytTJXMUZQ0qhSVdQtDNYLPLnjsATEYhaO94GlRQwi4t4gO8FfjM6NnikHeKjUm8D7A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -9044,14 +7896,16 @@ packages: engines: {node: '>=14.17'} hasBin: true + typescript@5.7.3: + resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} + engines: {node: '>=14.17'} + hasBin: true + typescript@5.8.3: resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} engines: {node: '>=14.17'} hasBin: true - ufo@1.5.4: - resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} - ufo@1.6.1: resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} @@ -9080,23 +7934,14 @@ packages: undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - undici-types@6.20.0: - resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} - undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - unenv@2.0.0-rc.15: - resolution: {integrity: sha512-J/rEIZU8w6FOfLNz/hNKsnY+fFHWnu9MH4yRbSZF3xbbGHovcetXPs7sD+9p8L6CeNC//I9bhRYAOsBt2u7/OA==} - unenv@2.0.0-rc.17: resolution: {integrity: sha512-B06u0wXkEd+o5gOCMl/ZHl5cfpYbDZKAT+HWTL+Hws6jWu7dCiqBBXXXzMFcFVJb8D4ytAnYmxJA83uwOQRSsg==} - unhead@2.0.5: - resolution: {integrity: sha512-bG4wyp+KuW+ivQYtTQvnvtMM55ziIrQ9Yq1/VAm099buBgH0CoBWgu39jkSUoE4oZ4Qki8SsnMbq2gL0h3/sUA==} - - unhead@2.0.8: - resolution: {integrity: sha512-63WR+y08RZE7ChiFdgNY64haAkhCtUS5/HM7xo4Q83NA63txWbEh2WGmrKbArdQmSct+XlqbFN8ZL1yWpQEHEA==} + unhead@2.0.10: + resolution: {integrity: sha512-GT188rzTCeSKt55tYyQlHHKfUTtZvgubrXiwzGeXg6UjcKO3FsagaMzQp6TVDrpDY++3i7Qt0t3pnCc/ebg5yQ==} unicorn-magic@0.1.0: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} @@ -9106,10 +7951,6 @@ packages: resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} engines: {node: '>=18'} - unimport@4.1.3: - resolution: {integrity: sha512-H+IVJ7rAkE3b+oC8rSJ2FsPaVsweeMC8eKZc+C6Mz7+hxDF45AnrY/tVCNRBvzMwWNcJEV67WdAVcal27iMjOw==} - engines: {node: '>=18.12.0'} - unimport@5.0.1: resolution: {integrity: sha512-1YWzPj6wYhtwHE+9LxRlyqP4DiRrhGfJxdtH475im8ktyZXO3jHj/3PZ97zDdvkYoovFdi0K4SKl3a7l92v3sQ==} engines: {node: '>=18.12.0'} @@ -9157,75 +7998,12 @@ packages: resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} engines: {node: '>=14.0.0'} - unplugin@2.2.2: - resolution: {integrity: sha512-Qp+iiD+qCRnUek+nDoYvtWX7tfnYyXsrOnJ452FRTgOyKmTM7TUJ3l+PLPJOOWPTUyKISKp4isC5JJPSXUjGgw==} - engines: {node: '>=18.12.0'} - unplugin@2.3.4: resolution: {integrity: sha512-m4PjxTurwpWfpMomp8AptjD5yj8qEZN5uQjjGM3TAs9MWWD2tXSSNNj6jGR2FoVGod4293ytyV6SwBbertfyJg==} engines: {node: '>=18.12.0'} - unrs-resolver@1.5.0: - resolution: {integrity: sha512-6aia3Oy7SEe0MuUGQm2nsyob0L2+g57w178K5SE/3pvSGAIp28BB2O921fKx424Ahc/gQ6v0DXFbhcpyhGZdOA==} - - unstorage@1.15.0: - resolution: {integrity: sha512-m40eHdGY/gA6xAPqo8eaxqXgBuzQTlAKfmB1iF7oCKXE1HfwHwzDJBywK+qQGn52dta+bPlZluPF7++yR3p/bg==} - peerDependencies: - '@azure/app-configuration': ^1.8.0 - '@azure/cosmos': ^4.2.0 - '@azure/data-tables': ^13.3.0 - '@azure/identity': ^4.6.0 - '@azure/keyvault-secrets': ^4.9.0 - '@azure/storage-blob': ^12.26.0 - '@capacitor/preferences': ^6.0.3 - '@deno/kv': '>=0.9.0' - '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 - '@planetscale/database': ^1.19.0 - '@upstash/redis': ^1.34.3 - '@vercel/blob': '>=0.27.1' - '@vercel/kv': ^1.0.1 - aws4fetch: ^1.0.20 - db0: '>=0.2.1' - idb-keyval: ^6.2.1 - ioredis: ^5.4.2 - uploadthing: ^7.4.4 - peerDependenciesMeta: - '@azure/app-configuration': - optional: true - '@azure/cosmos': - optional: true - '@azure/data-tables': - optional: true - '@azure/identity': - optional: true - '@azure/keyvault-secrets': - optional: true - '@azure/storage-blob': - optional: true - '@capacitor/preferences': - optional: true - '@deno/kv': - optional: true - '@netlify/blobs': - optional: true - '@planetscale/database': - optional: true - '@upstash/redis': - optional: true - '@vercel/blob': - optional: true - '@vercel/kv': - optional: true - aws4fetch: - optional: true - db0: - optional: true - idb-keyval: - optional: true - ioredis: - optional: true - uploadthing: - optional: true + unrs-resolver@1.7.2: + resolution: {integrity: sha512-BBKpaylOW8KbHsu378Zky/dGh4ckT/4NW/0SHRABdqRLcQJ2dAOjDo9g97p04sWflm0kqPqpUatxReNV/dqI5A==} unstorage@1.16.0: resolution: {integrity: sha512-WQ37/H5A7LcRPWfYOrDa1Ys02xAbpPJq6q5GkO88FBXVSQzHd7+BjEwfRqyaSWCv9MbsJy058GWjjPjcJ16GGA==} @@ -9309,10 +8087,6 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - url@0.11.4: - resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==} - engines: {node: '>= 0.4'} - urlpattern-polyfill@10.1.0: resolution: {integrity: sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==} @@ -9322,9 +8096,6 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - util@0.12.5: - resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} - uuid@11.1.0: resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} hasBin: true @@ -9350,64 +8121,20 @@ packages: peerDependencies: vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 - vite-hot-client@0.2.4: - resolution: {integrity: sha512-a1nzURqO7DDmnXqabFOliz908FRmIppkBKsJthS8rbe8hBEXwEwe4C3Pp33Z1JoFCYfVL4kTOMLKk0ZZxREIeA==} - peerDependencies: - vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 - vite-hot-client@2.0.4: resolution: {integrity: sha512-W9LOGAyGMrbGArYJN4LBCdOC5+Zwh7dHvOHC0KmGKkJhsOzaKbpo/jEjpPKVHIW0/jBWj8RZG0NUxfgA8BxgAg==} peerDependencies: vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 - vite-node@3.0.8: - resolution: {integrity: sha512-6PhR4H9VGlcwXZ+KWCdMqbtG649xCPZqfI9j2PsK1FcXgEzro5bGHcVKFCTqPLaNKZES8Evqv4LwvZARsq5qlg==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - - vite-node@3.1.1: - resolution: {integrity: sha512-V+IxPAE2FvXpTCHXyNem0M+gWm6J7eRyWPR6vYoG/Gl+IscNOjXzztUhimQgTxaAoUoj40Qqimaa0NLIOOAH4w==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - vite-node@3.1.3: resolution: {integrity: sha512-uHV4plJ2IxCl4u1up1FQRrqclylKAogbtBfOTwcuJ28xFi+89PZ57BRh+naIRvH70HPwxy5QHYzg1OrEaC7AbA==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true - vite-plugin-checker@0.9.1: - resolution: {integrity: sha512-neH3CSNWdkZ+zi+WPt/0y5+IO2I0UAI0NX6MaXqU/KxN1Lz6np/7IooRB6VVAMBa4nigqm1GRF6qNa4+EL5jDQ==} - engines: {node: '>=14.16'} - peerDependencies: - '@biomejs/biome': '>=1.7' - eslint: '>=7' - meow: ^13.2.0 - optionator: ^0.9.4 - stylelint: '>=16' - typescript: '*' - vite: '>=2.0.0' - vls: '*' - vti: '*' - vue-tsc: ~2.2.2 - peerDependenciesMeta: - '@biomejs/biome': - optional: true - eslint: - optional: true - meow: - optional: true - optionator: - optional: true - stylelint: - optional: true - typescript: - optional: true - vls: - optional: true - vti: - optional: true - vue-tsc: - optional: true + vite-node@3.1.4: + resolution: {integrity: sha512-6enNwYnpyDo4hEgytbmc6mYWHXDHYEn0D1/rw4Q+tnHUGtKTJsn8T1YkX6Q18wI5LCrS8CTYlBaiCqxOy2kvUA==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true vite-plugin-checker@0.9.3: resolution: {integrity: sha512-Tf7QBjeBtG7q11zG0lvoF38/2AVUzzhMNu+Wk+mcsJ00Rk/FpJ4rmUviVJpzWkagbU13cGXvKpt7CMiqtxVTbQ==} @@ -9443,18 +8170,8 @@ packages: vue-tsc: optional: true - vite-plugin-inspect@0.8.9: - resolution: {integrity: sha512-22/8qn+LYonzibb1VeFZmISdVao5kC22jmEKm24vfFE8siEn47EpVcCLYMv6iKOYMJfjSvSJfueOwcFCkUnV3A==} - engines: {node: '>=14'} - peerDependencies: - '@nuxt/kit': '*' - vite: ^3.1.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.1 - peerDependenciesMeta: - '@nuxt/kit': - optional: true - - vite-plugin-inspect@11.0.0: - resolution: {integrity: sha512-Q0RDNcMs1mbI2yGRwOzSapnnA6NFO0j88+Vb8pJX0iYMw34WczwKJi3JgheItDhbWRq/CLUR0cs+ajZpcUaIFQ==} + vite-plugin-inspect@11.1.0: + resolution: {integrity: sha512-r3Nx8xGQ08bSoNu7gJGfP5H/wNOROHtv0z3tWspplyHZJlABwNoPOdFEmcVh+lVMDyk/Be4yt8oS596ZHoYhOg==} engines: {node: '>=14'} peerDependencies: '@nuxt/kit': '*' @@ -9463,30 +8180,14 @@ packages: '@nuxt/kit': optional: true - vite-plugin-node-polyfills@0.21.0: - resolution: {integrity: sha512-Sk4DiKnmxN8E0vhgEhzLudfJQfaT8k4/gJ25xvUPG54KjLJ6HAmDKbr4rzDD/QWEY+Lwg80KE85fGYBQihEPQA==} - peerDependencies: - vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 - - vite-plugin-vue-devtools@7.7.2: - resolution: {integrity: sha512-5V0UijQWiSBj32blkyPEqIbzc6HO9c1bwnBhx+ay2dzU0FakH+qMdNUT8nF9BvDE+i6I1U8CqCuJiO20vKEdQw==} - engines: {node: '>=v14.21.3'} - peerDependencies: - vite: ^3.1.0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 - - vite-plugin-vue-inspector@5.3.1: - resolution: {integrity: sha512-cBk172kZKTdvGpJuzCCLg8lJ909wopwsu3Ve9FsL1XsnLBiRT9U3MePcqrgGHgCX2ZgkqZmAGR8taxw+TV6s7A==} - peerDependencies: - vite: ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 - vite-plugin-vue-tracer@0.1.3: resolution: {integrity: sha512-+fN6oo0//dwZP9Ax9gRKeUroCqpQ43P57qlWgL0ljCIxAs+Rpqn/L4anIPZPgjDPga5dZH+ZJsshbF0PNJbm3Q==} peerDependencies: vite: ^6.0.0 vue: ^3.5.0 - vite@5.4.14: - resolution: {integrity: sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==} + vite@5.4.19: + resolution: {integrity: sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -9516,86 +8217,6 @@ packages: terser: optional: true - vite@6.2.2: - resolution: {integrity: sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - jiti: '>=1.21.0' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - vite@6.2.5: - resolution: {integrity: sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - jiti: '>=1.21.0' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - vite@6.3.5: resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -9648,47 +8269,35 @@ packages: postcss: optional: true - vitest-environment-nuxt@1.0.1: - resolution: {integrity: sha512-eBCwtIQriXW5/M49FjqNKfnlJYlG2LWMSNFsRVKomc8CaMqmhQPBS5LZ9DlgYL9T8xIVsiA6RZn2lk7vxov3Ow==} - - vitest@3.0.8: - resolution: {integrity: sha512-dfqAsNqRGUc8hB9OVR2P0w8PZPEckti2+5rdZip0WIz9WW0MnImJ8XiR61QhqLa92EQzKP2uPkzenKOAHyEIbA==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true + vitest-browser-react@0.1.1: + resolution: {integrity: sha512-n9l+sIAexKqqfBuEkjVGdfZ4xAn1Gn/+wc4Mo8KsUSUOVoM9evSY0rVXdMIzCQqloT/zvmFGAtziFINkqu+t7g==} + engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: - '@edge-runtime/vm': '*' - '@types/debug': ^4.1.12 - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': 3.0.8 - '@vitest/ui': 3.0.8 - happy-dom: '*' - jsdom: '*' + '@types/react': '>18.0.0' + '@types/react-dom': '>18.0.0' + '@vitest/browser': '>=2.1.0' + react: '>18.0.0' + react-dom: '>18.0.0' + vitest: '>=2.1.0' peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@types/debug': - optional: true - '@types/node': - optional: true - '@vitest/browser': - optional: true - '@vitest/ui': - optional: true - happy-dom: + '@types/react': optional: true - jsdom: + '@types/react-dom': optional: true - vitest@3.1.1: - resolution: {integrity: sha512-kiZc/IYmKICeBAZr9DQ5rT7/6bD9G7uqQEki4fxazi1jdVl2mWGzedtBs5s6llz59yQhVb7FFY2MbHzHCnT79Q==} + vitest-environment-nuxt@1.0.1: + resolution: {integrity: sha512-eBCwtIQriXW5/M49FjqNKfnlJYlG2LWMSNFsRVKomc8CaMqmhQPBS5LZ9DlgYL9T8xIVsiA6RZn2lk7vxov3Ow==} + + vitest@3.1.3: + resolution: {integrity: sha512-188iM4hAHQ0km23TN/adso1q5hhwKqUpv+Sd6p5sOuh6FhQnRNW3IsiIpvxqahtBabsJ2SLZgmGSpcYK4wQYJw==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/debug': ^4.1.12 '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': 3.1.1 - '@vitest/ui': 3.1.1 + '@vitest/browser': 3.1.3 + '@vitest/ui': 3.1.3 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -9707,23 +8316,20 @@ packages: jsdom: optional: true - vm-browserify@1.1.2: - resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} - vscode-uri@3.1.0: resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} vue-bundle-renderer@2.1.1: resolution: {integrity: sha512-+qALLI5cQncuetYOXp4yScwYvqh8c6SMXee3B+M7oTZxOgtESP0l4j/fXdEJoZ+EdMxkGWIj+aSEyjXkOdmd7g==} - vue-component-type-helpers@2.2.8: - resolution: {integrity: sha512-4bjIsC284coDO9om4HPA62M7wfsTvcmZyzdfR0aUlFXqq4tXxM1APyXpNVxPC8QazKw9OhmZNHBVDA6ODaZsrA==} + vue-component-type-helpers@2.2.10: + resolution: {integrity: sha512-iDUO7uQK+Sab2tYuiP9D1oLujCWlhHELHMgV/cB13cuGbG4qwkLHvtfWb6FzvxrIOPDnU0oHsz2MlQjhYDeaHA==} vue-devtools-stub@0.1.0: resolution: {integrity: sha512-RutnB7X8c5hjq39NceArgXg28WZtZpGc3+J16ljMiYnFhKvd8hITxSWQSQ5bvldxMDU6gG5mkxl1MTQLXckVSQ==} - vue-eslint-parser@10.1.1: - resolution: {integrity: sha512-bh2Z/Au5slro9QJ3neFYLanZtb1jH+W2bKqGHXAoYD4vZgNG3KeotL7JpPv5xzY4UXUXJl7TrIsnzECH63kd3Q==} + vue-eslint-parser@10.1.3: + resolution: {integrity: sha512-dbCBnd2e02dYWsXoqX5yKUZlOt+ExIpq7hmHKPb5ZqKcjf++Eo0hMseFTZMLKThrUk61m+Uv6A2YSBve6ZvuDQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -9734,31 +8340,27 @@ packages: peerDependencies: eslint: '>=6.0.0' - vue-router@4.5.0: - resolution: {integrity: sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==} - peerDependencies: - vue: ^3.2.0 - vue-router@4.5.1: resolution: {integrity: sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==} peerDependencies: vue: ^3.2.0 - vue-sfc-transformer@0.1.11: - resolution: {integrity: sha512-nfh8jfBuZKtHv/TRbCfCChQJr28dObEa+SH1IiKWOrRjIZkzPPFyW9wSfY8F5dCN2IV4C1o0n7e59luV4dTlxg==} + vue-sfc-transformer@0.1.16: + resolution: {integrity: sha512-pXx4pkHigOJCzGPXhGA9Rdou1oIuNiF9n4n5GQ7C4QehTXFEpKUjcpvc3PZ6LvC6ccUL021qor8j1153Y7/6Ig==} engines: {node: '>=18.0.0'} peerDependencies: + '@vue/compiler-core': ^3.5.13 esbuild: '*' vue: ^3.5.13 - vue-tsc@2.2.8: - resolution: {integrity: sha512-jBYKBNFADTN+L+MdesNX/TB3XuDSyaWynKMDgR+yCSln0GQ9Tfb7JS2lr46s2LiFUT1WsmfWsSvIElyxzOPqcQ==} + vue-tsc@2.2.10: + resolution: {integrity: sha512-jWZ1xSaNbabEV3whpIDMbjVSVawjAyW+x1n3JeGQo7S0uv2n9F/JMgWW90tGWNFRKya4YwKMZgCtr0vRAM7DeQ==} hasBin: true peerDependencies: typescript: '>=5.0.0' - vue@3.5.13: - resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} + vue@3.5.14: + resolution: {integrity: sha512-LbOm50/vZFG6Mhy6KscQYXZMQ0LMCC/y40HDJPPvGFQ+i/lUH+PJHR6C3assgOQiXdl6tAfsXHbXYVBZZu65ew==} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -9836,9 +8438,6 @@ packages: engines: {node: '>=8'} hasBin: true - wide-align@1.1.5: - resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} - winston-transport@4.9.0: resolution: {integrity: sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==} engines: {node: '>= 12.0.0'} @@ -9851,9 +8450,6 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} - world-countries@5.1.0: - resolution: {integrity: sha512-CXR6EBvTbArDlDDIWU3gfKb7Qk0ck2WNZ234b/A0vuecPzIfzzxH+O6Ejnvg1sT8XuiZjVlzOH0h08ZtaO7g0w==} - wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -9873,8 +8469,8 @@ packages: resolution: {integrity: sha512-GmqrO8WJ1NuzJ2DrziEI2o57jKAVIQNf8a18W3nCYU3H7PNWqCCVTeH6/NQE93CIllIgQS98rrmVkYgTX9fFJQ==} engines: {node: ^18.17.0 || >=20.5.0} - ws@8.18.1: - resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==} + ws@8.18.2: + resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -9896,10 +8492,6 @@ packages: xmlchars@2.2.0: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} - xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -9918,9 +8510,9 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} - yaml@2.7.1: - resolution: {integrity: sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==} - engines: {node: '>= 14'} + yaml@2.8.0: + resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==} + engines: {node: '>= 14.6'} hasBin: true yargs-parser@20.2.9: @@ -9946,166 +8538,153 @@ packages: resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==} engines: {node: '>=12.20'} - yoctocolors@2.1.1: - resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} - engines: {node: '>=18'} - youch-core@0.3.2: resolution: {integrity: sha512-fusrlIMLeRvTFYLUjJ9KzlGC3N+6MOPJ68HNj/yJv2nz7zq8t4HEviLms2gkdRPUS7F5rZ5n+pYx9r88m6IE1g==} engines: {node: '>=18'} - youch@4.1.0-beta.6: - resolution: {integrity: sha512-y1aNsEeoLXnWb6pI9TvfNPIxySyo4Un3OGxKn7rsNj8+tgSquzXEWkzfA5y6gU0fvzmQgvx3JBn/p51qQ8Xg9A==} - engines: {node: '>=18'} - youch@4.1.0-beta.7: resolution: {integrity: sha512-HUn0M24AUTMvjdkoMtH8fJz2FEd+k1xvtR9EoTrDUoVUi6o7xl5X+pST/vjk4T3GEQo2mJ9FlAvhWBm8dIdD4g==} engines: {node: '>=18'} - zip-stream@4.1.1: - resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==} - engines: {node: '>= 10'} - zip-stream@6.0.1: resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} engines: {node: '>= 14'} - zod@3.24.4: - resolution: {integrity: sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==} + zod@3.25.28: + resolution: {integrity: sha512-/nt/67WYKnr5by3YS7LroZJbtcCBurDKKPBPWWzaxvVCGuG/NOsiKkrjoOhI8mJ+SQUXEbUzeB3S+6XDUEEj7Q==} zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} snapshots: - '@algolia/autocomplete-core@1.17.7(@algolia/client-search@5.21.0)(algoliasearch@5.21.0)(search-insights@2.17.3)': + '@algolia/autocomplete-core@1.17.7(@algolia/client-search@5.25.0)(algoliasearch@5.25.0)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-plugin-algolia-insights': 1.17.7(@algolia/client-search@5.21.0)(algoliasearch@5.21.0)(search-insights@2.17.3) - '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.21.0)(algoliasearch@5.21.0) + '@algolia/autocomplete-plugin-algolia-insights': 1.17.7(@algolia/client-search@5.25.0)(algoliasearch@5.25.0)(search-insights@2.17.3) + '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.25.0)(algoliasearch@5.25.0) transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - search-insights - '@algolia/autocomplete-plugin-algolia-insights@1.17.7(@algolia/client-search@5.21.0)(algoliasearch@5.21.0)(search-insights@2.17.3)': + '@algolia/autocomplete-plugin-algolia-insights@1.17.7(@algolia/client-search@5.25.0)(algoliasearch@5.25.0)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.21.0)(algoliasearch@5.21.0) + '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.25.0)(algoliasearch@5.25.0) search-insights: 2.17.3 transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - '@algolia/autocomplete-preset-algolia@1.17.7(@algolia/client-search@5.21.0)(algoliasearch@5.21.0)': + '@algolia/autocomplete-preset-algolia@1.17.7(@algolia/client-search@5.25.0)(algoliasearch@5.25.0)': dependencies: - '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.21.0)(algoliasearch@5.21.0) - '@algolia/client-search': 5.21.0 - algoliasearch: 5.21.0 + '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.25.0)(algoliasearch@5.25.0) + '@algolia/client-search': 5.25.0 + algoliasearch: 5.25.0 - '@algolia/autocomplete-shared@1.17.7(@algolia/client-search@5.21.0)(algoliasearch@5.21.0)': + '@algolia/autocomplete-shared@1.17.7(@algolia/client-search@5.25.0)(algoliasearch@5.25.0)': dependencies: - '@algolia/client-search': 5.21.0 - algoliasearch: 5.21.0 + '@algolia/client-search': 5.25.0 + algoliasearch: 5.25.0 - '@algolia/client-abtesting@5.21.0': + '@algolia/client-abtesting@5.25.0': dependencies: - '@algolia/client-common': 5.21.0 - '@algolia/requester-browser-xhr': 5.21.0 - '@algolia/requester-fetch': 5.21.0 - '@algolia/requester-node-http': 5.21.0 + '@algolia/client-common': 5.25.0 + '@algolia/requester-browser-xhr': 5.25.0 + '@algolia/requester-fetch': 5.25.0 + '@algolia/requester-node-http': 5.25.0 - '@algolia/client-analytics@5.21.0': + '@algolia/client-analytics@5.25.0': dependencies: - '@algolia/client-common': 5.21.0 - '@algolia/requester-browser-xhr': 5.21.0 - '@algolia/requester-fetch': 5.21.0 - '@algolia/requester-node-http': 5.21.0 + '@algolia/client-common': 5.25.0 + '@algolia/requester-browser-xhr': 5.25.0 + '@algolia/requester-fetch': 5.25.0 + '@algolia/requester-node-http': 5.25.0 - '@algolia/client-common@5.21.0': {} + '@algolia/client-common@5.25.0': {} - '@algolia/client-insights@5.21.0': + '@algolia/client-insights@5.25.0': dependencies: - '@algolia/client-common': 5.21.0 - '@algolia/requester-browser-xhr': 5.21.0 - '@algolia/requester-fetch': 5.21.0 - '@algolia/requester-node-http': 5.21.0 + '@algolia/client-common': 5.25.0 + '@algolia/requester-browser-xhr': 5.25.0 + '@algolia/requester-fetch': 5.25.0 + '@algolia/requester-node-http': 5.25.0 - '@algolia/client-personalization@5.21.0': + '@algolia/client-personalization@5.25.0': dependencies: - '@algolia/client-common': 5.21.0 - '@algolia/requester-browser-xhr': 5.21.0 - '@algolia/requester-fetch': 5.21.0 - '@algolia/requester-node-http': 5.21.0 + '@algolia/client-common': 5.25.0 + '@algolia/requester-browser-xhr': 5.25.0 + '@algolia/requester-fetch': 5.25.0 + '@algolia/requester-node-http': 5.25.0 - '@algolia/client-query-suggestions@5.21.0': + '@algolia/client-query-suggestions@5.25.0': dependencies: - '@algolia/client-common': 5.21.0 - '@algolia/requester-browser-xhr': 5.21.0 - '@algolia/requester-fetch': 5.21.0 - '@algolia/requester-node-http': 5.21.0 + '@algolia/client-common': 5.25.0 + '@algolia/requester-browser-xhr': 5.25.0 + '@algolia/requester-fetch': 5.25.0 + '@algolia/requester-node-http': 5.25.0 - '@algolia/client-search@5.21.0': + '@algolia/client-search@5.25.0': dependencies: - '@algolia/client-common': 5.21.0 - '@algolia/requester-browser-xhr': 5.21.0 - '@algolia/requester-fetch': 5.21.0 - '@algolia/requester-node-http': 5.21.0 + '@algolia/client-common': 5.25.0 + '@algolia/requester-browser-xhr': 5.25.0 + '@algolia/requester-fetch': 5.25.0 + '@algolia/requester-node-http': 5.25.0 - '@algolia/ingestion@1.21.0': + '@algolia/ingestion@1.25.0': dependencies: - '@algolia/client-common': 5.21.0 - '@algolia/requester-browser-xhr': 5.21.0 - '@algolia/requester-fetch': 5.21.0 - '@algolia/requester-node-http': 5.21.0 + '@algolia/client-common': 5.25.0 + '@algolia/requester-browser-xhr': 5.25.0 + '@algolia/requester-fetch': 5.25.0 + '@algolia/requester-node-http': 5.25.0 - '@algolia/monitoring@1.21.0': + '@algolia/monitoring@1.25.0': dependencies: - '@algolia/client-common': 5.21.0 - '@algolia/requester-browser-xhr': 5.21.0 - '@algolia/requester-fetch': 5.21.0 - '@algolia/requester-node-http': 5.21.0 + '@algolia/client-common': 5.25.0 + '@algolia/requester-browser-xhr': 5.25.0 + '@algolia/requester-fetch': 5.25.0 + '@algolia/requester-node-http': 5.25.0 - '@algolia/recommend@5.21.0': + '@algolia/recommend@5.25.0': dependencies: - '@algolia/client-common': 5.21.0 - '@algolia/requester-browser-xhr': 5.21.0 - '@algolia/requester-fetch': 5.21.0 - '@algolia/requester-node-http': 5.21.0 + '@algolia/client-common': 5.25.0 + '@algolia/requester-browser-xhr': 5.25.0 + '@algolia/requester-fetch': 5.25.0 + '@algolia/requester-node-http': 5.25.0 - '@algolia/requester-browser-xhr@5.21.0': + '@algolia/requester-browser-xhr@5.25.0': dependencies: - '@algolia/client-common': 5.21.0 + '@algolia/client-common': 5.25.0 - '@algolia/requester-fetch@5.21.0': + '@algolia/requester-fetch@5.25.0': dependencies: - '@algolia/client-common': 5.21.0 + '@algolia/client-common': 5.25.0 - '@algolia/requester-node-http@5.21.0': + '@algolia/requester-node-http@5.25.0': dependencies: - '@algolia/client-common': 5.21.0 + '@algolia/client-common': 5.25.0 '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 - '@antfu/install-pkg@1.0.0': + '@antfu/install-pkg@1.1.0': dependencies: - package-manager-detector: 0.2.11 - tinyexec: 0.3.2 - - '@antfu/utils@0.7.10': {} + package-manager-detector: 1.3.0 + tinyexec: 1.0.1 - '@asamuzakjp/css-color@3.1.1': + '@asamuzakjp/css-color@3.1.7': dependencies: - '@csstools/css-calc': 2.1.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) - '@csstools/css-color-parser': 3.0.8(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-calc': 2.1.3(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-color-parser': 3.0.9(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) '@csstools/css-tokenizer': 3.0.3 lru-cache: 10.4.3 + optional: true '@asgardeo/auth-js@2.0.15': {} - '@asgardeo/auth-js@5.1.1': {} + '@asgardeo/auth-js@5.1.2': {} '@asgardeo/auth-node@0.1.3': dependencies: @@ -10120,9 +8699,9 @@ snapshots: transitivePeerDependencies: - encoding - '@asgardeo/auth-spa@3.1.4': + '@asgardeo/auth-spa@3.2.0': dependencies: - '@asgardeo/auth-js': 5.1.1 + '@asgardeo/auth-js': 5.1.2 await-semaphore: 0.1.3 axios: 0.26.1 base64url: 3.0.1 @@ -10135,264 +8714,191 @@ snapshots: '@asgardeo/js@0.1.3': dependencies: - '@asgardeo/auth-js': 5.1.1 + '@asgardeo/auth-js': 5.1.2 csstype: 3.1.3 lodash.isempty: 4.4.0 lodash.merge: 4.6.2 - '@asgardeo/react@0.2.4(0356e0e967205ddd07cd0bc9fd616469)': - dependencies: - '@asgardeo/js': 0.1.3 - '@oxygen-ui/react': 1.15.2(0356e0e967205ddd07cd0bc9fd616469) - base64url: 3.0.1 - buffer: 6.0.3 - clsx: 2.1.1 - fast-sha256: 1.3.0 - jose: 5.10.0 - randombytes: 2.1.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - transitivePeerDependencies: - - '@emotion/react' - - '@emotion/styled' - - '@mui/icons-material' - - '@mui/lab' - - '@mui/material' - - '@mui/system' - - '@mui/utils' - - '@types/react' - - typescript - - '@babel/code-frame@7.26.2': - dependencies: - '@babel/helper-validator-identifier': 7.25.9 - js-tokens: 4.0.0 - picocolors: 1.1.1 - '@babel/code-frame@7.27.1': dependencies: '@babel/helper-validator-identifier': 7.27.1 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.26.8': {} + '@babel/compat-data@7.27.2': {} - '@babel/core@7.26.10': + '@babel/core@7.27.1': dependencies: '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.10 - '@babel/helper-compilation-targets': 7.26.5 - '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.10) - '@babel/helpers': 7.26.10 - '@babel/parser': 7.26.10 - '@babel/template': 7.26.9 - '@babel/traverse': 7.26.10 - '@babel/types': 7.26.10 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.1 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.27.1(@babel/core@7.27.1) + '@babel/helpers': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/template': 7.27.2 + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 convert-source-map: 2.0.0 - debug: 4.4.0 + debug: 4.4.1 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/eslint-parser@7.26.10(@babel/core@7.26.10)(eslint@8.57.1)': + '@babel/eslint-parser@7.27.1(@babel/core@7.27.1)(eslint@8.57.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.27.1 '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 - eslint: 8.57.1 + eslint: 8.57.0 eslint-visitor-keys: 2.1.0 semver: 6.3.1 - '@babel/generator@7.26.10': + '@babel/generator@7.27.1': dependencies: - '@babel/parser': 7.26.10 - '@babel/types': 7.26.10 + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.1.0 - '@babel/helper-annotate-as-pure@7.25.9': + '@babel/helper-annotate-as-pure@7.27.1': dependencies: - '@babel/types': 7.26.10 + '@babel/types': 7.27.1 - '@babel/helper-compilation-targets@7.26.5': + '@babel/helper-compilation-targets@7.27.2': dependencies: - '@babel/compat-data': 7.26.8 - '@babel/helper-validator-option': 7.25.9 - browserslist: 4.24.4 + '@babel/compat-data': 7.27.2 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.24.5 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.26.9(@babel/core@7.26.10)': + '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.27.1)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-member-expression-to-functions': 7.25.9 - '@babel/helper-optimise-call-expression': 7.25.9 - '@babel/helper-replace-supers': 7.26.5(@babel/core@7.26.10) - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - '@babel/traverse': 7.26.10 + '@babel/core': 7.27.1 + '@babel/helper-annotate-as-pure': 7.27.1 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.1) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.27.1 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-member-expression-to-functions@7.25.9': + '@babel/helper-member-expression-to-functions@7.27.1': dependencies: - '@babel/traverse': 7.26.10 - '@babel/types': 7.26.10 + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/helper-module-imports@7.25.9': + '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.26.10 - '@babel/types': 7.26.10 + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.10)': + '@babel/helper-module-transforms@7.27.1(@babel/core@7.27.1)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-module-imports': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.26.10 + '@babel/core': 7.27.1 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/helper-optimise-call-expression@7.25.9': + '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.26.10 + '@babel/types': 7.27.1 - '@babel/helper-plugin-utils@7.26.5': {} + '@babel/helper-plugin-utils@7.27.1': {} - '@babel/helper-replace-supers@7.26.5(@babel/core@7.26.10)': + '@babel/helper-replace-supers@7.27.1(@babel/core@7.27.1)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-member-expression-to-functions': 7.25.9 - '@babel/helper-optimise-call-expression': 7.25.9 - '@babel/traverse': 7.26.10 + '@babel/core': 7.27.1 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/helper-skip-transparent-expression-wrappers@7.25.9': + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: - '@babel/traverse': 7.26.10 - '@babel/types': 7.26.10 + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/helper-string-parser@7.25.9': {} - '@babel/helper-string-parser@7.27.1': {} - '@babel/helper-validator-identifier@7.25.9': {} - '@babel/helper-validator-identifier@7.27.1': {} - '@babel/helper-validator-option@7.25.9': {} - - '@babel/helpers@7.26.10': - dependencies: - '@babel/template': 7.26.9 - '@babel/types': 7.26.10 - - '@babel/parser@7.26.10': - dependencies: - '@babel/types': 7.26.10 - - '@babel/parser@7.27.0': - dependencies: - '@babel/types': 7.27.0 - - '@babel/plugin-proposal-decorators@7.25.9(@babel/core@7.26.10)': - dependencies: - '@babel/core': 7.26.10 - '@babel/helper-create-class-features-plugin': 7.26.9(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-decorators': 7.25.9(@babel/core@7.26.10) - transitivePeerDependencies: - - supports-color - - '@babel/plugin-syntax-decorators@7.25.9(@babel/core@7.26.10)': - dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/helper-validator-option@7.27.1': {} - '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@7.26.10)': + '@babel/helpers@7.27.1': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/template': 7.27.2 + '@babel/types': 7.27.1 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.26.10)': + '@babel/parser@7.27.2': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/types': 7.27.1 - '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.27.1)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.1)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.27.1)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-jsx-source@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.27.1)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-typescript@7.26.8(@babel/core@7.26.10)': + '@babel/plugin-transform-typescript@7.27.1(@babel/core@7.27.1)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-create-class-features-plugin': 7.26.9(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.10) + '@babel/core': 7.27.1 + '@babel/helper-annotate-as-pure': 7.27.1 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.1) transitivePeerDependencies: - supports-color - '@babel/runtime@7.26.10': - dependencies: - regenerator-runtime: 0.14.1 + '@babel/runtime@7.27.1': {} - '@babel/template@7.26.9': + '@babel/template@7.27.2': dependencies: - '@babel/code-frame': 7.26.2 - '@babel/parser': 7.26.10 - '@babel/types': 7.26.10 + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 - '@babel/traverse@7.26.10': + '@babel/traverse@7.27.1': dependencies: - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.10 - '@babel/parser': 7.26.10 - '@babel/template': 7.26.9 - '@babel/types': 7.26.10 - debug: 4.4.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/template': 7.27.2 + '@babel/types': 7.27.1 + debug: 4.4.1 globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.26.10': - dependencies: - '@babel/helper-string-parser': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 - - '@babel/types@7.27.0': - dependencies: - '@babel/helper-string-parser': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 - '@babel/types@7.27.1': dependencies: '@babel/helper-string-parser': 7.27.1 @@ -10400,11 +8906,11 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} - '@changesets/apply-release-plan@7.0.10': + '@changesets/apply-release-plan@7.0.12': dependencies: '@changesets/config': 3.1.1 '@changesets/get-version-range-type': 0.4.0 - '@changesets/git': 3.0.2 + '@changesets/git': 3.0.4 '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 @@ -10414,16 +8920,16 @@ snapshots: outdent: 0.5.0 prettier: 2.8.8 resolve-from: 5.0.0 - semver: 7.7.1 + semver: 7.7.2 - '@changesets/assemble-release-plan@6.0.6': + '@changesets/assemble-release-plan@6.0.8': dependencies: '@changesets/errors': 0.2.0 '@changesets/get-dependents-graph': 2.1.3 '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 - semver: 7.7.1 + semver: 7.7.2 '@changesets/changelog-git@0.2.1': dependencies: @@ -10437,19 +8943,19 @@ snapshots: transitivePeerDependencies: - encoding - '@changesets/cli@2.28.1': + '@changesets/cli@2.29.4': dependencies: - '@changesets/apply-release-plan': 7.0.10 - '@changesets/assemble-release-plan': 6.0.6 + '@changesets/apply-release-plan': 7.0.12 + '@changesets/assemble-release-plan': 6.0.8 '@changesets/changelog-git': 0.2.1 '@changesets/config': 3.1.1 '@changesets/errors': 0.2.0 '@changesets/get-dependents-graph': 2.1.3 - '@changesets/get-release-plan': 4.0.8 - '@changesets/git': 3.0.2 + '@changesets/get-release-plan': 4.0.12 + '@changesets/git': 3.0.4 '@changesets/logger': 0.1.1 '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.3 + '@changesets/read': 0.6.5 '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@changesets/write': 0.4.0 @@ -10464,7 +8970,7 @@ snapshots: package-manager-detector: 0.2.11 picocolors: 1.1.1 resolve-from: 5.0.0 - semver: 7.7.1 + semver: 7.7.2 spawndamnit: 3.0.1 term-size: 2.2.1 @@ -10487,7 +8993,7 @@ snapshots: '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 picocolors: 1.1.1 - semver: 7.7.1 + semver: 7.7.2 '@changesets/get-github-info@0.6.0': dependencies: @@ -10496,18 +9002,18 @@ snapshots: transitivePeerDependencies: - encoding - '@changesets/get-release-plan@4.0.8': + '@changesets/get-release-plan@4.0.12': dependencies: - '@changesets/assemble-release-plan': 6.0.6 + '@changesets/assemble-release-plan': 6.0.8 '@changesets/config': 3.1.1 '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.3 + '@changesets/read': 0.6.5 '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 '@changesets/get-version-range-type@0.4.0': {} - '@changesets/git@3.0.2': + '@changesets/git@3.0.4': dependencies: '@changesets/errors': 0.2.0 '@manypkg/get-packages': 1.1.3 @@ -10531,9 +9037,9 @@ snapshots: '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 - '@changesets/read@0.6.3': + '@changesets/read@0.6.5': dependencies: - '@changesets/git': 3.0.2 + '@changesets/git': 3.0.4 '@changesets/logger': 0.1.1 '@changesets/parse': 0.4.1 '@changesets/types': 6.1.0 @@ -10574,19 +9080,22 @@ snapshots: '@colors/colors@1.6.0': {} - '@csstools/color-helpers@5.0.2': {} + '@csstools/color-helpers@5.0.2': + optional: true - '@csstools/css-calc@2.1.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': + '@csstools/css-calc@2.1.3(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': dependencies: '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) '@csstools/css-tokenizer': 3.0.3 + optional: true - '@csstools/css-color-parser@3.0.8(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': + '@csstools/css-color-parser@3.0.9(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': dependencies: '@csstools/color-helpers': 5.0.2 - '@csstools/css-calc': 2.1.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-calc': 2.1.3(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) '@csstools/css-tokenizer': 3.0.3 + optional: true '@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1)': dependencies: @@ -10595,10 +9104,12 @@ snapshots: '@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3)': dependencies: '@csstools/css-tokenizer': 3.0.3 + optional: true '@csstools/css-tokenizer@2.4.1': {} - '@csstools/css-tokenizer@3.0.3': {} + '@csstools/css-tokenizer@3.0.3': + optional: true '@csstools/media-query-list-parser@2.1.13(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1)': dependencies: @@ -10615,17 +9126,17 @@ snapshots: enabled: 2.0.0 kuler: 2.0.0 - '@dependents/detective-less@4.1.0': + '@dependents/detective-less@5.0.1': dependencies: gonzales-pe: 4.3.0 - node-source-walk: 6.0.2 + node-source-walk: 7.0.1 '@docsearch/css@3.8.2': {} - '@docsearch/js@3.8.2(@algolia/client-search@5.21.0)(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)': + '@docsearch/js@3.8.2(@algolia/client-search@5.25.0)(search-insights@2.17.3)': dependencies: - '@docsearch/react': 3.8.2(@algolia/client-search@5.21.0)(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3) - preact: 10.26.4 + '@docsearch/react': 3.8.2(@algolia/client-search@5.25.0)(search-insights@2.17.3) + preact: 10.26.7 transitivePeerDependencies: - '@algolia/client-search' - '@types/react' @@ -10633,438 +9144,220 @@ snapshots: - react-dom - search-insights - '@docsearch/react@3.8.2(@algolia/client-search@5.21.0)(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)': + '@docsearch/react@3.8.2(@algolia/client-search@5.25.0)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-core': 1.17.7(@algolia/client-search@5.21.0)(algoliasearch@5.21.0)(search-insights@2.17.3) - '@algolia/autocomplete-preset-algolia': 1.17.7(@algolia/client-search@5.21.0)(algoliasearch@5.21.0) + '@algolia/autocomplete-core': 1.17.7(@algolia/client-search@5.25.0)(algoliasearch@5.25.0)(search-insights@2.17.3) + '@algolia/autocomplete-preset-algolia': 1.17.7(@algolia/client-search@5.25.0)(algoliasearch@5.25.0) '@docsearch/css': 3.8.2 - algoliasearch: 5.21.0 + algoliasearch: 5.25.0 optionalDependencies: - '@types/react': 18.3.18 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) search-insights: 2.17.3 transitivePeerDependencies: - '@algolia/client-search' - '@emnapi/core@1.4.0': + '@emnapi/core@1.4.3': dependencies: - '@emnapi/wasi-threads': 1.0.1 + '@emnapi/wasi-threads': 1.0.2 tslib: 2.8.1 - optional: true - '@emnapi/runtime@1.4.0': + '@emnapi/runtime@1.4.3': dependencies: tslib: 2.8.1 - optional: true - '@emnapi/wasi-threads@1.0.1': + '@emnapi/wasi-threads@1.0.2': dependencies: tslib: 2.8.1 - optional: true - '@emotion/babel-plugin@11.13.5': + '@es-joy/jsdoccomment@0.50.2': dependencies: - '@babel/helper-module-imports': 7.25.9 - '@babel/runtime': 7.26.10 - '@emotion/hash': 0.9.2 - '@emotion/memoize': 0.9.0 - '@emotion/serialize': 1.3.3 - babel-plugin-macros: 3.1.0 - convert-source-map: 1.9.0 - escape-string-regexp: 4.0.0 - find-root: 1.1.0 - source-map: 0.5.7 - stylis: 4.2.0 - transitivePeerDependencies: - - supports-color + '@types/estree': 1.0.7 + '@typescript-eslint/types': 8.32.1 + comment-parser: 1.4.1 + esquery: 1.6.0 + jsdoc-type-pratt-parser: 4.1.0 - '@emotion/cache@11.14.0': - dependencies: - '@emotion/memoize': 0.9.0 - '@emotion/sheet': 1.4.0 - '@emotion/utils': 1.4.2 - '@emotion/weak-memoize': 0.4.0 - stylis: 4.2.0 + '@esbuild/aix-ppc64@0.21.5': + optional: true - '@emotion/hash@0.9.2': {} + '@esbuild/aix-ppc64@0.25.4': + optional: true - '@emotion/is-prop-valid@1.3.1': - dependencies: - '@emotion/memoize': 0.9.0 + '@esbuild/android-arm64@0.21.5': + optional: true - '@emotion/memoize@0.9.0': {} - - '@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1)': - dependencies: - '@babel/runtime': 7.26.10 - '@emotion/babel-plugin': 11.13.5 - '@emotion/cache': 11.14.0 - '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@18.3.1) - '@emotion/utils': 1.4.2 - '@emotion/weak-memoize': 0.4.0 - hoist-non-react-statics: 3.3.2 - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.18 - transitivePeerDependencies: - - supports-color - - '@emotion/serialize@1.3.3': - dependencies: - '@emotion/hash': 0.9.2 - '@emotion/memoize': 0.9.0 - '@emotion/unitless': 0.10.0 - '@emotion/utils': 1.4.2 - csstype: 3.1.3 - - '@emotion/sheet@1.4.0': {} - - '@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1)': - dependencies: - '@babel/runtime': 7.26.10 - '@emotion/babel-plugin': 11.13.5 - '@emotion/is-prop-valid': 1.3.1 - '@emotion/react': 11.14.0(@types/react@18.3.18)(react@18.3.1) - '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@18.3.1) - '@emotion/utils': 1.4.2 - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.18 - transitivePeerDependencies: - - supports-color - - '@emotion/unitless@0.10.0': {} - - '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@18.3.1)': - dependencies: - react: 18.3.1 - - '@emotion/utils@1.4.2': {} - - '@emotion/weak-memoize@0.4.0': {} - - '@es-joy/jsdoccomment@0.49.0': - dependencies: - comment-parser: 1.4.1 - esquery: 1.6.0 - jsdoc-type-pratt-parser: 4.1.0 - - '@esbuild/aix-ppc64@0.21.5': - optional: true - - '@esbuild/aix-ppc64@0.25.1': - optional: true - - '@esbuild/aix-ppc64@0.25.2': - optional: true - - '@esbuild/aix-ppc64@0.25.4': - optional: true - - '@esbuild/android-arm64@0.21.5': - optional: true - - '@esbuild/android-arm64@0.25.1': - optional: true - - '@esbuild/android-arm64@0.25.2': - optional: true - - '@esbuild/android-arm64@0.25.4': - optional: true + '@esbuild/android-arm64@0.25.4': + optional: true '@esbuild/android-arm@0.21.5': optional: true - '@esbuild/android-arm@0.25.1': - optional: true - - '@esbuild/android-arm@0.25.2': - optional: true - '@esbuild/android-arm@0.25.4': optional: true '@esbuild/android-x64@0.21.5': optional: true - '@esbuild/android-x64@0.25.1': - optional: true - - '@esbuild/android-x64@0.25.2': - optional: true - '@esbuild/android-x64@0.25.4': optional: true '@esbuild/darwin-arm64@0.21.5': optional: true - '@esbuild/darwin-arm64@0.25.1': - optional: true - - '@esbuild/darwin-arm64@0.25.2': - optional: true - '@esbuild/darwin-arm64@0.25.4': optional: true '@esbuild/darwin-x64@0.21.5': optional: true - '@esbuild/darwin-x64@0.25.1': - optional: true - - '@esbuild/darwin-x64@0.25.2': - optional: true - '@esbuild/darwin-x64@0.25.4': optional: true '@esbuild/freebsd-arm64@0.21.5': optional: true - '@esbuild/freebsd-arm64@0.25.1': - optional: true - - '@esbuild/freebsd-arm64@0.25.2': - optional: true - '@esbuild/freebsd-arm64@0.25.4': optional: true '@esbuild/freebsd-x64@0.21.5': optional: true - '@esbuild/freebsd-x64@0.25.1': - optional: true - - '@esbuild/freebsd-x64@0.25.2': - optional: true - '@esbuild/freebsd-x64@0.25.4': optional: true '@esbuild/linux-arm64@0.21.5': optional: true - '@esbuild/linux-arm64@0.25.1': - optional: true - - '@esbuild/linux-arm64@0.25.2': - optional: true - '@esbuild/linux-arm64@0.25.4': optional: true '@esbuild/linux-arm@0.21.5': optional: true - '@esbuild/linux-arm@0.25.1': - optional: true - - '@esbuild/linux-arm@0.25.2': - optional: true - '@esbuild/linux-arm@0.25.4': optional: true '@esbuild/linux-ia32@0.21.5': optional: true - '@esbuild/linux-ia32@0.25.1': - optional: true - - '@esbuild/linux-ia32@0.25.2': - optional: true - '@esbuild/linux-ia32@0.25.4': optional: true '@esbuild/linux-loong64@0.21.5': optional: true - '@esbuild/linux-loong64@0.25.1': - optional: true - - '@esbuild/linux-loong64@0.25.2': - optional: true - '@esbuild/linux-loong64@0.25.4': optional: true '@esbuild/linux-mips64el@0.21.5': optional: true - '@esbuild/linux-mips64el@0.25.1': - optional: true - - '@esbuild/linux-mips64el@0.25.2': - optional: true - '@esbuild/linux-mips64el@0.25.4': optional: true '@esbuild/linux-ppc64@0.21.5': optional: true - '@esbuild/linux-ppc64@0.25.1': - optional: true - - '@esbuild/linux-ppc64@0.25.2': - optional: true - '@esbuild/linux-ppc64@0.25.4': optional: true '@esbuild/linux-riscv64@0.21.5': optional: true - '@esbuild/linux-riscv64@0.25.1': - optional: true - - '@esbuild/linux-riscv64@0.25.2': - optional: true - '@esbuild/linux-riscv64@0.25.4': optional: true '@esbuild/linux-s390x@0.21.5': optional: true - '@esbuild/linux-s390x@0.25.1': - optional: true - - '@esbuild/linux-s390x@0.25.2': - optional: true - '@esbuild/linux-s390x@0.25.4': optional: true '@esbuild/linux-x64@0.21.5': optional: true - '@esbuild/linux-x64@0.25.1': - optional: true - - '@esbuild/linux-x64@0.25.2': - optional: true - '@esbuild/linux-x64@0.25.4': optional: true - '@esbuild/netbsd-arm64@0.25.1': - optional: true - - '@esbuild/netbsd-arm64@0.25.2': - optional: true - '@esbuild/netbsd-arm64@0.25.4': optional: true '@esbuild/netbsd-x64@0.21.5': optional: true - '@esbuild/netbsd-x64@0.25.1': - optional: true - - '@esbuild/netbsd-x64@0.25.2': - optional: true - '@esbuild/netbsd-x64@0.25.4': optional: true - '@esbuild/openbsd-arm64@0.25.1': - optional: true - - '@esbuild/openbsd-arm64@0.25.2': - optional: true - '@esbuild/openbsd-arm64@0.25.4': optional: true '@esbuild/openbsd-x64@0.21.5': optional: true - '@esbuild/openbsd-x64@0.25.1': - optional: true - - '@esbuild/openbsd-x64@0.25.2': - optional: true - '@esbuild/openbsd-x64@0.25.4': optional: true '@esbuild/sunos-x64@0.21.5': optional: true - '@esbuild/sunos-x64@0.25.1': - optional: true - - '@esbuild/sunos-x64@0.25.2': - optional: true - '@esbuild/sunos-x64@0.25.4': optional: true '@esbuild/win32-arm64@0.21.5': optional: true - '@esbuild/win32-arm64@0.25.1': - optional: true - - '@esbuild/win32-arm64@0.25.2': - optional: true - '@esbuild/win32-arm64@0.25.4': optional: true '@esbuild/win32-ia32@0.21.5': optional: true - '@esbuild/win32-ia32@0.25.1': - optional: true - - '@esbuild/win32-ia32@0.25.2': - optional: true - '@esbuild/win32-ia32@0.25.4': optional: true '@esbuild/win32-x64@0.21.5': optional: true - '@esbuild/win32-x64@0.25.1': - optional: true - - '@esbuild/win32-x64@0.25.2': - optional: true - '@esbuild/win32-x64@0.25.4': optional: true - '@eslint-community/eslint-utils@4.5.1(eslint@8.57.1)': + '@eslint-community/eslint-utils@4.7.0(eslint@8.57.0)': dependencies: - eslint: 8.57.1 + eslint: 8.57.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/eslint-utils@4.7.0(eslint@9.28.0(jiti@2.4.2))': + dependencies: + eslint: 9.28.0(jiti@2.4.2) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} - '@eslint/compat@1.2.8(eslint@8.57.1)': + '@eslint/compat@1.2.9(eslint@8.57.0)': optionalDependencies: - eslint: 8.57.1 + eslint: 8.57.0 + + '@eslint/config-array@0.20.0': + dependencies: + '@eslint/object-schema': 2.1.6 + debug: 4.4.1 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.2.2': {} '@eslint/core@0.13.0': dependencies: '@types/json-schema': 7.0.15 + '@eslint/core@0.14.0': + dependencies: + '@types/json-schema': 7.0.15 + '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 - debug: 4.4.0 + debug: 4.4.1 espree: 9.6.1 globals: 13.24.0 ignore: 5.3.2 @@ -11075,23 +9368,51 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@8.57.1': {} + '@eslint/eslintrc@3.3.1': + dependencies: + ajv: 6.12.6 + debug: 4.4.1 + espree: 10.3.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.0': {} + + '@eslint/js@9.27.0': {} - '@eslint/js@9.22.0': {} + '@eslint/js@9.28.0': {} - '@eslint/js@9.24.0': {} + '@eslint/object-schema@2.1.6': {} '@eslint/plugin-kit@0.2.8': dependencies: '@eslint/core': 0.13.0 levn: 0.4.1 + '@eslint/plugin-kit@0.3.1': + dependencies: + '@eslint/core': 0.14.0 + levn: 0.4.1 + '@fastify/busboy@3.1.1': {} - '@humanwhocodes/config-array@0.13.0': + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.6': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 + + '@humanwhocodes/config-array@0.11.14': dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.4.0 + debug: 4.4.1 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -11100,12 +9421,97 @@ snapshots: '@humanwhocodes/object-schema@2.0.3': {} - '@iconify-json/simple-icons@1.2.28': + '@humanwhocodes/retry@0.3.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@iconify-json/simple-icons@1.2.35': dependencies: '@iconify/types': 2.0.0 '@iconify/types@2.0.0': {} + '@img/sharp-darwin-arm64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.1.0 + optional: true + + '@img/sharp-darwin-x64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.1.0 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.1.0': + optional: true + + '@img/sharp-libvips-darwin-x64@1.1.0': + optional: true + + '@img/sharp-libvips-linux-arm64@1.1.0': + optional: true + + '@img/sharp-libvips-linux-arm@1.1.0': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.1.0': + optional: true + + '@img/sharp-libvips-linux-s390x@1.1.0': + optional: true + + '@img/sharp-libvips-linux-x64@1.1.0': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.1.0': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.1.0': + optional: true + + '@img/sharp-linux-arm64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.1.0 + optional: true + + '@img/sharp-linux-arm@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.1.0 + optional: true + + '@img/sharp-linux-s390x@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.1.0 + optional: true + + '@img/sharp-linux-x64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.1.0 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + optional: true + + '@img/sharp-wasm32@0.34.2': + dependencies: + '@emnapi/runtime': 1.4.3 + optional: true + + '@img/sharp-win32-arm64@0.34.2': + optional: true + + '@img/sharp-win32-ia32@0.34.2': + optional: true + + '@img/sharp-win32-x64@0.34.2': + optional: true + '@ioredis/commands@1.2.0': {} '@isaacs/cliui@8.0.2': @@ -11149,9 +9555,11 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@jspm/core@2.1.0': {} + '@kwsites/file-exists@1.1.1': dependencies: - debug: 4.4.0 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -11159,43 +9567,28 @@ snapshots: '@manypkg/find-root@1.1.0': dependencies: - '@babel/runtime': 7.26.10 + '@babel/runtime': 7.27.1 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 '@manypkg/get-packages@1.1.3': dependencies: - '@babel/runtime': 7.26.10 + '@babel/runtime': 7.27.1 '@changesets/types': 4.1.0 '@manypkg/find-root': 1.1.0 fs-extra: 8.1.0 globby: 11.1.0 read-yaml-file: 1.1.0 - '@mapbox/node-pre-gyp@1.0.11': - dependencies: - detect-libc: 2.0.3 - https-proxy-agent: 5.0.1 - make-dir: 3.1.0 - node-fetch: 2.7.0 - nopt: 5.0.0 - npmlog: 5.0.1 - rimraf: 3.0.2 - semver: 7.7.2 - tar: 6.2.1 - transitivePeerDependencies: - - encoding - - supports-color - '@mapbox/node-pre-gyp@2.0.0': dependencies: consola: 3.4.2 - detect-libc: 2.0.3 + detect-libc: 2.0.4 https-proxy-agent: 7.0.6 node-fetch: 2.7.0 nopt: 8.1.0 - semver: 7.7.1 + semver: 7.7.2 tar: 7.4.3 transitivePeerDependencies: - encoding @@ -11210,158 +9603,27 @@ snapshots: '@microsoft/tsdoc@0.14.2': {} - '@mui/base@5.0.0-alpha.108(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@babel/runtime': 7.26.10 - '@emotion/is-prop-valid': 1.3.1 - '@mui/types': 7.2.21(@types/react@18.3.18) - '@mui/utils': 5.16.14(@types/react@18.3.18)(react@18.3.1) - '@popperjs/core': 2.11.8 - clsx: 1.2.1 - prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-is: 18.3.1 - optionalDependencies: - '@types/react': 18.3.18 - - '@mui/core-downloads-tracker@5.16.14': {} - - '@mui/icons-material@5.16.14(@mui/material@5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.18)(react@18.3.1)': - dependencies: - '@babel/runtime': 7.26.10 - '@mui/material': 5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.18 - - '@mui/lab@5.0.0-alpha.110(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@mui/material@5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@napi-rs/wasm-runtime@0.2.10': dependencies: - '@babel/runtime': 7.26.10 - '@mui/base': 5.0.0-alpha.108(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/material': 5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': 5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1) - '@mui/types': 7.2.21(@types/react@18.3.18) - '@mui/utils': 5.16.14(@types/react@18.3.18)(react@18.3.1) - clsx: 1.2.1 - prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-is: 18.3.1 - optionalDependencies: - '@emotion/react': 11.14.0(@types/react@18.3.18)(react@18.3.1) - '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1) - '@types/react': 18.3.18 - - '@mui/material@5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@babel/runtime': 7.26.10 - '@mui/core-downloads-tracker': 5.16.14 - '@mui/system': 5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1) - '@mui/types': 7.2.21(@types/react@18.3.18) - '@mui/utils': 5.16.14(@types/react@18.3.18)(react@18.3.1) - '@popperjs/core': 2.11.8 - '@types/react-transition-group': 4.4.12(@types/react@18.3.18) - clsx: 2.1.1 - csstype: 3.1.3 - prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-is: 19.0.0 - react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - optionalDependencies: - '@emotion/react': 11.14.0(@types/react@18.3.18)(react@18.3.1) - '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1) - '@types/react': 18.3.18 - - '@mui/private-theming@5.16.14(@types/react@18.3.18)(react@18.3.1)': - dependencies: - '@babel/runtime': 7.26.10 - '@mui/utils': 5.16.14(@types/react@18.3.18)(react@18.3.1) - prop-types: 15.8.1 - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.18 - - '@mui/styled-engine@5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(react@18.3.1)': - dependencies: - '@babel/runtime': 7.26.10 - '@emotion/cache': 11.14.0 - csstype: 3.1.3 - prop-types: 15.8.1 - react: 18.3.1 - optionalDependencies: - '@emotion/react': 11.14.0(@types/react@18.3.18)(react@18.3.1) - '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1) - - '@mui/system@5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1)': - dependencies: - '@babel/runtime': 7.26.10 - '@mui/private-theming': 5.16.14(@types/react@18.3.18)(react@18.3.1) - '@mui/styled-engine': 5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(react@18.3.1) - '@mui/types': 7.2.21(@types/react@18.3.18) - '@mui/utils': 5.16.14(@types/react@18.3.18)(react@18.3.1) - clsx: 2.1.1 - csstype: 3.1.3 - prop-types: 15.8.1 - react: 18.3.1 - optionalDependencies: - '@emotion/react': 11.14.0(@types/react@18.3.18)(react@18.3.1) - '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1) - '@types/react': 18.3.18 - - '@mui/types@7.2.21(@types/react@18.3.18)': - optionalDependencies: - '@types/react': 18.3.18 - - '@mui/utils@5.16.14(@types/react@18.3.18)(react@18.3.1)': - dependencies: - '@babel/runtime': 7.26.10 - '@mui/types': 7.2.21(@types/react@18.3.18) - '@types/prop-types': 15.7.14 - clsx: 2.1.1 - prop-types: 15.8.1 - react: 18.3.1 - react-is: 19.0.0 - optionalDependencies: - '@types/react': 18.3.18 - - '@mui/x-data-grid@6.20.4(@mui/material@5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@babel/runtime': 7.26.10 - '@mui/material': 5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': 5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1) - '@mui/utils': 5.16.14(@types/react@18.3.18)(react@18.3.1) - clsx: 2.1.1 - prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - reselect: 4.1.8 - transitivePeerDependencies: - - '@types/react' - - '@napi-rs/wasm-runtime@0.2.8': - dependencies: - '@emnapi/core': 1.4.0 - '@emnapi/runtime': 1.4.0 + '@emnapi/core': 1.4.3 + '@emnapi/runtime': 1.4.3 '@tybys/wasm-util': 0.9.0 optional: true - '@napi-rs/wasm-runtime@0.2.9': + '@napi-rs/wasm-runtime@0.2.4': dependencies: - '@emnapi/core': 1.4.0 - '@emnapi/runtime': 1.4.0 + '@emnapi/core': 1.4.3 + '@emnapi/runtime': 1.4.3 '@tybys/wasm-util': 0.9.0 - optional: true '@netlify/binary-info@1.0.0': {} - '@netlify/blobs@9.1.1': + '@netlify/blobs@9.1.2': dependencies: - '@netlify/dev-utils': 2.1.1 + '@netlify/dev-utils': 2.2.0 '@netlify/runtime-utils': 1.3.1 - '@netlify/dev-utils@2.1.1': + '@netlify/dev-utils@2.2.0': dependencies: '@whatwg-node/server': 0.9.71 chokidar: 4.0.3 @@ -11375,16 +9637,12 @@ snapshots: uuid: 11.1.0 write-file-atomic: 6.0.0 - '@netlify/functions@3.0.4': + '@netlify/functions@3.1.9(rollup@4.40.2)': dependencies: - '@netlify/serverless-functions-api': 1.36.0 - - '@netlify/functions@3.1.8(rollup@4.40.2)': - dependencies: - '@netlify/blobs': 9.1.1 - '@netlify/dev-utils': 2.1.1 - '@netlify/serverless-functions-api': 1.41.1 - '@netlify/zip-it-and-ship-it': 10.1.1(rollup@4.40.2) + '@netlify/blobs': 9.1.2 + '@netlify/dev-utils': 2.2.0 + '@netlify/serverless-functions-api': 1.41.2 + '@netlify/zip-it-and-ship-it': 12.1.0(rollup@4.40.2) cron-parser: 4.9.0 decache: 4.6.2 extract-zip: 2.0.1 @@ -11402,26 +9660,24 @@ snapshots: '@netlify/runtime-utils@1.3.1': {} - '@netlify/serverless-functions-api@1.36.0': {} - - '@netlify/serverless-functions-api@1.41.1': {} + '@netlify/serverless-functions-api@1.41.2': {} - '@netlify/zip-it-and-ship-it@10.1.1(rollup@4.40.2)': + '@netlify/zip-it-and-ship-it@12.1.0(rollup@4.40.2)': dependencies: - '@babel/parser': 7.27.0 + '@babel/parser': 7.27.2 '@babel/types': 7.27.1 '@netlify/binary-info': 1.0.0 - '@netlify/serverless-functions-api': 1.41.1 - '@vercel/nft': 0.27.7(rollup@4.40.2) - archiver: 5.3.2 + '@netlify/serverless-functions-api': 1.41.2 + '@vercel/nft': 0.29.3(rollup@4.40.2) + archiver: 7.0.1 common-path-prefix: 3.0.0 - cp-file: 10.0.0 - es-module-lexer: 1.6.0 + copy-file: 11.0.0 + es-module-lexer: 1.7.0 esbuild: 0.25.4 - execa: 7.2.0 + execa: 8.0.1 fast-glob: 3.3.3 - filter-obj: 5.1.0 - find-up: 6.3.0 + filter-obj: 6.1.0 + find-up: 7.0.0 glob: 8.1.0 is-builtin-module: 3.2.1 is-path-inside: 4.0.0 @@ -11432,7 +9688,7 @@ snapshots: normalize-path: 3.0.0 p-map: 7.0.3 path-exists: 5.0.0 - precinct: 11.0.5 + precinct: 12.2.0 require-package-name: 2.0.1 resolve: 2.0.0-next.5 semver: 7.7.2 @@ -11441,16 +9697,46 @@ snapshots: unixify: 1.0.0 urlpattern-polyfill: 8.0.2 yargs: 17.7.2 - zod: 3.24.4 + zod: 3.25.28 transitivePeerDependencies: - encoding - rollup - supports-color - '@next/eslint-plugin-next@13.5.8': + '@next/env@15.3.2': {} + + '@next/eslint-plugin-next@13.5.11': dependencies: glob: 7.1.7 + '@next/eslint-plugin-next@15.3.2': + dependencies: + fast-glob: 3.3.1 + + '@next/swc-darwin-arm64@15.3.2': + optional: true + + '@next/swc-darwin-x64@15.3.2': + optional: true + + '@next/swc-linux-arm64-gnu@15.3.2': + optional: true + + '@next/swc-linux-arm64-musl@15.3.2': + optional: true + + '@next/swc-linux-x64-gnu@15.3.2': + optional: true + + '@next/swc-linux-x64-musl@15.3.2': + optional: true + + '@next/swc-win32-arm64-msvc@15.3.2': + optional: true + + '@next/swc-win32-x64-msvc@15.3.2': + optional: true + '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': dependencies: eslint-scope: 5.1.1 @@ -11467,47 +9753,11 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@nrwl/tao@18.2.4': - dependencies: - nx: 18.2.4 - tslib: 2.8.1 - transitivePeerDependencies: - - '@swc-node/register' - - '@swc/core' - - debug - - '@nuxt/cli@3.24.1(magicast@0.3.5)': - dependencies: - c12: 3.0.3(magicast@0.3.5) - chokidar: 4.0.3 - citty: 0.1.6 - clipboardy: 4.0.0 - consola: 3.4.2 - defu: 6.1.4 - fuse.js: 7.1.0 - giget: 2.0.0 - h3: 1.15.1 - httpxy: 0.1.7 - jiti: 2.4.2 - listhen: 1.9.0 - nypm: 0.6.0 - ofetch: 1.4.1 - ohash: 2.0.11 - pathe: 2.0.3 - perfect-debounce: 1.0.0 - pkg-types: 2.1.0 - scule: 1.3.0 - semver: 7.7.1 - std-env: 3.8.1 - tinyexec: 1.0.1 - ufo: 1.5.4 - youch: 4.1.0-beta.6 - transitivePeerDependencies: - - magicast + '@nolyfill/is-core-module@1.0.39': {} '@nuxt/cli@3.25.1(magicast@0.3.5)': dependencies: - c12: 3.0.3(magicast@0.3.5) + c12: 3.0.4(magicast@0.3.5) chokidar: 4.0.3 citty: 0.1.6 clipboardy: 4.0.0 @@ -11526,7 +9776,7 @@ snapshots: perfect-debounce: 1.0.0 pkg-types: 2.1.0 scule: 1.3.0 - semver: 7.7.1 + semver: 7.7.2 std-env: 3.9.0 tinyexec: 1.0.1 ufo: 1.6.1 @@ -11536,25 +9786,16 @@ snapshots: '@nuxt/devalue@2.0.2': {} - '@nuxt/devtools-kit@2.4.0(magicast@0.3.5)(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))': - dependencies: - '@nuxt/kit': 3.16.2(magicast@0.3.5) - '@nuxt/schema': 3.16.2 - execa: 8.0.1 - vite: 6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - transitivePeerDependencies: - - magicast - - '@nuxt/devtools-kit@2.4.0(magicast@0.3.5)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))': + '@nuxt/devtools-kit@2.4.1(magicast@0.3.5)(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))': dependencies: - '@nuxt/kit': 3.16.2(magicast@0.3.5) - '@nuxt/schema': 3.16.2 + '@nuxt/kit': 3.17.4(magicast@0.3.5) + '@nuxt/schema': 3.17.4 execa: 8.0.1 - vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) transitivePeerDependencies: - magicast - '@nuxt/devtools-wizard@2.4.0': + '@nuxt/devtools-wizard@2.4.1': dependencies: consola: 3.4.2 diff: 7.0.0 @@ -11563,62 +9804,21 @@ snapshots: pathe: 2.0.3 pkg-types: 2.1.0 prompts: 2.4.2 - semver: 7.7.1 - - '@nuxt/devtools@2.4.0(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': - dependencies: - '@nuxt/devtools-kit': 2.4.0(magicast@0.3.5)(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) - '@nuxt/devtools-wizard': 2.4.0 - '@nuxt/kit': 3.16.2(magicast@0.3.5) - '@vue/devtools-core': 7.7.2(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) - '@vue/devtools-kit': 7.7.2 - birpc: 2.3.0 - consola: 3.4.2 - destr: 2.0.5 - error-stack-parser-es: 1.0.5 - execa: 8.0.1 - fast-npm-meta: 0.4.2 - get-port-please: 3.1.2 - hookable: 5.5.3 - image-meta: 0.2.1 - is-installed-globally: 1.0.0 - launch-editor: 2.10.0 - local-pkg: 1.1.1 - magicast: 0.3.5 - nypm: 0.6.0 - ohash: 2.0.11 - pathe: 2.0.3 - perfect-debounce: 1.0.0 - pkg-types: 2.1.0 - semver: 7.7.1 - simple-git: 3.27.0 - sirv: 3.0.1 - structured-clone-es: 1.0.0 - tinyglobby: 0.2.12 - vite: 6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vite-plugin-inspect: 11.0.0(@nuxt/kit@3.16.2(magicast@0.3.5))(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) - vite-plugin-vue-tracer: 0.1.3(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) - which: 5.0.0 - ws: 8.18.1 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - vue + semver: 7.7.2 - '@nuxt/devtools@2.4.0(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': + '@nuxt/devtools@2.4.1(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3))': dependencies: - '@nuxt/devtools-kit': 2.4.0(magicast@0.3.5)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) - '@nuxt/devtools-wizard': 2.4.0 - '@nuxt/kit': 3.16.2(magicast@0.3.5) - '@vue/devtools-core': 7.7.2(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) - '@vue/devtools-kit': 7.7.2 + '@nuxt/devtools-kit': 2.4.1(magicast@0.3.5)(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0)) + '@nuxt/devtools-wizard': 2.4.1 + '@nuxt/kit': 3.17.4(magicast@0.3.5) + '@vue/devtools-core': 7.7.6(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3)) + '@vue/devtools-kit': 7.7.6 birpc: 2.3.0 consola: 3.4.2 destr: 2.0.5 error-stack-parser-es: 1.0.5 execa: 8.0.1 - fast-npm-meta: 0.4.2 + fast-npm-meta: 0.4.3 get-port-please: 3.1.2 hookable: 5.5.3 image-meta: 0.2.1 @@ -11631,89 +9831,62 @@ snapshots: pathe: 2.0.3 perfect-debounce: 1.0.0 pkg-types: 2.1.0 - semver: 7.7.1 + semver: 7.7.2 simple-git: 3.27.0 sirv: 3.0.1 structured-clone-es: 1.0.0 - tinyglobby: 0.2.12 - vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vite-plugin-inspect: 11.0.0(@nuxt/kit@3.16.2(magicast@0.3.5))(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) - vite-plugin-vue-tracer: 0.1.3(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) + tinyglobby: 0.2.13 + vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + vite-plugin-inspect: 11.1.0(@nuxt/kit@3.17.4(magicast@0.3.5))(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0)) + vite-plugin-vue-tracer: 0.1.3(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3)) which: 5.0.0 - ws: 8.18.1 + ws: 8.18.2 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - vue - '@nuxt/eslint-config@1.3.0(@vue/compiler-sfc@3.5.13)(eslint@8.57.1)(typescript@5.8.3)': + '@nuxt/eslint-config@1.4.1(@vue/compiler-sfc@3.5.14)(eslint@8.57.0)(typescript@5.8.3)': dependencies: - '@antfu/install-pkg': 1.0.0 + '@antfu/install-pkg': 1.1.0 '@clack/prompts': 0.10.1 - '@eslint/js': 9.24.0 - '@nuxt/eslint-plugin': 1.3.0(eslint@8.57.1)(typescript@5.8.3) - '@stylistic/eslint-plugin': 4.2.0(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/eslint-plugin': 8.30.1(@typescript-eslint/parser@8.30.1(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/parser': 8.30.1(eslint@8.57.1)(typescript@5.8.3) - eslint: 8.57.1 - eslint-config-flat-gitignore: 2.1.0(eslint@8.57.1) - eslint-flat-config-utils: 2.0.1 - eslint-merge-processors: 2.0.0(eslint@8.57.1) - eslint-plugin-import-x: 4.10.5(eslint@8.57.1)(typescript@5.8.3) - eslint-plugin-jsdoc: 50.6.9(eslint@8.57.1) - eslint-plugin-regexp: 2.7.0(eslint@8.57.1) - eslint-plugin-unicorn: 58.0.0(eslint@8.57.1) - eslint-plugin-vue: 10.0.0(eslint@8.57.1)(vue-eslint-parser@10.1.1(eslint@8.57.1)) - eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.13)(eslint@8.57.1) - globals: 16.0.0 - local-pkg: 1.1.1 - pathe: 2.0.3 - vue-eslint-parser: 10.1.1(eslint@8.57.1) - transitivePeerDependencies: - - '@vue/compiler-sfc' - - supports-color - - typescript - - '@nuxt/eslint-plugin@1.3.0(eslint@8.57.1)(typescript@5.8.3)': - dependencies: - '@typescript-eslint/types': 8.30.1 - '@typescript-eslint/utils': 8.30.1(eslint@8.57.1)(typescript@5.8.3) - eslint: 8.57.1 - transitivePeerDependencies: - - supports-color - - typescript - - '@nuxt/kit@3.16.2(magicast@0.3.5)': - dependencies: - c12: 3.0.3(magicast@0.3.5) - consola: 3.4.2 - defu: 6.1.4 - destr: 2.0.5 - errx: 0.1.0 - exsolve: 1.0.4 - globby: 14.1.0 - ignore: 7.0.3 - jiti: 2.4.2 - klona: 2.0.6 - knitwork: 1.2.0 - mlly: 1.7.4 - ohash: 2.0.11 - pathe: 2.0.3 - pkg-types: 2.1.0 - scule: 1.3.0 - semver: 7.7.1 - std-env: 3.8.1 - ufo: 1.5.4 - unctx: 2.4.1 - unimport: 4.1.3 - untyped: 2.0.0 + '@eslint/js': 9.27.0 + '@nuxt/eslint-plugin': 1.4.1(eslint@8.57.0)(typescript@5.8.3) + '@stylistic/eslint-plugin': 4.4.0(eslint@8.57.0)(typescript@5.8.3) + '@typescript-eslint/eslint-plugin': 8.32.1(@typescript-eslint/parser@8.32.1(eslint@8.57.0)(typescript@5.8.3))(eslint@8.57.0)(typescript@5.8.3) + '@typescript-eslint/parser': 8.32.1(eslint@8.57.0)(typescript@5.8.3) + eslint: 8.57.0 + eslint-config-flat-gitignore: 2.1.0(eslint@8.57.0) + eslint-flat-config-utils: 2.1.0 + eslint-merge-processors: 2.0.0(eslint@8.57.0) + eslint-plugin-import-x: 4.12.2(eslint@8.57.0)(typescript@5.8.3) + eslint-plugin-jsdoc: 50.6.17(eslint@8.57.0) + eslint-plugin-regexp: 2.7.0(eslint@8.57.0) + eslint-plugin-unicorn: 59.0.1(eslint@8.57.0) + eslint-plugin-vue: 10.1.0(eslint@8.57.0)(vue-eslint-parser@10.1.3(eslint@8.57.0)) + eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.14)(eslint@8.57.0) + globals: 16.1.0 + local-pkg: 1.1.1 + pathe: 2.0.3 + vue-eslint-parser: 10.1.3(eslint@8.57.0) transitivePeerDependencies: - - magicast + - '@vue/compiler-sfc' + - supports-color + - typescript + + '@nuxt/eslint-plugin@1.4.1(eslint@8.57.0)(typescript@5.8.3)': + dependencies: + '@typescript-eslint/types': 8.32.1 + '@typescript-eslint/utils': 8.32.1(eslint@8.57.0)(typescript@5.8.3) + eslint: 8.57.0 + transitivePeerDependencies: + - supports-color + - typescript - '@nuxt/kit@3.17.3(magicast@0.3.5)': + '@nuxt/kit@3.17.4(magicast@0.3.5)': dependencies: - c12: 3.0.3(magicast@0.3.5) + c12: 3.0.4(magicast@0.3.5) consola: 3.4.2 defu: 6.1.4 destr: 2.0.5 @@ -11728,7 +9901,7 @@ snapshots: pathe: 2.0.3 pkg-types: 2.1.0 scule: 1.3.0 - semver: 7.7.1 + semver: 7.7.2 std-env: 3.9.0 tinyglobby: 0.2.13 ufo: 1.6.1 @@ -11738,7 +9911,7 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/module-builder@1.0.1(@nuxt/cli@3.25.1(magicast@0.3.5))(esbuild@0.25.4)(sass@1.85.1)(typescript@5.8.3)(vue-tsc@2.2.8(typescript@5.8.3))(vue@3.5.13(typescript@5.8.3))': + '@nuxt/module-builder@1.0.1(@nuxt/cli@3.25.1(magicast@0.3.5))(@vue/compiler-core@3.5.14)(esbuild@0.25.4)(sass@1.89.0)(typescript@5.8.3)(vue-tsc@2.2.10(typescript@5.8.3))(vue@3.5.14(typescript@5.8.3))': dependencies: '@nuxt/cli': 3.25.1(magicast@0.3.5) citty: 0.1.6 @@ -11746,30 +9919,24 @@ snapshots: defu: 6.1.4 jiti: 2.4.2 magic-regexp: 0.8.0 - mkdist: 2.3.0(sass@1.85.1)(typescript@5.8.3)(vue-sfc-transformer@0.1.11(esbuild@0.25.4)(vue@3.5.13(typescript@5.8.3)))(vue-tsc@2.2.8(typescript@5.8.3))(vue@3.5.13(typescript@5.8.3)) + mkdist: 2.3.0(sass@1.89.0)(typescript@5.8.3)(vue-sfc-transformer@0.1.16(@vue/compiler-core@3.5.14)(esbuild@0.25.4)(vue@3.5.14(typescript@5.8.3)))(vue-tsc@2.2.10(typescript@5.8.3))(vue@3.5.14(typescript@5.8.3)) mlly: 1.7.4 pathe: 2.0.3 pkg-types: 2.1.0 - tsconfck: 3.1.5(typescript@5.8.3) + tsconfck: 3.1.6(typescript@5.8.3) typescript: 5.8.3 - unbuild: 3.5.0(sass@1.85.1)(typescript@5.8.3)(vue-sfc-transformer@0.1.11(esbuild@0.25.4)(vue@3.5.13(typescript@5.8.3)))(vue-tsc@2.2.8(typescript@5.8.3))(vue@3.5.13(typescript@5.8.3)) - vue-sfc-transformer: 0.1.11(esbuild@0.25.4)(vue@3.5.13(typescript@5.8.3)) + unbuild: 3.5.0(sass@1.89.0)(typescript@5.8.3)(vue-sfc-transformer@0.1.16(@vue/compiler-core@3.5.14)(esbuild@0.25.4)(vue@3.5.14(typescript@5.8.3)))(vue-tsc@2.2.10(typescript@5.8.3))(vue@3.5.14(typescript@5.8.3)) + vue-sfc-transformer: 0.1.16(@vue/compiler-core@3.5.14)(esbuild@0.25.4)(vue@3.5.14(typescript@5.8.3)) transitivePeerDependencies: + - '@vue/compiler-core' - esbuild - sass - vue - vue-tsc - '@nuxt/schema@3.16.2': - dependencies: - consola: 3.4.2 - defu: 6.1.4 - pathe: 2.0.3 - std-env: 3.8.1 - - '@nuxt/schema@3.17.3': + '@nuxt/schema@3.17.4': dependencies: - '@vue/shared': 3.5.13 + '@vue/shared': 3.5.14 consola: 3.4.2 defu: 6.1.4 pathe: 2.0.3 @@ -11777,33 +9944,33 @@ snapshots: '@nuxt/telemetry@2.6.6(magicast@0.3.5)': dependencies: - '@nuxt/kit': 3.16.2(magicast@0.3.5) + '@nuxt/kit': 3.17.4(magicast@0.3.5) citty: 0.1.6 consola: 3.4.2 destr: 2.0.5 dotenv: 16.4.7 - git-url-parse: 16.0.1 + git-url-parse: 16.1.0 is-docker: 3.0.0 ofetch: 1.4.1 - package-manager-detector: 1.1.0 + package-manager-detector: 1.3.0 pathe: 2.0.3 rc9: 2.1.2 - std-env: 3.8.1 + std-env: 3.9.0 transitivePeerDependencies: - magicast - '@nuxt/test-utils@3.17.2(@types/node@22.14.1)(@vue/test-utils@2.4.6)(jiti@2.4.2)(jsdom@26.0.0)(magicast@0.3.5)(sass@1.85.1)(terser@5.39.0)(typescript@5.8.3)(vitest@3.1.1(@types/node@22.14.1)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(yaml@2.7.1)': + '@nuxt/test-utils@3.19.0(@types/node@22.15.29)(@vue/test-utils@2.4.6)(jiti@2.4.2)(jsdom@26.1.0)(magicast@0.3.5)(playwright-core@1.52.0)(sass@1.89.0)(terser@5.39.2)(typescript@5.8.3)(vitest@3.1.3)(yaml@2.8.0)': dependencies: - '@nuxt/kit': 3.16.2(magicast@0.3.5) - '@nuxt/schema': 3.16.2 - c12: 3.0.3(magicast@0.3.5) + '@nuxt/kit': 3.17.4(magicast@0.3.5) + '@nuxt/schema': 3.17.4 + c12: 3.0.4(magicast@0.3.5) consola: 3.4.2 defu: 6.1.4 destr: 2.0.5 estree-walker: 3.0.3 - fake-indexeddb: 6.0.0 + fake-indexeddb: 6.0.1 get-port-please: 3.1.2 - h3: 1.15.1 + h3: 1.15.3 local-pkg: 1.1.1 magic-string: 0.30.17 node-fetch-native: 1.6.6 @@ -11813,17 +9980,18 @@ snapshots: perfect-debounce: 1.0.0 radix3: 1.1.2 scule: 1.3.0 - std-env: 3.8.1 - tinyexec: 0.3.2 - ufo: 1.5.4 - unplugin: 2.2.2 - vite: 6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vitest-environment-nuxt: 1.0.1(@types/node@22.14.1)(@vue/test-utils@2.4.6)(jiti@2.4.2)(jsdom@26.0.0)(magicast@0.3.5)(sass@1.85.1)(terser@5.39.0)(typescript@5.8.3)(vitest@3.1.1(@types/node@22.14.1)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(yaml@2.7.1) - vue: 3.5.13(typescript@5.8.3) + std-env: 3.9.0 + tinyexec: 1.0.1 + ufo: 1.6.1 + unplugin: 2.3.4 + vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + vitest-environment-nuxt: 1.0.1(@types/node@22.15.29)(@vue/test-utils@2.4.6)(jiti@2.4.2)(jsdom@26.1.0)(magicast@0.3.5)(playwright-core@1.52.0)(sass@1.89.0)(terser@5.39.2)(typescript@5.8.3)(vitest@3.1.3)(yaml@2.8.0) + vue: 3.5.14(typescript@5.8.3) optionalDependencies: '@vue/test-utils': 2.4.6 - jsdom: 26.0.0 - vitest: 3.1.1(@types/node@22.14.1)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + jsdom: 26.1.0 + playwright-core: 1.52.0 + vitest: 3.1.3(@types/node@22.15.29)(@vitest/browser@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) transitivePeerDependencies: - '@types/node' - jiti @@ -11839,73 +10007,12 @@ snapshots: - typescript - yaml - '@nuxt/vite-builder@3.16.2(@types/node@22.14.1)(eslint@8.57.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.39.0)(sass@1.85.1)(terser@5.39.0)(typescript@5.8.3)(vue-tsc@2.2.8(typescript@5.8.3))(vue@3.5.13(typescript@5.8.3))(yaml@2.7.1)': - dependencies: - '@nuxt/kit': 3.16.2(magicast@0.3.5) - '@rollup/plugin-replace': 6.0.2(rollup@4.39.0) - '@vitejs/plugin-vue': 5.2.3(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) - '@vitejs/plugin-vue-jsx': 4.1.2(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) - autoprefixer: 10.4.21(postcss@8.5.3) - consola: 3.4.2 - cssnano: 7.0.6(postcss@8.5.3) - defu: 6.1.4 - esbuild: 0.25.2 - escape-string-regexp: 5.0.0 - exsolve: 1.0.4 - externality: 1.0.2 - get-port-please: 3.1.2 - h3: 1.15.1 - jiti: 2.4.2 - knitwork: 1.2.0 - magic-string: 0.30.17 - mlly: 1.7.4 - mocked-exports: 0.1.1 - ohash: 2.0.11 - pathe: 2.0.3 - perfect-debounce: 1.0.0 - pkg-types: 2.1.0 - postcss: 8.5.3 - rollup-plugin-visualizer: 5.14.0(rollup@4.39.0) - std-env: 3.8.1 - ufo: 1.5.4 - unenv: 2.0.0-rc.15 - unplugin: 2.2.2 - vite: 6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vite-node: 3.1.1(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vite-plugin-checker: 0.9.1(eslint@8.57.1)(optionator@0.9.4)(typescript@5.8.3)(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue-tsc@2.2.8(typescript@5.8.3)) - vue: 3.5.13(typescript@5.8.3) - vue-bundle-renderer: 2.1.1 - transitivePeerDependencies: - - '@biomejs/biome' - - '@types/node' - - eslint - - less - - lightningcss - - magicast - - meow - - optionator - - rolldown - - rollup - - sass - - sass-embedded - - stylelint - - stylus - - sugarss - - supports-color - - terser - - tsx - - typescript - - vls - - vti - - vue-tsc - - yaml - - '@nuxt/vite-builder@3.17.3(@types/node@22.15.18)(eslint@8.57.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.40.2)(sass@1.85.1)(terser@5.39.0)(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3))(yaml@2.7.1)': + '@nuxt/vite-builder@3.17.4(@types/node@22.15.29)(eslint@8.57.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.40.2)(sass@1.89.0)(terser@5.39.2)(typescript@5.8.3)(vue-tsc@2.2.10(typescript@5.8.3))(vue@3.5.14(typescript@5.8.3))(yaml@2.8.0)': dependencies: - '@nuxt/kit': 3.17.3(magicast@0.3.5) + '@nuxt/kit': 3.17.4(magicast@0.3.5) '@rollup/plugin-replace': 6.0.2(rollup@4.40.2) - '@vitejs/plugin-vue': 5.2.4(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) - '@vitejs/plugin-vue-jsx': 4.1.2(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) + '@vitejs/plugin-vue': 5.2.4(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3)) + '@vitejs/plugin-vue-jsx': 4.2.0(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3)) autoprefixer: 10.4.21(postcss@8.5.3) consola: 3.4.2 cssnano: 7.0.7(postcss@8.5.3) @@ -11929,12 +10036,12 @@ snapshots: rollup-plugin-visualizer: 5.14.0(rollup@4.40.2) std-env: 3.9.0 ufo: 1.6.1 - unenv: 2.0.0-rc.15 + unenv: 2.0.0-rc.17 unplugin: 2.3.4 - vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vite-node: 3.1.3(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vite-plugin-checker: 0.9.3(eslint@8.57.1)(optionator@0.9.4)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) - vue: 3.5.13(typescript@5.8.3) + vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + vite-node: 3.1.4(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + vite-plugin-checker: 0.9.3(eslint@8.57.0)(optionator@0.9.4)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue-tsc@2.2.10(typescript@5.8.3)) + vue: 3.5.14(typescript@5.8.3) vue-bundle-renderer: 2.1.1 transitivePeerDependencies: - '@biomejs/biome' @@ -11961,150 +10068,83 @@ snapshots: - vue-tsc - yaml - '@nx/nx-darwin-arm64@18.2.4': + '@nx/nx-darwin-arm64@20.8.1': optional: true - '@nx/nx-darwin-x64@18.2.4': + '@nx/nx-darwin-x64@20.8.1': optional: true - '@nx/nx-freebsd-x64@18.2.4': + '@nx/nx-freebsd-x64@20.8.1': optional: true - '@nx/nx-linux-arm-gnueabihf@18.2.4': + '@nx/nx-linux-arm-gnueabihf@20.8.1': optional: true - '@nx/nx-linux-arm64-gnu@18.2.4': + '@nx/nx-linux-arm64-gnu@20.8.1': optional: true - '@nx/nx-linux-arm64-musl@18.2.4': + '@nx/nx-linux-arm64-musl@20.8.1': optional: true - '@nx/nx-linux-x64-gnu@18.2.4': + '@nx/nx-linux-x64-gnu@20.8.1': optional: true - '@nx/nx-linux-x64-musl@18.2.4': + '@nx/nx-linux-x64-musl@20.8.1': optional: true - '@nx/nx-win32-arm64-msvc@18.2.4': + '@nx/nx-win32-arm64-msvc@20.8.1': optional: true - '@nx/nx-win32-x64-msvc@18.2.4': + '@nx/nx-win32-x64-msvc@20.8.1': optional: true '@one-ini/wasm@0.1.1': {} - '@oxc-parser/binding-darwin-arm64@0.56.5': - optional: true - - '@oxc-parser/binding-darwin-arm64@0.69.0': - optional: true - - '@oxc-parser/binding-darwin-x64@0.56.5': - optional: true - - '@oxc-parser/binding-darwin-x64@0.69.0': - optional: true - - '@oxc-parser/binding-freebsd-x64@0.69.0': - optional: true - - '@oxc-parser/binding-linux-arm-gnueabihf@0.56.5': - optional: true - - '@oxc-parser/binding-linux-arm-gnueabihf@0.69.0': + '@oxc-parser/binding-darwin-arm64@0.71.0': optional: true - '@oxc-parser/binding-linux-arm64-gnu@0.56.5': + '@oxc-parser/binding-darwin-x64@0.71.0': optional: true - '@oxc-parser/binding-linux-arm64-gnu@0.69.0': + '@oxc-parser/binding-freebsd-x64@0.71.0': optional: true - '@oxc-parser/binding-linux-arm64-musl@0.56.5': + '@oxc-parser/binding-linux-arm-gnueabihf@0.71.0': optional: true - '@oxc-parser/binding-linux-arm64-musl@0.69.0': + '@oxc-parser/binding-linux-arm-musleabihf@0.71.0': optional: true - '@oxc-parser/binding-linux-riscv64-gnu@0.69.0': + '@oxc-parser/binding-linux-arm64-gnu@0.71.0': optional: true - '@oxc-parser/binding-linux-s390x-gnu@0.69.0': + '@oxc-parser/binding-linux-arm64-musl@0.71.0': optional: true - '@oxc-parser/binding-linux-x64-gnu@0.56.5': + '@oxc-parser/binding-linux-riscv64-gnu@0.71.0': optional: true - '@oxc-parser/binding-linux-x64-gnu@0.69.0': + '@oxc-parser/binding-linux-s390x-gnu@0.71.0': optional: true - '@oxc-parser/binding-linux-x64-musl@0.56.5': + '@oxc-parser/binding-linux-x64-gnu@0.71.0': optional: true - '@oxc-parser/binding-linux-x64-musl@0.69.0': + '@oxc-parser/binding-linux-x64-musl@0.71.0': optional: true - '@oxc-parser/binding-wasm32-wasi@0.56.5': + '@oxc-parser/binding-wasm32-wasi@0.71.0': dependencies: - '@napi-rs/wasm-runtime': 0.2.8 + '@napi-rs/wasm-runtime': 0.2.10 optional: true - '@oxc-parser/binding-wasm32-wasi@0.69.0': - dependencies: - '@napi-rs/wasm-runtime': 0.2.9 - optional: true - - '@oxc-parser/binding-win32-arm64-msvc@0.56.5': - optional: true - - '@oxc-parser/binding-win32-arm64-msvc@0.69.0': - optional: true - - '@oxc-parser/binding-win32-x64-msvc@0.56.5': + '@oxc-parser/binding-win32-arm64-msvc@0.71.0': optional: true - '@oxc-parser/binding-win32-x64-msvc@0.69.0': + '@oxc-parser/binding-win32-x64-msvc@0.71.0': optional: true - '@oxc-parser/wasm@0.60.0': - dependencies: - '@oxc-project/types': 0.60.0 - - '@oxc-project/types@0.56.5': {} - - '@oxc-project/types@0.60.0': {} - - '@oxc-project/types@0.69.0': {} - - '@oxygen-ui/primitives@1.15.2': {} - - '@oxygen-ui/react-icons@1.15.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.1.6)': - dependencies: - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - typescript: 5.1.6 - - '@oxygen-ui/react@1.15.2(0356e0e967205ddd07cd0bc9fd616469)': - dependencies: - '@emotion/react': 11.14.0(@types/react@18.3.18)(react@18.3.1) - '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1) - '@mui/icons-material': 5.16.14(@mui/material@5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.18)(react@18.3.1) - '@mui/lab': 5.0.0-alpha.110(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@mui/material@5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/material': 5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': 5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1) - '@mui/utils': 5.16.14(@types/react@18.3.18)(react@18.3.1) - '@mui/x-data-grid': 6.20.4(@mui/material@5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@oxygen-ui/primitives': 1.15.2 - '@oxygen-ui/react-icons': 1.15.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.1.6) - clsx: 1.2.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-world-flags: 1.6.0(react@18.3.1) - optionalDependencies: - typescript: 5.1.6 - transitivePeerDependencies: - - '@types/react' + '@oxc-project/types@0.71.0': {} '@parcel/watcher-android-arm64@2.5.1': optional: true @@ -12174,13 +10214,9 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@pkgr/core@0.1.1': {} - '@pkgr/core@0.2.4': {} - '@polka/url@1.0.0-next.28': {} - - '@popperjs/core@2.11.8': {} + '@polka/url@1.0.0-next.29': {} '@poppinss/colors@4.1.4': dependencies: @@ -12194,81 +10230,41 @@ snapshots: '@poppinss/exception@1.2.1': {} - '@rollup/plugin-alias@5.1.1(rollup@4.39.0)': - optionalDependencies: - rollup: 4.39.0 + '@rolldown/pluginutils@1.0.0-beta.9': {} '@rollup/plugin-alias@5.1.1(rollup@4.40.2)': optionalDependencies: rollup: 4.40.2 - '@rollup/plugin-commonjs@25.0.8(rollup@4.35.0)': + '@rollup/plugin-commonjs@25.0.8(rollup@4.40.2)': dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.35.0) + '@rollup/pluginutils': 5.1.4(rollup@4.40.2) commondir: 1.0.1 estree-walker: 2.0.2 glob: 8.1.0 is-reference: 1.2.1 magic-string: 0.30.17 optionalDependencies: - rollup: 4.35.0 - - '@rollup/plugin-commonjs@28.0.3(rollup@4.39.0)': - dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.39.0) - commondir: 1.0.1 - estree-walker: 2.0.2 - fdir: 6.4.3(picomatch@4.0.2) - is-reference: 1.2.1 - magic-string: 0.30.17 - picomatch: 4.0.2 - optionalDependencies: - rollup: 4.39.0 + rollup: 4.40.2 '@rollup/plugin-commonjs@28.0.3(rollup@4.40.2)': dependencies: '@rollup/pluginutils': 5.1.4(rollup@4.40.2) commondir: 1.0.1 estree-walker: 2.0.2 - fdir: 6.4.3(picomatch@4.0.2) + fdir: 6.4.4(picomatch@4.0.2) is-reference: 1.2.1 magic-string: 0.30.17 picomatch: 4.0.2 optionalDependencies: rollup: 4.40.2 - '@rollup/plugin-dynamic-import-vars@2.1.5(rollup@4.35.0)': - dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.35.0) - astring: 1.9.0 - estree-walker: 2.0.2 - fast-glob: 3.3.3 - magic-string: 0.30.17 - optionalDependencies: - rollup: 4.35.0 - - '@rollup/plugin-image@3.0.3(rollup@4.35.0)': + '@rollup/plugin-image@3.0.3(rollup@4.40.2)': dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.35.0) + '@rollup/pluginutils': 5.1.4(rollup@4.40.2) mini-svg-data-uri: 1.4.4 optionalDependencies: - rollup: 4.35.0 - - '@rollup/plugin-inject@5.0.5(rollup@4.35.0)': - dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.35.0) - estree-walker: 2.0.2 - magic-string: 0.30.17 - optionalDependencies: - rollup: 4.35.0 - - '@rollup/plugin-inject@5.0.5(rollup@4.39.0)': - dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.39.0) - estree-walker: 2.0.2 - magic-string: 0.30.17 - optionalDependencies: - rollup: 4.39.0 + rollup: 4.40.2 '@rollup/plugin-inject@5.0.5(rollup@4.40.2)': dependencies: @@ -12278,37 +10274,21 @@ snapshots: optionalDependencies: rollup: 4.40.2 - '@rollup/plugin-json@6.1.0(rollup@4.39.0)': - dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.39.0) - optionalDependencies: - rollup: 4.39.0 - '@rollup/plugin-json@6.1.0(rollup@4.40.2)': dependencies: '@rollup/pluginutils': 5.1.4(rollup@4.40.2) optionalDependencies: rollup: 4.40.2 - '@rollup/plugin-node-resolve@15.3.1(rollup@4.35.0)': + '@rollup/plugin-node-resolve@15.3.1(rollup@4.40.2)': dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.35.0) - '@types/resolve': 1.20.2 - deepmerge: 4.3.1 - is-module: 1.0.0 - resolve: 1.22.10 - optionalDependencies: - rollup: 4.35.0 - - '@rollup/plugin-node-resolve@16.0.1(rollup@4.39.0)': - dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.39.0) + '@rollup/pluginutils': 5.1.4(rollup@4.40.2) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.10 optionalDependencies: - rollup: 4.39.0 + rollup: 4.40.2 '@rollup/plugin-node-resolve@16.0.1(rollup@4.40.2)': dependencies: @@ -12320,13 +10300,6 @@ snapshots: optionalDependencies: rollup: 4.40.2 - '@rollup/plugin-replace@6.0.2(rollup@4.39.0)': - dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.39.0) - magic-string: 0.30.17 - optionalDependencies: - rollup: 4.39.0 - '@rollup/plugin-replace@6.0.2(rollup@4.40.2)': dependencies: '@rollup/pluginutils': 5.1.4(rollup@4.40.2) @@ -12334,29 +10307,21 @@ snapshots: optionalDependencies: rollup: 4.40.2 - '@rollup/plugin-terser@0.4.4(rollup@4.39.0)': - dependencies: - serialize-javascript: 6.0.2 - smob: 1.5.0 - terser: 5.39.0 - optionalDependencies: - rollup: 4.39.0 - '@rollup/plugin-terser@0.4.4(rollup@4.40.2)': dependencies: serialize-javascript: 6.0.2 smob: 1.5.0 - terser: 5.39.0 + terser: 5.39.2 optionalDependencies: rollup: 4.40.2 - '@rollup/plugin-typescript@11.1.6(rollup@4.35.0)(tslib@2.8.1)(typescript@5.1.6)': + '@rollup/plugin-typescript@11.1.6(rollup@4.40.2)(tslib@2.8.1)(typescript@5.1.6)': dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.35.0) + '@rollup/pluginutils': 5.1.4(rollup@4.40.2) resolve: 1.22.10 typescript: 5.1.6 optionalDependencies: - rollup: 4.35.0 + rollup: 4.40.2 tslib: 2.8.1 '@rollup/pluginutils@4.2.1': @@ -12364,210 +10329,77 @@ snapshots: estree-walker: 2.0.2 picomatch: 2.3.1 - '@rollup/pluginutils@5.1.4(rollup@4.35.0)': - dependencies: - '@types/estree': 1.0.6 - estree-walker: 2.0.2 - picomatch: 4.0.2 - optionalDependencies: - rollup: 4.35.0 - - '@rollup/pluginutils@5.1.4(rollup@4.39.0)': - dependencies: - '@types/estree': 1.0.6 - estree-walker: 2.0.2 - picomatch: 4.0.2 - optionalDependencies: - rollup: 4.39.0 - '@rollup/pluginutils@5.1.4(rollup@4.40.2)': dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 estree-walker: 2.0.2 picomatch: 4.0.2 optionalDependencies: rollup: 4.40.2 - '@rollup/rollup-android-arm-eabi@4.35.0': - optional: true - - '@rollup/rollup-android-arm-eabi@4.39.0': - optional: true - '@rollup/rollup-android-arm-eabi@4.40.2': optional: true - '@rollup/rollup-android-arm64@4.35.0': - optional: true - - '@rollup/rollup-android-arm64@4.39.0': - optional: true - '@rollup/rollup-android-arm64@4.40.2': optional: true - '@rollup/rollup-darwin-arm64@4.35.0': - optional: true - - '@rollup/rollup-darwin-arm64@4.39.0': - optional: true - '@rollup/rollup-darwin-arm64@4.40.2': optional: true - '@rollup/rollup-darwin-x64@4.35.0': - optional: true - - '@rollup/rollup-darwin-x64@4.39.0': - optional: true - '@rollup/rollup-darwin-x64@4.40.2': optional: true - '@rollup/rollup-freebsd-arm64@4.35.0': - optional: true - - '@rollup/rollup-freebsd-arm64@4.39.0': - optional: true - '@rollup/rollup-freebsd-arm64@4.40.2': optional: true - '@rollup/rollup-freebsd-x64@4.35.0': - optional: true - - '@rollup/rollup-freebsd-x64@4.39.0': - optional: true - '@rollup/rollup-freebsd-x64@4.40.2': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.35.0': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.39.0': - optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.40.2': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.35.0': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.39.0': - optional: true - '@rollup/rollup-linux-arm-musleabihf@4.40.2': optional: true - '@rollup/rollup-linux-arm64-gnu@4.35.0': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.39.0': - optional: true - '@rollup/rollup-linux-arm64-gnu@4.40.2': optional: true - '@rollup/rollup-linux-arm64-musl@4.35.0': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.39.0': - optional: true - '@rollup/rollup-linux-arm64-musl@4.40.2': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.35.0': - optional: true - - '@rollup/rollup-linux-loongarch64-gnu@4.39.0': - optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.40.2': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.35.0': - optional: true - - '@rollup/rollup-linux-powerpc64le-gnu@4.39.0': - optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.40.2': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.35.0': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.39.0': - optional: true - '@rollup/rollup-linux-riscv64-gnu@4.40.2': optional: true - '@rollup/rollup-linux-riscv64-musl@4.39.0': - optional: true - '@rollup/rollup-linux-riscv64-musl@4.40.2': optional: true - '@rollup/rollup-linux-s390x-gnu@4.35.0': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.39.0': - optional: true - '@rollup/rollup-linux-s390x-gnu@4.40.2': optional: true - '@rollup/rollup-linux-x64-gnu@4.35.0': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.39.0': - optional: true - '@rollup/rollup-linux-x64-gnu@4.40.2': optional: true - '@rollup/rollup-linux-x64-musl@4.35.0': - optional: true - - '@rollup/rollup-linux-x64-musl@4.39.0': - optional: true - '@rollup/rollup-linux-x64-musl@4.40.2': optional: true - '@rollup/rollup-win32-arm64-msvc@4.35.0': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.39.0': - optional: true - '@rollup/rollup-win32-arm64-msvc@4.40.2': optional: true - '@rollup/rollup-win32-ia32-msvc@4.35.0': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.39.0': - optional: true - '@rollup/rollup-win32-ia32-msvc@4.40.2': optional: true - '@rollup/rollup-win32-x64-msvc@4.35.0': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.39.0': - optional: true - '@rollup/rollup-win32-x64-msvc@4.40.2': optional: true '@rtsao/scc@1.1.0': {} - '@sec-ant/readable-stream@0.4.1': {} + '@rushstack/eslint-patch@1.11.0': {} '@shikijs/core@2.5.0': dependencies: @@ -12615,14 +10447,12 @@ snapshots: '@sindresorhus/merge-streams@2.3.0': {} - '@sindresorhus/merge-streams@4.0.0': {} - '@speed-highlight/core@1.2.7': {} - '@stylistic/eslint-plugin@4.2.0(eslint@8.57.1)(typescript@5.8.3)': + '@stylistic/eslint-plugin@4.4.0(eslint@8.57.0)(typescript@5.8.3)': dependencies: - '@typescript-eslint/utils': 8.26.1(eslint@8.57.1)(typescript@5.8.3) - eslint: 8.57.1 + '@typescript-eslint/utils': 8.32.1(eslint@8.57.0)(typescript@5.8.3) + eslint: 8.57.0 eslint-visitor-keys: 4.2.0 espree: 10.3.0 estraverse: 5.3.0 @@ -12631,35 +10461,55 @@ snapshots: - supports-color - typescript + '@swc/counter@0.1.3': {} + + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 + + '@testing-library/dom@10.4.0': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/runtime': 7.27.1 + '@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 + pretty-format: 27.5.1 + + '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.0)': + dependencies: + '@testing-library/dom': 10.4.0 + '@trysound/sax@0.2.0': {} - '@tsconfig/node22@22.0.0': {} - '@tybys/wasm-util@0.9.0': dependencies: tslib: 2.8.1 - optional: true + + '@types/aria-query@5.0.4': {} '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.26.10 - '@babel/types': 7.26.10 - '@types/babel__generator': 7.6.8 + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 + '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.6 + '@types/babel__traverse': 7.20.7 - '@types/babel__generator@7.6.8': + '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.26.10 + '@babel/types': 7.27.1 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.26.10 - '@babel/types': 7.26.10 + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 - '@types/babel__traverse@7.20.6': + '@types/babel__traverse@7.20.7': dependencies: - '@babel/types': 7.26.10 + '@babel/types': 7.27.1 '@types/cssnano@5.1.3(postcss@8.5.3)': dependencies: @@ -12667,38 +10517,18 @@ snapshots: transitivePeerDependencies: - postcss - '@types/doctrine@0.0.9': {} - - '@types/estree@1.0.6': {} - '@types/estree@1.0.7': {} '@types/hast@3.0.4': dependencies: '@types/unist': 3.0.3 - '@types/jsdom@21.1.7': - dependencies: - '@types/node': 22.14.1 - '@types/tough-cookie': 4.0.5 - parse5: 7.2.1 - '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} '@types/linkify-it@5.0.0': {} - '@types/lodash.isempty@4.4.9': - dependencies: - '@types/lodash': 4.17.16 - - '@types/lodash.merge@4.6.9': - dependencies: - '@types/lodash': 4.17.16 - - '@types/lodash@4.17.16': {} - '@types/markdown-it@14.1.2': dependencies: '@types/linkify-it': 5.0.0 @@ -12714,53 +10544,37 @@ snapshots: '@types/node@12.20.55': {} - '@types/node@20.17.24': + '@types/node@20.17.50': dependencies: undici-types: 6.19.8 - '@types/node@22.13.10': - dependencies: - undici-types: 6.20.0 - - '@types/node@22.14.1': + '@types/node@22.15.18': dependencies: undici-types: 6.21.0 - '@types/node@22.15.18': + '@types/node@22.15.29': dependencies: undici-types: 6.21.0 - optional: true '@types/normalize-package-data@2.4.4': {} '@types/parse-json@4.0.2': {} - '@types/parse-path@7.0.3': {} - - '@types/prop-types@15.7.14': {} - - '@types/randombytes@2.0.3': - dependencies: - '@types/node': 22.14.1 - - '@types/react-dom@18.3.5(@types/react@18.3.18)': + '@types/parse-path@7.1.0': dependencies: - '@types/react': 18.3.18 + parse-path: 7.1.0 - '@types/react-transition-group@4.4.12(@types/react@18.3.18)': + '@types/react-dom@19.1.5(@types/react@19.1.5)': dependencies: - '@types/react': 18.3.18 + '@types/react': 19.1.5 - '@types/react@18.3.18': + '@types/react@19.1.5': dependencies: - '@types/prop-types': 15.7.14 csstype: 3.1.3 '@types/resolve@1.20.2': {} - '@types/semver@7.5.8': {} - - '@types/tough-cookie@4.0.5': {} + '@types/semver@7.7.0': {} '@types/triple-beam@1.3.5': {} @@ -12770,166 +10584,214 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 22.15.18 + '@types/node': 22.15.29 optional: true - '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6)': + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0)(typescript@5.1.6)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.1.6) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.1.6) '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.1)(typescript@5.1.6) - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.1.6) - debug: 4.4.0 - eslint: 8.57.1 + '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.0)(typescript@5.1.6) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.1.6) + debug: 4.4.1 + eslint: 8.57.0 graphemer: 1.4.0 ignore: 5.3.2 natural-compare-lite: 1.4.0 - semver: 7.7.1 + semver: 7.7.2 tsutils: 3.21.0(typescript@5.1.6) optionalDependencies: typescript: 5.1.6 transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6)': + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0)(typescript@5.7.3)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.7.3) + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.0)(typescript@5.7.3) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.7.3) + debug: 4.4.1 + eslint: 8.57.0 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare-lite: 1.4.0 + semver: 7.7.2 + tsutils: 3.21.0(typescript@5.7.3) + optionalDependencies: + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0)(typescript@5.1.6)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.1.6) + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.1.6) '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.1)(typescript@5.1.6) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.1.6) + '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.0)(typescript@5.1.6) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.1.6) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 - eslint: 8.57.1 + debug: 4.4.1 + eslint: 8.57.0 graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - semver: 7.7.1 + semver: 7.7.2 ts-api-utils: 1.4.3(typescript@5.1.6) optionalDependencies: typescript: 5.1.6 transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6)': + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.1.6) + '@typescript-eslint/parser': 7.18.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) '@typescript-eslint/scope-manager': 7.18.0 - '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.1)(typescript@5.1.6) - '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.1.6) + '@typescript-eslint/type-utils': 7.18.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 7.18.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) '@typescript-eslint/visitor-keys': 7.18.0 - eslint: 8.57.1 + eslint: 9.28.0(jiti@2.4.2) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 1.4.3(typescript@5.1.6) + ts-api-utils: 1.4.3(typescript@5.8.3) optionalDependencies: - typescript: 5.1.6 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.26.1(@typescript-eslint/parser@8.26.1(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6)': + '@typescript-eslint/eslint-plugin@8.32.1(@typescript-eslint/parser@8.32.1(eslint@8.57.0)(typescript@5.8.3))(eslint@8.57.0)(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.26.1(eslint@8.57.1)(typescript@5.1.6) - '@typescript-eslint/scope-manager': 8.26.1 - '@typescript-eslint/type-utils': 8.26.1(eslint@8.57.1)(typescript@5.1.6) - '@typescript-eslint/utils': 8.26.1(eslint@8.57.1)(typescript@5.1.6) - '@typescript-eslint/visitor-keys': 8.26.1 - eslint: 8.57.1 + '@typescript-eslint/parser': 8.32.1(eslint@8.57.0)(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.32.1 + '@typescript-eslint/type-utils': 8.32.1(eslint@8.57.0)(typescript@5.8.3) + '@typescript-eslint/utils': 8.32.1(eslint@8.57.0)(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.32.1 + eslint: 8.57.0 graphemer: 1.4.0 - ignore: 5.3.2 + ignore: 7.0.4 natural-compare: 1.4.0 - ts-api-utils: 2.0.1(typescript@5.1.6) - typescript: 5.1.6 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.30.1(@typescript-eslint/parser@8.30.1(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.33.1(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.30.1(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/scope-manager': 8.30.1 - '@typescript-eslint/type-utils': 8.30.1(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/utils': 8.30.1(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.30.1 - eslint: 8.57.1 + '@typescript-eslint/parser': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.33.1 + '@typescript-eslint/type-utils': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.33.1 + eslint: 9.28.0(jiti@2.4.2) graphemer: 1.4.0 - ignore: 5.3.2 + ignore: 7.0.4 natural-compare: 1.4.0 - ts-api-utils: 2.0.1(typescript@5.8.3) + ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/experimental-utils@5.62.0(eslint@8.57.1)(typescript@5.1.6)': + '@typescript-eslint/experimental-utils@5.62.0(eslint@8.57.0)(typescript@5.1.6)': + dependencies: + '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.1.6) + eslint: 8.57.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/experimental-utils@5.62.0(eslint@8.57.0)(typescript@5.7.3)': dependencies: - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.1.6) - eslint: 8.57.1 + '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.7.3) + eslint: 8.57.0 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6)': + '@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6)': dependencies: '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.1.6) - debug: 4.4.0 - eslint: 8.57.1 + debug: 4.4.1 + eslint: 8.57.0 optionalDependencies: typescript: 5.1.6 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.1.6)': + '@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3)': + dependencies: + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.7.3) + debug: 4.4.1 + eslint: 8.57.0 + optionalDependencies: + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.1.6)': dependencies: '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.1.6) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 - eslint: 8.57.1 + debug: 4.4.1 + eslint: 8.57.0 optionalDependencies: typescript: 5.1.6 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.1.6)': + '@typescript-eslint/parser@7.18.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.1.6) + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.8.3) '@typescript-eslint/visitor-keys': 7.18.0 - debug: 4.4.0 - eslint: 8.57.1 + debug: 4.4.1 + eslint: 9.28.0(jiti@2.4.2) optionalDependencies: - typescript: 5.1.6 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.26.1(eslint@8.57.1)(typescript@5.1.6)': + '@typescript-eslint/parser@8.32.1(eslint@8.57.0)(typescript@5.8.3)': dependencies: - '@typescript-eslint/scope-manager': 8.26.1 - '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.1.6) - '@typescript-eslint/visitor-keys': 8.26.1 - debug: 4.4.0 - eslint: 8.57.1 - typescript: 5.1.6 + '@typescript-eslint/scope-manager': 8.32.1 + '@typescript-eslint/types': 8.32.1 + '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.32.1 + debug: 4.4.1 + eslint: 8.57.0 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.33.1 + '@typescript-eslint/types': 8.33.1 + '@typescript-eslint/typescript-estree': 8.33.1(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.33.1 + debug: 4.4.1 + eslint: 9.28.0(jiti@2.4.2) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.30.1(eslint@8.57.1)(typescript@5.8.3)': + '@typescript-eslint/project-service@8.33.1(typescript@5.8.3)': dependencies: - '@typescript-eslint/scope-manager': 8.30.1 - '@typescript-eslint/types': 8.30.1 - '@typescript-eslint/typescript-estree': 8.30.1(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.30.1 - debug: 4.4.0 - eslint: 8.57.1 + '@typescript-eslint/tsconfig-utils': 8.33.1(typescript@5.8.3) + '@typescript-eslint/types': 8.33.1 + debug: 4.4.1 typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -12949,70 +10811,86 @@ snapshots: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0 - '@typescript-eslint/scope-manager@8.26.1': + '@typescript-eslint/scope-manager@8.32.1': + dependencies: + '@typescript-eslint/types': 8.32.1 + '@typescript-eslint/visitor-keys': 8.32.1 + + '@typescript-eslint/scope-manager@8.33.1': dependencies: - '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/visitor-keys': 8.26.1 + '@typescript-eslint/types': 8.33.1 + '@typescript-eslint/visitor-keys': 8.33.1 - '@typescript-eslint/scope-manager@8.30.1': + '@typescript-eslint/tsconfig-utils@8.33.1(typescript@5.8.3)': dependencies: - '@typescript-eslint/types': 8.30.1 - '@typescript-eslint/visitor-keys': 8.30.1 + typescript: 5.8.3 - '@typescript-eslint/type-utils@5.62.0(eslint@8.57.1)(typescript@5.1.6)': + '@typescript-eslint/type-utils@5.62.0(eslint@8.57.0)(typescript@5.1.6)': dependencies: '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.1.6) - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.1.6) - debug: 4.4.0 - eslint: 8.57.1 + '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.1.6) + debug: 4.4.1 + eslint: 8.57.0 tsutils: 3.21.0(typescript@5.1.6) optionalDependencies: typescript: 5.1.6 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@6.21.0(eslint@8.57.1)(typescript@5.1.6)': + '@typescript-eslint/type-utils@5.62.0(eslint@8.57.0)(typescript@5.7.3)': + dependencies: + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.7.3) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.7.3) + debug: 4.4.1 + eslint: 8.57.0 + tsutils: 3.21.0(typescript@5.7.3) + optionalDependencies: + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/type-utils@6.21.0(eslint@8.57.0)(typescript@5.1.6)': dependencies: '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.1.6) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.1.6) - debug: 4.4.0 - eslint: 8.57.1 + '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.1.6) + debug: 4.4.1 + eslint: 8.57.0 ts-api-utils: 1.4.3(typescript@5.1.6) optionalDependencies: typescript: 5.1.6 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@7.18.0(eslint@8.57.1)(typescript@5.1.6)': + '@typescript-eslint/type-utils@7.18.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.1.6) - '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.1.6) - debug: 4.4.0 - eslint: 8.57.1 - ts-api-utils: 1.4.3(typescript@5.1.6) + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.8.3) + '@typescript-eslint/utils': 7.18.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + debug: 4.4.1 + eslint: 9.28.0(jiti@2.4.2) + ts-api-utils: 1.4.3(typescript@5.8.3) optionalDependencies: - typescript: 5.1.6 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.26.1(eslint@8.57.1)(typescript@5.1.6)': + '@typescript-eslint/type-utils@8.32.1(eslint@8.57.0)(typescript@5.8.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.1.6) - '@typescript-eslint/utils': 8.26.1(eslint@8.57.1)(typescript@5.1.6) - debug: 4.4.0 - eslint: 8.57.1 - ts-api-utils: 2.0.1(typescript@5.1.6) - typescript: 5.1.6 + '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.8.3) + '@typescript-eslint/utils': 8.32.1(eslint@8.57.0)(typescript@5.8.3) + debug: 4.4.1 + eslint: 8.57.0 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.30.1(eslint@8.57.1)(typescript@5.8.3)': + '@typescript-eslint/type-utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.30.1(typescript@5.8.3) - '@typescript-eslint/utils': 8.30.1(eslint@8.57.1)(typescript@5.8.3) - debug: 4.4.0 - eslint: 8.57.1 - ts-api-utils: 2.0.1(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.33.1(typescript@5.8.3) + '@typescript-eslint/utils': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + debug: 4.4.1 + eslint: 9.28.0(jiti@2.4.2) + ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -13023,35 +10901,35 @@ snapshots: '@typescript-eslint/types@7.18.0': {} - '@typescript-eslint/types@8.26.1': {} + '@typescript-eslint/types@8.32.1': {} - '@typescript-eslint/types@8.30.1': {} + '@typescript-eslint/types@8.33.1': {} '@typescript-eslint/typescript-estree@5.62.0(typescript@5.1.6)': dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.4.0 + debug: 4.4.1 globby: 11.1.0 is-glob: 4.0.3 - semver: 7.7.1 + semver: 7.7.2 tsutils: 3.21.0(typescript@5.1.6) optionalDependencies: typescript: 5.1.6 transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@5.62.0(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@5.62.0(typescript@5.7.3)': dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.4.0 + debug: 4.4.1 globby: 11.1.0 is-glob: 4.0.3 - semver: 7.7.1 - tsutils: 3.21.0(typescript@5.8.3) + semver: 7.7.2 + tsutils: 3.21.0(typescript@5.7.3) optionalDependencies: - typescript: 5.8.3 + typescript: 5.7.3 transitivePeerDependencies: - supports-color @@ -13059,168 +10937,147 @@ snapshots: dependencies: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 + debug: 4.4.1 globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 - semver: 7.7.1 + semver: 7.7.2 ts-api-utils: 1.4.3(typescript@5.1.6) optionalDependencies: typescript: 5.1.6 transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@7.18.0(typescript@5.1.6)': + '@typescript-eslint/typescript-estree@7.18.0(typescript@5.8.3)': dependencies: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0 - debug: 4.4.0 + debug: 4.4.1 globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.1 - ts-api-utils: 1.4.3(typescript@5.1.6) + semver: 7.7.2 + ts-api-utils: 1.4.3(typescript@5.8.3) optionalDependencies: - typescript: 5.1.6 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/typescript-estree@8.26.1(typescript@5.1.6)': - dependencies: - '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/visitor-keys': 8.26.1 - debug: 4.4.0 - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.1 - ts-api-utils: 2.0.1(typescript@5.1.6) - typescript: 5.1.6 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.26.1(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@8.32.1(typescript@5.8.3)': dependencies: - '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/visitor-keys': 8.26.1 - debug: 4.4.0 + '@typescript-eslint/types': 8.32.1 + '@typescript-eslint/visitor-keys': 8.32.1 + debug: 4.4.1 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.1 - ts-api-utils: 2.0.1(typescript@5.8.3) + semver: 7.7.2 + ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.30.1(typescript@5.1.6)': + '@typescript-eslint/typescript-estree@8.33.1(typescript@5.8.3)': dependencies: - '@typescript-eslint/types': 8.30.1 - '@typescript-eslint/visitor-keys': 8.30.1 - debug: 4.4.0 + '@typescript-eslint/project-service': 8.33.1(typescript@5.8.3) + '@typescript-eslint/tsconfig-utils': 8.33.1(typescript@5.8.3) + '@typescript-eslint/types': 8.33.1 + '@typescript-eslint/visitor-keys': 8.33.1 + debug: 4.4.1 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.1 - ts-api-utils: 2.0.1(typescript@5.1.6) - typescript: 5.1.6 + semver: 7.7.2 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.30.1(typescript@5.8.3)': + '@typescript-eslint/utils@5.62.0(eslint@8.57.0)(typescript@5.1.6)': dependencies: - '@typescript-eslint/types': 8.30.1 - '@typescript-eslint/visitor-keys': 8.30.1 - debug: 4.4.0 - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.1 - ts-api-utils: 2.0.1(typescript@5.8.3) - typescript: 5.8.3 + '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.7.0 + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.1.6) + eslint: 8.57.0 + eslint-scope: 5.1.1 + semver: 7.7.2 transitivePeerDependencies: - supports-color + - typescript - '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@5.1.6)': + '@typescript-eslint/utils@5.62.0(eslint@8.57.0)(typescript@5.7.3)': dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@8.57.1) + '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.0) '@types/json-schema': 7.0.15 - '@types/semver': 7.5.8 + '@types/semver': 7.7.0 '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.1.6) - eslint: 8.57.1 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.7.3) + eslint: 8.57.0 eslint-scope: 5.1.1 - semver: 7.7.1 + semver: 7.7.2 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/utils@6.21.0(eslint@8.57.1)(typescript@5.1.6)': + '@typescript-eslint/utils@6.21.0(eslint@8.57.0)(typescript@5.1.6)': dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@8.57.1) + '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.0) '@types/json-schema': 7.0.15 - '@types/semver': 7.5.8 + '@types/semver': 7.7.0 '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.1.6) - eslint: 8.57.1 - semver: 7.7.1 + eslint: 8.57.0 + semver: 7.7.2 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/utils@7.18.0(eslint@8.57.1)(typescript@5.1.6)': + '@typescript-eslint/utils@7.18.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@8.57.1) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0(jiti@2.4.2)) '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.1.6) - eslint: 8.57.1 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.8.3) + eslint: 9.28.0(jiti@2.4.2) transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/utils@8.26.1(eslint@8.57.1)(typescript@5.1.6)': - dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@8.57.1) - '@typescript-eslint/scope-manager': 8.26.1 - '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.1.6) - eslint: 8.57.1 - typescript: 5.1.6 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.26.1(eslint@8.57.1)(typescript@5.8.3)': + '@typescript-eslint/utils@8.32.1(eslint@8.57.0)(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@8.57.1) - '@typescript-eslint/scope-manager': 8.26.1 - '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.3) - eslint: 8.57.1 + '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.0) + '@typescript-eslint/scope-manager': 8.32.1 + '@typescript-eslint/types': 8.32.1 + '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.8.3) + eslint: 8.57.0 typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.30.1(eslint@8.57.1)(typescript@5.1.6)': + '@typescript-eslint/utils@8.32.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@8.57.1) - '@typescript-eslint/scope-manager': 8.30.1 - '@typescript-eslint/types': 8.30.1 - '@typescript-eslint/typescript-estree': 8.30.1(typescript@5.1.6) - eslint: 8.57.1 - typescript: 5.1.6 + '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0(jiti@2.4.2)) + '@typescript-eslint/scope-manager': 8.32.1 + '@typescript-eslint/types': 8.32.1 + '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.8.3) + eslint: 9.28.0(jiti@2.4.2) + typescript: 5.8.3 transitivePeerDependencies: - supports-color + optional: true - '@typescript-eslint/utils@8.30.1(eslint@8.57.1)(typescript@5.8.3)': + '@typescript-eslint/utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@8.57.1) - '@typescript-eslint/scope-manager': 8.30.1 - '@typescript-eslint/types': 8.30.1 - '@typescript-eslint/typescript-estree': 8.30.1(typescript@5.8.3) - eslint: 8.57.1 + '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0(jiti@2.4.2)) + '@typescript-eslint/scope-manager': 8.33.1 + '@typescript-eslint/types': 8.33.1 + '@typescript-eslint/typescript-estree': 8.33.1(typescript@5.8.3) + eslint: 9.28.0(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -13240,119 +11097,78 @@ snapshots: '@typescript-eslint/types': 7.18.0 eslint-visitor-keys: 3.4.3 - '@typescript-eslint/visitor-keys@8.26.1': + '@typescript-eslint/visitor-keys@8.32.1': dependencies: - '@typescript-eslint/types': 8.26.1 + '@typescript-eslint/types': 8.32.1 eslint-visitor-keys: 4.2.0 - '@typescript-eslint/visitor-keys@8.30.1': + '@typescript-eslint/visitor-keys@8.33.1': dependencies: - '@typescript-eslint/types': 8.30.1 + '@typescript-eslint/types': 8.33.1 eslint-visitor-keys: 4.2.0 '@ungap/structured-clone@1.3.0': {} - '@unhead/vue@2.0.5(vue@3.5.13(typescript@5.8.3))': + '@unhead/vue@2.0.10(vue@3.5.14(typescript@5.8.3))': dependencies: hookable: 5.5.3 - unhead: 2.0.5 - vue: 3.5.13(typescript@5.8.3) + unhead: 2.0.10 + vue: 3.5.14(typescript@5.8.3) - '@unhead/vue@2.0.8(vue@3.5.13(typescript@5.8.3))': - dependencies: - hookable: 5.5.3 - unhead: 2.0.8 - vue: 3.5.13(typescript@5.8.3) + '@unrs/resolver-binding-darwin-arm64@1.7.2': + optional: true - '@unrs/resolver-binding-darwin-arm64@1.5.0': + '@unrs/resolver-binding-darwin-x64@1.7.2': optional: true - '@unrs/resolver-binding-darwin-x64@1.5.0': + '@unrs/resolver-binding-freebsd-x64@1.7.2': optional: true - '@unrs/resolver-binding-freebsd-x64@1.5.0': + '@unrs/resolver-binding-linux-arm-gnueabihf@1.7.2': optional: true - '@unrs/resolver-binding-linux-arm-gnueabihf@1.5.0': + '@unrs/resolver-binding-linux-arm-musleabihf@1.7.2': optional: true - '@unrs/resolver-binding-linux-arm-musleabihf@1.5.0': + '@unrs/resolver-binding-linux-arm64-gnu@1.7.2': optional: true - '@unrs/resolver-binding-linux-arm64-gnu@1.5.0': + '@unrs/resolver-binding-linux-arm64-musl@1.7.2': optional: true - '@unrs/resolver-binding-linux-arm64-musl@1.5.0': + '@unrs/resolver-binding-linux-ppc64-gnu@1.7.2': optional: true - '@unrs/resolver-binding-linux-ppc64-gnu@1.5.0': + '@unrs/resolver-binding-linux-riscv64-gnu@1.7.2': optional: true - '@unrs/resolver-binding-linux-riscv64-gnu@1.5.0': + '@unrs/resolver-binding-linux-riscv64-musl@1.7.2': optional: true - '@unrs/resolver-binding-linux-s390x-gnu@1.5.0': + '@unrs/resolver-binding-linux-s390x-gnu@1.7.2': optional: true - '@unrs/resolver-binding-linux-x64-gnu@1.5.0': + '@unrs/resolver-binding-linux-x64-gnu@1.7.2': optional: true - '@unrs/resolver-binding-linux-x64-musl@1.5.0': + '@unrs/resolver-binding-linux-x64-musl@1.7.2': optional: true - '@unrs/resolver-binding-wasm32-wasi@1.5.0': + '@unrs/resolver-binding-wasm32-wasi@1.7.2': dependencies: - '@napi-rs/wasm-runtime': 0.2.8 + '@napi-rs/wasm-runtime': 0.2.10 optional: true - '@unrs/resolver-binding-win32-arm64-msvc@1.5.0': + '@unrs/resolver-binding-win32-arm64-msvc@1.7.2': optional: true - '@unrs/resolver-binding-win32-ia32-msvc@1.5.0': + '@unrs/resolver-binding-win32-ia32-msvc@1.7.2': optional: true - '@unrs/resolver-binding-win32-x64-msvc@1.5.0': + '@unrs/resolver-binding-win32-x64-msvc@1.7.2': optional: true - '@vercel/nft@0.27.7(rollup@4.40.2)': - dependencies: - '@mapbox/node-pre-gyp': 1.0.11 - '@rollup/pluginutils': 5.1.4(rollup@4.40.2) - acorn: 8.14.1 - acorn-import-attributes: 1.9.5(acorn@8.14.1) - async-sema: 3.1.1 - bindings: 1.5.0 - estree-walker: 2.0.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - micromatch: 4.0.8 - node-gyp-build: 4.8.4 - resolve-from: 5.0.0 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - '@vercel/nft@0.29.2(rollup@4.39.0)': - dependencies: - '@mapbox/node-pre-gyp': 2.0.0 - '@rollup/pluginutils': 5.1.4(rollup@4.39.0) - acorn: 8.14.1 - acorn-import-attributes: 1.9.5(acorn@8.14.1) - async-sema: 3.1.1 - bindings: 1.5.0 - estree-walker: 2.0.2 - glob: 10.4.5 - graceful-fs: 4.2.11 - node-gyp-build: 4.8.4 - picomatch: 4.0.2 - resolve-from: 5.0.0 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - '@vercel/nft@0.29.2(rollup@4.40.2)': + '@vercel/nft@0.29.3(rollup@4.40.2)': dependencies: '@mapbox/node-pre-gyp': 2.0.0 '@rollup/pluginutils': 5.1.4(rollup@4.40.2) @@ -13371,268 +11187,245 @@ snapshots: - rollup - supports-color - '@vitejs/plugin-basic-ssl@1.2.0(vite@5.4.14(@types/node@22.15.18)(sass@1.85.1)(terser@5.39.0))': - dependencies: - vite: 5.4.14(@types/node@22.15.18)(sass@1.85.1)(terser@5.39.0) - - '@vitejs/plugin-react@4.3.4(vite@5.4.14(@types/node@22.15.18)(sass@1.85.1)(terser@5.39.0))': + '@vitejs/plugin-react@4.5.1(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))': dependencies: - '@babel/core': 7.26.10 - '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.10) + '@babel/core': 7.27.1 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.27.1) + '@rolldown/pluginutils': 1.0.0-beta.9 '@types/babel__core': 7.20.5 - react-refresh: 0.14.2 - vite: 5.4.14(@types/node@22.15.18)(sass@1.85.1)(terser@5.39.0) - transitivePeerDependencies: - - supports-color - - '@vitejs/plugin-vue-jsx@4.1.2(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': - dependencies: - '@babel/core': 7.26.10 - '@babel/plugin-transform-typescript': 7.26.8(@babel/core@7.26.10) - '@vue/babel-plugin-jsx': 1.4.0(@babel/core@7.26.10) - vite: 6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vue: 3.5.13(typescript@5.8.3) + react-refresh: 0.17.0 + vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue-jsx@4.1.2(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': + '@vitejs/plugin-vue-jsx@4.2.0(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3))': dependencies: - '@babel/core': 7.26.10 - '@babel/plugin-transform-typescript': 7.26.8(@babel/core@7.26.10) - '@vue/babel-plugin-jsx': 1.4.0(@babel/core@7.26.10) - vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vue: 3.5.13(typescript@5.8.3) + '@babel/core': 7.27.1 + '@babel/plugin-transform-typescript': 7.27.1(@babel/core@7.27.1) + '@rolldown/pluginutils': 1.0.0-beta.9 + '@vue/babel-plugin-jsx': 1.4.0(@babel/core@7.27.1) + vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + vue: 3.5.14(typescript@5.8.3) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@5.2.1(vite@5.4.14(@types/node@22.15.18)(sass@1.85.1)(terser@5.39.0))(vue@3.5.13(typescript@5.8.3))': + '@vitejs/plugin-vue@5.2.4(vite@5.4.19(@types/node@22.15.29)(sass@1.89.0)(terser@5.39.2))(vue@3.5.14(typescript@5.8.3))': dependencies: - vite: 5.4.14(@types/node@22.15.18)(sass@1.85.1)(terser@5.39.0) - vue: 3.5.13(typescript@5.8.3) + vite: 5.4.19(@types/node@22.15.29)(sass@1.89.0)(terser@5.39.2) + vue: 3.5.14(typescript@5.8.3) - '@vitejs/plugin-vue@5.2.1(vite@6.2.2(@types/node@20.17.24)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.1.6))': + '@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@20.17.50)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.1.6))': dependencies: - vite: 6.2.2(@types/node@20.17.24)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vue: 3.5.13(typescript@5.1.6) + vite: 6.3.5(@types/node@20.17.50)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + vue: 3.5.14(typescript@5.1.6) - '@vitejs/plugin-vue@5.2.1(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.1.6))': + '@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3))': dependencies: - vite: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vue: 3.5.13(typescript@5.1.6) + vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + vue: 3.5.14(typescript@5.8.3) - '@vitejs/plugin-vue@5.2.3(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': + '@vitest/browser@3.1.3(playwright@1.52.0)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vitest@3.1.3)': dependencies: - vite: 6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vue: 3.5.13(typescript@5.8.3) + '@testing-library/dom': 10.4.0 + '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.0) + '@vitest/mocker': 3.1.3(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0)) + '@vitest/utils': 3.1.3 + magic-string: 0.30.17 + sirv: 3.0.1 + tinyrainbow: 2.0.0 + vitest: 3.1.3(@types/node@22.15.18)(@vitest/browser@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + ws: 8.18.2 + optionalDependencies: + playwright: 1.52.0 + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite - '@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': + '@vitest/browser@3.1.3(playwright@1.52.0)(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vitest@3.1.3)': dependencies: - vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vue: 3.5.13(typescript@5.8.3) + '@testing-library/dom': 10.4.0 + '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.0) + '@vitest/mocker': 3.1.3(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0)) + '@vitest/utils': 3.1.3 + magic-string: 0.30.17 + sirv: 3.0.1 + tinyrainbow: 2.0.0 + vitest: 3.1.3(@types/node@22.15.29)(@vitest/browser@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + ws: 8.18.2 + optionalDependencies: + playwright: 1.52.0 + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite + optional: true - '@vitest/coverage-v8@3.0.8(vitest@3.0.8(@types/node@20.17.24)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))': + '@vitest/coverage-v8@3.0.8(vitest@3.1.3(@types/node@20.17.50)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 - debug: 4.4.0 + debug: 4.4.1 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 istanbul-reports: 3.1.7 magic-string: 0.30.17 magicast: 0.3.5 - std-env: 3.8.1 + std-env: 3.9.0 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.0.8(@types/node@20.17.24)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + vitest: 3.1.3(@types/node@20.17.50)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) transitivePeerDependencies: - supports-color - '@vitest/eslint-plugin@1.1.31(@typescript-eslint/utils@8.30.1(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6)(vitest@3.0.8(@types/node@22.13.10)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))': - dependencies: - '@typescript-eslint/utils': 8.30.1(eslint@8.57.1)(typescript@5.1.6) - eslint: 8.57.1 - optionalDependencies: - typescript: 5.1.6 - vitest: 3.0.8(@types/node@22.13.10)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - - '@vitest/expect@3.0.8': + '@vitest/expect@3.1.3': dependencies: - '@vitest/spy': 3.0.8 - '@vitest/utils': 3.0.8 + '@vitest/spy': 3.1.3 + '@vitest/utils': 3.1.3 chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/expect@3.1.1': + '@vitest/mocker@3.1.3(vite@6.3.5(@types/node@20.17.50)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))': dependencies: - '@vitest/spy': 3.1.1 - '@vitest/utils': 3.1.1 - chai: 5.2.0 - tinyrainbow: 2.0.0 - - '@vitest/mocker@3.0.8(vite@6.2.2(@types/node@20.17.24)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))': - dependencies: - '@vitest/spy': 3.0.8 + '@vitest/spy': 3.1.3 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.2.2(@types/node@20.17.24)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.5(@types/node@20.17.50)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) - '@vitest/mocker@3.0.8(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))': + '@vitest/mocker@3.1.3(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))': dependencies: - '@vitest/spy': 3.0.8 + '@vitest/spy': 3.1.3 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) - '@vitest/mocker@3.1.1(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))': + '@vitest/mocker@3.1.3(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))': dependencies: - '@vitest/spy': 3.1.1 + '@vitest/spy': 3.1.3 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) - '@vitest/pretty-format@3.0.8': + '@vitest/pretty-format@3.1.3': dependencies: tinyrainbow: 2.0.0 - '@vitest/pretty-format@3.1.1': - dependencies: - tinyrainbow: 2.0.0 - - '@vitest/runner@3.0.8': - dependencies: - '@vitest/utils': 3.0.8 - pathe: 2.0.3 - - '@vitest/runner@3.1.1': - dependencies: - '@vitest/utils': 3.1.1 - pathe: 2.0.3 - - '@vitest/snapshot@3.0.8': + '@vitest/runner@3.1.3': dependencies: - '@vitest/pretty-format': 3.0.8 - magic-string: 0.30.17 + '@vitest/utils': 3.1.3 pathe: 2.0.3 - '@vitest/snapshot@3.1.1': + '@vitest/snapshot@3.1.3': dependencies: - '@vitest/pretty-format': 3.1.1 + '@vitest/pretty-format': 3.1.3 magic-string: 0.30.17 pathe: 2.0.3 - '@vitest/spy@3.0.8': - dependencies: - tinyspy: 3.0.2 - - '@vitest/spy@3.1.1': + '@vitest/spy@3.1.3': dependencies: tinyspy: 3.0.2 - '@vitest/utils@3.0.8': - dependencies: - '@vitest/pretty-format': 3.0.8 - loupe: 3.1.3 - tinyrainbow: 2.0.0 - - '@vitest/utils@3.1.1': + '@vitest/utils@3.1.3': dependencies: - '@vitest/pretty-format': 3.1.1 + '@vitest/pretty-format': 3.1.3 loupe: 3.1.3 tinyrainbow: 2.0.0 - '@vitest/web-worker@3.0.8(vitest@3.0.8(@types/node@20.17.24)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))': + '@vitest/web-worker@3.1.4(vitest@3.1.3(@types/node@20.17.50)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))': dependencies: - debug: 4.4.0 - vitest: 3.0.8(@types/node@20.17.24)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + debug: 4.4.1 + vitest: 3.1.3(@types/node@20.17.50)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) transitivePeerDependencies: - supports-color - '@volar/language-core@2.4.12': + '@volar/language-core@2.4.14': dependencies: - '@volar/source-map': 2.4.12 + '@volar/source-map': 2.4.14 - '@volar/source-map@2.4.12': {} + '@volar/source-map@2.4.14': {} - '@volar/typescript@2.4.12': + '@volar/typescript@2.4.14': dependencies: - '@volar/language-core': 2.4.12 + '@volar/language-core': 2.4.14 path-browserify: 1.0.1 vscode-uri: 3.1.0 - '@vue-macros/common@1.16.1(vue@3.5.13(typescript@5.8.3))': + '@vue-macros/common@1.16.1(vue@3.5.14(typescript@5.8.3))': dependencies: - '@vue/compiler-sfc': 3.5.13 - ast-kit: 1.4.2 + '@vue/compiler-sfc': 3.5.14 + ast-kit: 1.4.3 local-pkg: 1.1.1 magic-string-ast: 0.7.1 pathe: 2.0.3 picomatch: 4.0.2 optionalDependencies: - vue: 3.5.13(typescript@5.8.3) + vue: 3.5.14(typescript@5.8.3) '@vue/babel-helper-vue-transform-on@1.4.0': {} - '@vue/babel-plugin-jsx@1.4.0(@babel/core@7.26.10)': + '@vue/babel-plugin-jsx@1.4.0(@babel/core@7.27.1)': dependencies: - '@babel/helper-module-imports': 7.25.9 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.10) - '@babel/template': 7.26.9 - '@babel/traverse': 7.26.10 - '@babel/types': 7.26.10 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.1) + '@babel/template': 7.27.2 + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 '@vue/babel-helper-vue-transform-on': 1.4.0 - '@vue/babel-plugin-resolve-type': 1.4.0(@babel/core@7.26.10) - '@vue/shared': 3.5.13 + '@vue/babel-plugin-resolve-type': 1.4.0(@babel/core@7.27.1) + '@vue/shared': 3.5.14 optionalDependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.27.1 transitivePeerDependencies: - supports-color - '@vue/babel-plugin-resolve-type@1.4.0(@babel/core@7.26.10)': + '@vue/babel-plugin-resolve-type@1.4.0(@babel/core@7.27.1)': dependencies: - '@babel/code-frame': 7.26.2 - '@babel/core': 7.26.10 - '@babel/helper-module-imports': 7.25.9 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/parser': 7.26.10 - '@vue/compiler-sfc': 3.5.13 + '@babel/code-frame': 7.27.1 + '@babel/core': 7.27.1 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/parser': 7.27.2 + '@vue/compiler-sfc': 3.5.14 transitivePeerDependencies: - supports-color - '@vue/compiler-core@3.5.13': + '@vue/compiler-core@3.5.14': dependencies: - '@babel/parser': 7.26.10 - '@vue/shared': 3.5.13 + '@babel/parser': 7.27.2 + '@vue/shared': 3.5.14 entities: 4.5.0 estree-walker: 2.0.2 source-map-js: 1.2.1 - '@vue/compiler-dom@3.5.13': + '@vue/compiler-dom@3.5.14': dependencies: - '@vue/compiler-core': 3.5.13 - '@vue/shared': 3.5.13 + '@vue/compiler-core': 3.5.14 + '@vue/shared': 3.5.14 - '@vue/compiler-sfc@3.5.13': + '@vue/compiler-sfc@3.5.14': dependencies: - '@babel/parser': 7.26.10 - '@vue/compiler-core': 3.5.13 - '@vue/compiler-dom': 3.5.13 - '@vue/compiler-ssr': 3.5.13 - '@vue/shared': 3.5.13 + '@babel/parser': 7.27.2 + '@vue/compiler-core': 3.5.14 + '@vue/compiler-dom': 3.5.14 + '@vue/compiler-ssr': 3.5.14 + '@vue/shared': 3.5.14 estree-walker: 2.0.2 magic-string: 0.30.17 postcss: 8.5.3 source-map-js: 1.2.1 - '@vue/compiler-ssr@3.5.13': + '@vue/compiler-ssr@3.5.14': dependencies: - '@vue/compiler-dom': 3.5.13 - '@vue/shared': 3.5.13 + '@vue/compiler-dom': 3.5.14 + '@vue/shared': 3.5.14 '@vue/compiler-vue2@2.7.16': dependencies: @@ -13641,185 +11434,134 @@ snapshots: '@vue/devtools-api@6.6.4': {} - '@vue/devtools-api@7.7.2': - dependencies: - '@vue/devtools-kit': 7.7.2 - - '@vue/devtools-core@7.7.2(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.1.6))': - dependencies: - '@vue/devtools-kit': 7.7.2 - '@vue/devtools-shared': 7.7.2 - mitt: 3.0.1 - nanoid: 5.1.3 - pathe: 2.0.3 - vite-hot-client: 0.2.4(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) - vue: 3.5.13(typescript@5.1.6) - transitivePeerDependencies: - - vite - - '@vue/devtools-core@7.7.2(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': + '@vue/devtools-api@7.7.6': dependencies: - '@vue/devtools-kit': 7.7.2 - '@vue/devtools-shared': 7.7.2 - mitt: 3.0.1 - nanoid: 5.1.3 - pathe: 2.0.3 - vite-hot-client: 0.2.4(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) - vue: 3.5.13(typescript@5.8.3) - transitivePeerDependencies: - - vite + '@vue/devtools-kit': 7.7.6 - '@vue/devtools-core@7.7.2(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': + '@vue/devtools-core@7.7.6(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3))': dependencies: - '@vue/devtools-kit': 7.7.2 - '@vue/devtools-shared': 7.7.2 + '@vue/devtools-kit': 7.7.6 + '@vue/devtools-shared': 7.7.6 mitt: 3.0.1 - nanoid: 5.1.3 + nanoid: 5.1.5 pathe: 2.0.3 - vite-hot-client: 0.2.4(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) - vue: 3.5.13(typescript@5.8.3) + vite-hot-client: 2.0.4(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0)) + vue: 3.5.14(typescript@5.8.3) transitivePeerDependencies: - vite - '@vue/devtools-kit@7.7.2': + '@vue/devtools-kit@7.7.6': dependencies: - '@vue/devtools-shared': 7.7.2 - birpc: 0.2.19 + '@vue/devtools-shared': 7.7.6 + birpc: 2.3.0 hookable: 5.5.3 mitt: 3.0.1 perfect-debounce: 1.0.0 speakingurl: 14.0.1 superjson: 2.2.2 - '@vue/devtools-shared@7.7.2': + '@vue/devtools-shared@7.7.6': dependencies: rfdc: 1.4.1 - '@vue/eslint-config-prettier@10.2.0(eslint@8.57.1)(prettier@3.5.3)': - dependencies: - eslint: 8.57.1 - eslint-config-prettier: 10.1.1(eslint@8.57.1) - eslint-plugin-prettier: 5.2.3(eslint-config-prettier@10.1.1(eslint@8.57.1))(eslint@8.57.1)(prettier@3.5.3) - prettier: 3.5.3 - transitivePeerDependencies: - - '@types/eslint' - - '@vue/eslint-config-prettier@8.0.0(eslint@8.57.1)(prettier@3.5.3)': + '@vue/eslint-config-prettier@8.0.0(eslint@8.57.0)(prettier@3.5.3)': dependencies: - eslint: 8.57.1 - eslint-config-prettier: 8.10.0(eslint@8.57.1) - eslint-plugin-prettier: 5.2.3(eslint-config-prettier@8.10.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.5.3) + eslint: 8.57.0 + eslint-config-prettier: 8.10.0(eslint@8.57.0) + eslint-plugin-prettier: 5.4.0(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.5.3) prettier: 3.5.3 transitivePeerDependencies: - '@types/eslint' - '@vue/eslint-config-typescript@12.0.0(eslint-plugin-vue@10.0.0(eslint@8.57.1)(vue-eslint-parser@10.1.1(eslint@8.57.1)))(eslint@8.57.1)(typescript@5.1.6)': - dependencies: - '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6) - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.1.6) - eslint: 8.57.1 - eslint-plugin-vue: 10.0.0(eslint@8.57.1)(vue-eslint-parser@10.1.1(eslint@8.57.1)) - vue-eslint-parser: 9.4.3(eslint@8.57.1) - optionalDependencies: - typescript: 5.1.6 - transitivePeerDependencies: - - supports-color - - '@vue/eslint-config-typescript@14.5.0(eslint-plugin-vue@9.33.0(eslint@8.57.1))(eslint@8.57.1)(typescript@5.1.6)': + '@vue/eslint-config-typescript@12.0.0(eslint-plugin-vue@10.1.0(eslint@8.57.0)(vue-eslint-parser@10.1.3(eslint@8.57.0)))(eslint@8.57.0)(typescript@5.1.6)': dependencies: - '@typescript-eslint/utils': 8.26.1(eslint@8.57.1)(typescript@5.1.6) - eslint: 8.57.1 - eslint-plugin-vue: 9.33.0(eslint@8.57.1) - fast-glob: 3.3.3 - typescript-eslint: 8.26.1(eslint@8.57.1)(typescript@5.1.6) - vue-eslint-parser: 10.1.1(eslint@8.57.1) + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0)(typescript@5.1.6) + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.1.6) + eslint: 8.57.0 + eslint-plugin-vue: 10.1.0(eslint@8.57.0)(vue-eslint-parser@10.1.3(eslint@8.57.0)) + vue-eslint-parser: 9.4.3(eslint@8.57.0) optionalDependencies: typescript: 5.1.6 transitivePeerDependencies: - supports-color - '@vue/language-core@2.2.8(typescript@5.1.6)': + '@vue/language-core@2.2.10(typescript@5.1.6)': dependencies: - '@volar/language-core': 2.4.12 - '@vue/compiler-dom': 3.5.13 + '@volar/language-core': 2.4.14 + '@vue/compiler-dom': 3.5.14 '@vue/compiler-vue2': 2.7.16 - '@vue/shared': 3.5.13 - alien-signals: 1.0.4 + '@vue/shared': 3.5.14 + alien-signals: 1.0.13 minimatch: 9.0.5 muggle-string: 0.4.1 path-browserify: 1.0.1 optionalDependencies: typescript: 5.1.6 - '@vue/language-core@2.2.8(typescript@5.8.3)': + '@vue/language-core@2.2.10(typescript@5.8.3)': dependencies: - '@volar/language-core': 2.4.12 - '@vue/compiler-dom': 3.5.13 + '@volar/language-core': 2.4.14 + '@vue/compiler-dom': 3.5.14 '@vue/compiler-vue2': 2.7.16 - '@vue/shared': 3.5.13 - alien-signals: 1.0.4 + '@vue/shared': 3.5.14 + alien-signals: 1.0.13 minimatch: 9.0.5 muggle-string: 0.4.1 path-browserify: 1.0.1 optionalDependencies: typescript: 5.8.3 - '@vue/reactivity@3.5.13': + '@vue/reactivity@3.5.14': dependencies: - '@vue/shared': 3.5.13 + '@vue/shared': 3.5.14 - '@vue/runtime-core@3.5.13': + '@vue/runtime-core@3.5.14': dependencies: - '@vue/reactivity': 3.5.13 - '@vue/shared': 3.5.13 + '@vue/reactivity': 3.5.14 + '@vue/shared': 3.5.14 - '@vue/runtime-dom@3.5.13': + '@vue/runtime-dom@3.5.14': dependencies: - '@vue/reactivity': 3.5.13 - '@vue/runtime-core': 3.5.13 - '@vue/shared': 3.5.13 + '@vue/reactivity': 3.5.14 + '@vue/runtime-core': 3.5.14 + '@vue/shared': 3.5.14 csstype: 3.1.3 - '@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.1.6))': + '@vue/server-renderer@3.5.14(vue@3.5.14(typescript@5.1.6))': dependencies: - '@vue/compiler-ssr': 3.5.13 - '@vue/shared': 3.5.13 - vue: 3.5.13(typescript@5.1.6) + '@vue/compiler-ssr': 3.5.14 + '@vue/shared': 3.5.14 + vue: 3.5.14(typescript@5.1.6) - '@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.8.3))': + '@vue/server-renderer@3.5.14(vue@3.5.14(typescript@5.8.3))': dependencies: - '@vue/compiler-ssr': 3.5.13 - '@vue/shared': 3.5.13 - vue: 3.5.13(typescript@5.8.3) + '@vue/compiler-ssr': 3.5.14 + '@vue/shared': 3.5.14 + vue: 3.5.14(typescript@5.8.3) - '@vue/shared@3.5.13': {} + '@vue/shared@3.5.14': {} '@vue/test-utils@2.4.6': dependencies: js-beautify: 1.15.4 - vue-component-type-helpers: 2.2.8 - - '@vue/tsconfig@0.7.0(typescript@5.1.6)(vue@3.5.13(typescript@5.1.6))': - optionalDependencies: - typescript: 5.1.6 - vue: 3.5.13(typescript@5.1.6) + vue-component-type-helpers: 2.2.10 '@vueuse/core@12.8.2(typescript@5.8.3)': dependencies: '@types/web-bluetooth': 0.0.21 '@vueuse/metadata': 12.8.2 '@vueuse/shared': 12.8.2(typescript@5.8.3) - vue: 3.5.13(typescript@5.8.3) + vue: 3.5.14(typescript@5.8.3) transitivePeerDependencies: - typescript - '@vueuse/integrations@12.8.2(axios@1.8.4)(focus-trap@7.6.4)(fuse.js@7.1.0)(jwt-decode@4.0.0)(typescript@5.8.3)': + '@vueuse/integrations@12.8.2(axios@1.9.0)(focus-trap@7.6.4)(fuse.js@7.1.0)(jwt-decode@4.0.0)(typescript@5.8.3)': dependencies: '@vueuse/core': 12.8.2(typescript@5.8.3) '@vueuse/shared': 12.8.2(typescript@5.8.3) - vue: 3.5.13(typescript@5.8.3) + vue: 3.5.14(typescript@5.8.3) optionalDependencies: - axios: 1.8.4 + axios: 1.9.0 focus-trap: 7.6.4 fuse.js: 7.1.0 jwt-decode: 4.0.0 @@ -13830,7 +11572,7 @@ snapshots: '@vueuse/shared@12.8.2(typescript@5.8.3)': dependencies: - vue: 3.5.13(typescript@5.8.3) + vue: 3.5.14(typescript@5.8.3) transitivePeerDependencies: - typescript @@ -13839,12 +11581,12 @@ snapshots: '@whatwg-node/promise-helpers': 1.3.2 tslib: 2.8.1 - '@whatwg-node/fetch@0.10.7': + '@whatwg-node/fetch@0.10.8': dependencies: - '@whatwg-node/node-fetch': 0.7.19 + '@whatwg-node/node-fetch': 0.7.21 urlpattern-polyfill: 10.1.0 - '@whatwg-node/node-fetch@0.7.19': + '@whatwg-node/node-fetch@0.7.21': dependencies: '@fastify/busboy': 3.1.1 '@whatwg-node/disposablestack': 0.0.6 @@ -13858,34 +11600,34 @@ snapshots: '@whatwg-node/server@0.9.71': dependencies: '@whatwg-node/disposablestack': 0.0.6 - '@whatwg-node/fetch': 0.10.7 + '@whatwg-node/fetch': 0.10.8 '@whatwg-node/promise-helpers': 1.3.2 tslib: 2.8.1 - '@wso2/eslint-plugin@https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/eslint-plugin?4ee6f6be232d7631999d709a86b91612f1d34ce7(eslint@8.57.1)(typescript@5.1.6)': - dependencies: - '@babel/core': 7.26.10 - '@babel/eslint-parser': 7.26.10(@babel/core@7.26.10)(eslint@8.57.1) - '@next/eslint-plugin-next': 13.5.8 - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6) - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.1.6) - eslint: 8.57.1 - eslint-config-airbnb: 19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.4(eslint@8.57.1))(eslint@8.57.1) - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1))(eslint@8.57.1) - eslint-config-airbnb-typescript: 17.1.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1))(eslint@8.57.1) - eslint-config-prettier: 8.10.0(eslint@8.57.1) - eslint-plugin-eslint-plugin: 5.5.1(eslint@8.57.1) - eslint-plugin-header: 3.1.1(eslint@8.57.1) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1) - eslint-plugin-jest: 27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6) - eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) - eslint-plugin-node: 11.1.0(eslint@8.57.1) - eslint-plugin-prettier: 4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8) - eslint-plugin-react: 7.37.4(eslint@8.57.1) - eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) - eslint-plugin-testing-library: 5.11.1(eslint@8.57.1)(typescript@5.1.6) + '@wso2/eslint-plugin@https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/eslint-plugin?a1fc6eb570653c999828aea9f5027cba06af4391(eslint@8.57.0)(typescript@5.1.6)': + dependencies: + '@babel/core': 7.27.1 + '@babel/eslint-parser': 7.27.1(@babel/core@7.27.1)(eslint@8.57.0) + '@next/eslint-plugin-next': 13.5.11 + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0)(typescript@5.1.6) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.1.6) + eslint: 8.57.0 + eslint-config-airbnb: 19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.37.5(eslint@8.57.0))(eslint@8.57.0) + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0))(eslint@8.57.0) + eslint-config-airbnb-typescript: 17.1.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0)(typescript@5.1.6))(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0))(eslint@8.57.0) + eslint-config-prettier: 8.10.0(eslint@8.57.0) + eslint-plugin-eslint-plugin: 5.5.1(eslint@8.57.0) + eslint-plugin-header: 3.1.1(eslint@8.57.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0) + eslint-plugin-jest: 27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0)(typescript@5.1.6) + eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.0) + eslint-plugin-node: 11.1.0(eslint@8.57.0) + eslint-plugin-prettier: 4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@8.57.0)(prettier@2.8.8) + eslint-plugin-react: 7.37.5(eslint@8.57.0) + eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) + eslint-plugin-testing-library: 5.11.1(eslint@8.57.0)(typescript@5.1.6) eslint-plugin-tsdoc: 0.2.17 - eslint-plugin-typescript-sort-keys: 2.3.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6) + eslint-plugin-typescript-sort-keys: 2.3.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0)(typescript@5.1.6) prettier: 2.8.8 requireindex: 1.2.0 optionalDependencies: @@ -13896,13 +11638,53 @@ snapshots: - jest - supports-color - '@wso2/prettier-config@https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/prettier-config?4ee6f6be232d7631999d709a86b91612f1d34ce7(prettier@3.5.3)(typescript@5.1.6)': + '@wso2/eslint-plugin@https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/eslint-plugin?a1fc6eb570653c999828aea9f5027cba06af4391(eslint@8.57.0)(typescript@5.7.3)': + dependencies: + '@babel/core': 7.27.1 + '@babel/eslint-parser': 7.27.1(@babel/core@7.27.1)(eslint@8.57.0) + '@next/eslint-plugin-next': 13.5.11 + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0)(typescript@5.7.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.7.3) + eslint: 8.57.0 + eslint-config-airbnb: 19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.37.5(eslint@8.57.0))(eslint@8.57.0) + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0))(eslint@8.57.0) + eslint-config-airbnb-typescript: 17.1.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0)(typescript@5.7.3))(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0))(eslint@8.57.0) + eslint-config-prettier: 8.10.0(eslint@8.57.0) + eslint-plugin-eslint-plugin: 5.5.1(eslint@8.57.0) + eslint-plugin-header: 3.1.1(eslint@8.57.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0) + eslint-plugin-jest: 27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0)(typescript@5.7.3) + eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.0) + eslint-plugin-node: 11.1.0(eslint@8.57.0) + eslint-plugin-prettier: 4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@8.57.0)(prettier@2.8.8) + eslint-plugin-react: 7.37.5(eslint@8.57.0) + eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) + eslint-plugin-testing-library: 5.11.1(eslint@8.57.0)(typescript@5.7.3) + eslint-plugin-tsdoc: 0.2.17 + eslint-plugin-typescript-sort-keys: 2.3.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0)(typescript@5.7.3) + prettier: 2.8.8 + requireindex: 1.2.0 + optionalDependencies: + typescript: 5.7.3 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - jest + - supports-color + + '@wso2/prettier-config@https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/prettier-config?a1fc6eb570653c999828aea9f5027cba06af4391(prettier@2.8.8)(typescript@5.7.3)': + dependencies: + prettier: 2.8.8 + optionalDependencies: + typescript: 5.7.3 + + '@wso2/prettier-config@https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/prettier-config?a1fc6eb570653c999828aea9f5027cba06af4391(prettier@3.5.3)(typescript@5.1.6)': dependencies: prettier: 3.5.3 optionalDependencies: typescript: 5.1.6 - '@wso2/stylelint-config@https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/stylelint-config?4ee6f6be232d7631999d709a86b91612f1d34ce7(postcss@8.5.3)(stylelint@15.1.0(typescript@5.1.6))(typescript@5.1.6)': + '@wso2/stylelint-config@https://gitpkg.vercel.app/brionmario/wso2-ui-configs/packages/stylelint-config?a1fc6eb570653c999828aea9f5027cba06af4391(postcss@8.5.3)(stylelint@15.1.0(typescript@5.1.6))(typescript@5.1.6)': dependencies: postcss-scss: 4.0.9(postcss@8.5.3) stylelint: 15.1.0(typescript@5.1.6) @@ -13914,20 +11696,18 @@ snapshots: '@yarnpkg/lockfile@1.1.0': {} - '@yarnpkg/parsers@3.0.0-rc.46': + '@yarnpkg/parsers@3.0.2': dependencies: js-yaml: 3.14.1 tslib: 2.8.1 - '@zkochan/js-yaml@0.0.6': + '@zkochan/js-yaml@0.0.7': dependencies: argparse: 2.0.1 - abbrev@1.1.1: {} - abbrev@2.0.0: {} - abbrev@3.0.0: {} + abbrev@3.0.1: {} abort-controller@3.0.0: dependencies: @@ -13943,12 +11723,6 @@ snapshots: acorn@8.14.1: {} - agent-base@6.0.2: - dependencies: - debug: 4.4.0 - transitivePeerDependencies: - - supports-color - agent-base@7.1.3: {} ajv@6.12.6: @@ -13965,23 +11739,23 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - algoliasearch@5.21.0: + algoliasearch@5.25.0: dependencies: - '@algolia/client-abtesting': 5.21.0 - '@algolia/client-analytics': 5.21.0 - '@algolia/client-common': 5.21.0 - '@algolia/client-insights': 5.21.0 - '@algolia/client-personalization': 5.21.0 - '@algolia/client-query-suggestions': 5.21.0 - '@algolia/client-search': 5.21.0 - '@algolia/ingestion': 1.21.0 - '@algolia/monitoring': 1.21.0 - '@algolia/recommend': 5.21.0 - '@algolia/requester-browser-xhr': 5.21.0 - '@algolia/requester-fetch': 5.21.0 - '@algolia/requester-node-http': 5.21.0 + '@algolia/client-abtesting': 5.25.0 + '@algolia/client-analytics': 5.25.0 + '@algolia/client-common': 5.25.0 + '@algolia/client-insights': 5.25.0 + '@algolia/client-personalization': 5.25.0 + '@algolia/client-query-suggestions': 5.25.0 + '@algolia/client-search': 5.25.0 + '@algolia/ingestion': 1.25.0 + '@algolia/monitoring': 1.25.0 + '@algolia/recommend': 5.25.0 + '@algolia/requester-browser-xhr': 5.25.0 + '@algolia/requester-fetch': 5.25.0 + '@algolia/requester-node-http': 5.25.0 - alien-signals@1.0.4: {} + alien-signals@1.0.13: {} ansi-colors@4.1.3: {} @@ -14004,34 +11778,6 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.1 - aproba@2.0.0: {} - - archiver-utils@2.1.0: - dependencies: - glob: 7.2.3 - graceful-fs: 4.2.11 - lazystream: 1.0.1 - lodash.defaults: 4.2.0 - lodash.difference: 4.5.0 - lodash.flatten: 4.4.0 - lodash.isplainobject: 4.0.6 - lodash.union: 4.6.0 - normalize-path: 3.0.0 - readable-stream: 2.3.8 - - archiver-utils@3.0.4: - dependencies: - glob: 7.2.3 - graceful-fs: 4.2.11 - lazystream: 1.0.1 - lodash.defaults: 4.2.0 - lodash.difference: 4.5.0 - lodash.flatten: 4.4.0 - lodash.isplainobject: 4.0.6 - lodash.union: 4.6.0 - normalize-path: 3.0.0 - readable-stream: 3.6.2 - archiver-utils@5.0.2: dependencies: glob: 10.4.5 @@ -14042,16 +11788,6 @@ snapshots: normalize-path: 3.0.0 readable-stream: 4.7.0 - archiver@5.3.2: - dependencies: - archiver-utils: 2.1.0 - async: 3.2.6 - buffer-crc32: 0.2.13 - readable-stream: 3.6.2 - readdir-glob: 1.1.3 - tar-stream: 2.2.0 - zip-stream: 4.1.1 - archiver@7.0.1: dependencies: archiver-utils: 5.0.2 @@ -14064,17 +11800,16 @@ snapshots: are-docs-informative@0.0.2: {} - are-we-there-yet@2.0.0: - dependencies: - delegates: 1.0.0 - readable-stream: 3.6.2 - argparse@1.0.10: dependencies: sprintf-js: 1.0.3 argparse@2.0.1: {} + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + aria-query@5.3.2: {} array-buffer-byte-length@1.0.2: @@ -14148,38 +11883,28 @@ snapshots: asn1.js@4.10.1: dependencies: - bn.js: 4.12.1 + bn.js: 4.12.2 inherits: 2.0.4 minimalistic-assert: 1.0.1 - assert@2.1.0: - dependencies: - call-bind: 1.0.8 - is-nan: 1.3.2 - object-is: 1.1.6 - object.assign: 4.1.7 - util: 0.12.5 - assertion-error@2.0.1: {} - ast-kit@1.4.2: + ast-kit@1.4.3: dependencies: - '@babel/parser': 7.26.10 + '@babel/parser': 7.27.2 pathe: 2.0.3 - ast-module-types@5.0.0: {} + ast-module-types@6.0.1: {} ast-types-flow@0.0.8: {} ast-walker-scope@0.6.2: dependencies: - '@babel/parser': 7.26.10 - ast-kit: 1.4.2 + '@babel/parser': 7.27.2 + ast-kit: 1.4.3 astral-regex@2.0.0: {} - astring@1.9.0: {} - async-function@1.0.0: {} async-sema@3.1.1: {} @@ -14190,8 +11915,8 @@ snapshots: autoprefixer@10.4.21(postcss@8.5.3): dependencies: - browserslist: 4.24.4 - caniuse-lite: 1.0.30001704 + browserslist: 4.24.5 + caniuse-lite: 1.0.30001718 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 @@ -14212,33 +11937,18 @@ snapshots: transitivePeerDependencies: - debug - axios@1.8.3: - dependencies: - follow-redirects: 1.15.9 - form-data: 4.0.2 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - - axios@1.8.4: + axios@1.9.0: dependencies: follow-redirects: 1.15.9 form-data: 4.0.2 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug - optional: true axobject-query@4.1.0: {} b4a@1.6.7: {} - babel-plugin-macros@3.1.0: - dependencies: - '@babel/runtime': 7.26.10 - cosmiconfig: 7.1.0 - resolve: 1.22.10 - balanced-match@1.0.2: {} balanced-match@2.0.0: {} @@ -14258,8 +11968,6 @@ snapshots: dependencies: file-uri-to-path: 1.0.0 - birpc@0.2.19: {} - birpc@2.3.0: {} bl@4.1.0: @@ -14268,9 +11976,9 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - bn.js@4.12.1: {} + bn.js@4.12.2: {} - bn.js@5.2.1: {} + bn.js@5.2.2: {} boolbase@1.0.0: {} @@ -14289,10 +11997,6 @@ snapshots: brorand@1.1.0: {} - browser-resolve@2.0.0: - dependencies: - resolve: 1.22.10 - browserify-aes@1.2.0: dependencies: buffer-xor: 1.0.3 @@ -14317,13 +12021,13 @@ snapshots: browserify-rsa@4.1.1: dependencies: - bn.js: 5.2.1 + bn.js: 5.2.2 randombytes: 2.1.0 safe-buffer: 5.2.1 browserify-sign@4.2.3: dependencies: - bn.js: 5.2.1 + bn.js: 5.2.2 browserify-rsa: 4.1.1 create-hash: 1.2.0 create-hmac: 1.1.7 @@ -14334,17 +12038,6 @@ snapshots: readable-stream: 2.3.8 safe-buffer: 5.2.1 - browserify-zlib@0.2.0: - dependencies: - pako: 1.0.11 - - browserslist@4.24.4: - dependencies: - caniuse-lite: 1.0.30001704 - electron-to-chromium: 1.5.118 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.24.4) - browserslist@4.24.5: dependencies: caniuse-lite: 1.0.30001718 @@ -14374,19 +12067,21 @@ snapshots: builtin-modules@5.0.0: {} - builtin-status-codes@3.0.0: {} - bundle-name@4.1.0: dependencies: run-applescript: 7.0.0 - c12@3.0.3(magicast@0.3.5): + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + + c12@3.0.4(magicast@0.3.5): dependencies: chokidar: 4.0.3 confbox: 0.2.2 defu: 6.1.4 - dotenv: 16.4.7 - exsolve: 1.0.4 + dotenv: 16.5.0 + exsolve: 1.0.5 giget: 2.0.0 jiti: 2.4.2 ohash: 2.0.11 @@ -14430,13 +12125,11 @@ snapshots: caniuse-api@3.0.0: dependencies: - browserslist: 4.24.4 - caniuse-lite: 1.0.30001704 + browserslist: 4.24.5 + caniuse-lite: 1.0.30001718 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 - caniuse-lite@1.0.30001704: {} - caniuse-lite@1.0.30001718: {} ccount@2.0.1: {} @@ -14456,19 +12149,19 @@ snapshots: changelogen@0.6.1(magicast@0.3.5): dependencies: - c12: 3.0.3(magicast@0.3.5) + c12: 3.0.4(magicast@0.3.5) confbox: 0.2.2 consola: 3.4.2 convert-gitmoji: 0.1.5 mri: 1.2.0 node-fetch-native: 1.6.6 ofetch: 1.4.1 - open: 10.1.0 + open: 10.1.2 pathe: 2.0.3 pkg-types: 2.1.0 scule: 1.3.0 - semver: 7.7.1 - std-env: 3.8.1 + semver: 7.7.2 + std-env: 3.9.0 transitivePeerDependencies: - magicast @@ -14484,8 +12177,6 @@ snapshots: dependencies: readdirp: 4.1.2 - chownr@2.0.0: {} - chownr@3.0.0: {} ci-info@3.9.0: {} @@ -14511,6 +12202,8 @@ snapshots: cli-spinners@2.6.1: {} + client-only@0.0.1: {} + clipboardy@4.0.0: dependencies: execa: 8.0.1 @@ -14525,8 +12218,6 @@ snapshots: clone@1.0.4: {} - clsx@1.2.1: {} - clsx@2.1.1: {} cluster-key-slot@1.1.2: {} @@ -14548,13 +12239,17 @@ snapshots: color-name: 1.1.4 simple-swizzle: 0.2.2 - color-support@1.1.3: {} - color@3.2.1: dependencies: color-convert: 1.9.3 color-string: 1.9.1 + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + optional: true + colord@2.9.3: {} colorspace@1.1.4: @@ -14570,6 +12265,8 @@ snapshots: commander@10.0.1: {} + commander@12.1.0: {} + commander@2.20.3: {} commander@7.2.0: {} @@ -14580,17 +12277,8 @@ snapshots: commondir@1.0.1: {} - compatx@0.1.8: {} - compatx@0.2.0: {} - compress-commons@4.1.2: - dependencies: - buffer-crc32: 0.2.13 - crc32-stream: 4.0.3 - normalize-path: 3.0.0 - readable-stream: 3.6.2 - compress-commons@6.0.2: dependencies: crc-32: 1.2.2 @@ -14614,16 +12302,8 @@ snapshots: consola@3.4.2: {} - console-browserify@1.2.0: {} - - console-control-strings@1.1.0: {} - - constants-browserify@1.0.0: {} - convert-gitmoji@0.1.5: {} - convert-source-map@1.9.0: {} - convert-source-map@2.0.0: {} cookie-es@1.2.2: {} @@ -14636,9 +12316,16 @@ snapshots: dependencies: is-what: 4.1.16 - core-js-compat@3.41.0: + copy-file@11.0.0: + dependencies: + graceful-fs: 4.2.11 + p-event: 6.0.1 + + core-js-compat@3.42.0: dependencies: - browserslist: 4.24.4 + browserslist: 4.24.5 + + core-js@3.42.0: {} core-util-is@1.0.3: {} @@ -14659,19 +12346,8 @@ snapshots: optionalDependencies: typescript: 5.1.6 - cp-file@10.0.0: - dependencies: - graceful-fs: 4.2.11 - nested-error-stacks: 2.1.1 - p-event: 5.0.1 - crc-32@1.2.2: {} - crc32-stream@4.0.3: - dependencies: - crc-32: 1.2.2 - readable-stream: 3.6.2 - crc32-stream@6.0.0: dependencies: crc-32: 1.2.2 @@ -14679,7 +12355,7 @@ snapshots: create-ecdh@4.0.4: dependencies: - bn.js: 4.12.1 + bn.js: 4.12.2 elliptic: 6.6.1 create-hash@1.2.0: @@ -14699,8 +12375,6 @@ snapshots: safe-buffer: 5.2.1 sha.js: 2.4.11 - create-require@1.1.1: {} - cron-parser@4.9.0: dependencies: luxon: 3.6.1 @@ -14713,16 +12387,18 @@ snapshots: transitivePeerDependencies: - encoding + cross-fetch@4.1.0: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 - crossws@0.3.4: - dependencies: - uncrypto: 0.1.3 - crossws@0.3.5: dependencies: uncrypto: 0.1.3 @@ -14820,40 +12496,6 @@ snapshots: postcss-svgo: 5.1.0(postcss@8.5.3) postcss-unique-selectors: 5.1.1(postcss@8.5.3) - cssnano-preset-default@7.0.6(postcss@8.5.3): - dependencies: - browserslist: 4.24.4 - css-declaration-sorter: 7.2.0(postcss@8.5.3) - cssnano-utils: 5.0.0(postcss@8.5.3) - postcss: 8.5.3 - postcss-calc: 10.1.1(postcss@8.5.3) - postcss-colormin: 7.0.2(postcss@8.5.3) - postcss-convert-values: 7.0.4(postcss@8.5.3) - postcss-discard-comments: 7.0.3(postcss@8.5.3) - postcss-discard-duplicates: 7.0.1(postcss@8.5.3) - postcss-discard-empty: 7.0.0(postcss@8.5.3) - postcss-discard-overridden: 7.0.0(postcss@8.5.3) - postcss-merge-longhand: 7.0.4(postcss@8.5.3) - postcss-merge-rules: 7.0.4(postcss@8.5.3) - postcss-minify-font-values: 7.0.0(postcss@8.5.3) - postcss-minify-gradients: 7.0.0(postcss@8.5.3) - postcss-minify-params: 7.0.2(postcss@8.5.3) - postcss-minify-selectors: 7.0.4(postcss@8.5.3) - postcss-normalize-charset: 7.0.0(postcss@8.5.3) - postcss-normalize-display-values: 7.0.0(postcss@8.5.3) - postcss-normalize-positions: 7.0.0(postcss@8.5.3) - postcss-normalize-repeat-style: 7.0.0(postcss@8.5.3) - postcss-normalize-string: 7.0.0(postcss@8.5.3) - postcss-normalize-timing-functions: 7.0.0(postcss@8.5.3) - postcss-normalize-unicode: 7.0.2(postcss@8.5.3) - postcss-normalize-url: 7.0.0(postcss@8.5.3) - postcss-normalize-whitespace: 7.0.0(postcss@8.5.3) - postcss-ordered-values: 7.0.1(postcss@8.5.3) - postcss-reduce-initial: 7.0.2(postcss@8.5.3) - postcss-reduce-transforms: 7.0.0(postcss@8.5.3) - postcss-svgo: 7.0.1(postcss@8.5.3) - postcss-unique-selectors: 7.0.3(postcss@8.5.3) - cssnano-preset-default@7.0.7(postcss@8.5.3): dependencies: browserslist: 4.24.5 @@ -14892,10 +12534,6 @@ snapshots: dependencies: postcss: 8.5.3 - cssnano-utils@5.0.0(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - cssnano-utils@5.0.1(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -14907,12 +12545,6 @@ snapshots: postcss: 8.5.3 yaml: 1.10.2 - cssnano@7.0.6(postcss@8.5.3): - dependencies: - cssnano-preset-default: 7.0.6(postcss@8.5.3) - lilconfig: 3.1.3 - postcss: 8.5.3 - cssnano@7.0.7(postcss@8.5.3): dependencies: cssnano-preset-default: 7.0.7(postcss@8.5.3) @@ -14927,10 +12559,11 @@ snapshots: dependencies: css-tree: 2.2.1 - cssstyle@4.3.0: + cssstyle@4.3.1: dependencies: - '@asamuzakjp/css-color': 3.1.1 + '@asamuzakjp/css-color': 3.1.7 rrweb-cssom: 0.8.0 + optional: true csstype@3.1.3: {} @@ -14942,6 +12575,7 @@ snapshots: dependencies: whatwg-mimetype: 4.0.0 whatwg-url: 14.2.0 + optional: true data-view-buffer@1.0.2: dependencies: @@ -14963,21 +12597,15 @@ snapshots: dataloader@1.4.0: {} - db0@0.3.1: {} - db0@0.3.2: {} de-indent@1.0.2: {} - debug@2.6.9: - dependencies: - ms: 2.0.0 - debug@3.2.7: dependencies: ms: 2.1.3 - debug@4.4.0: + debug@4.4.1: dependencies: ms: 2.1.3 @@ -14992,7 +12620,8 @@ snapshots: decamelize@1.2.0: {} - decimal.js@10.5.0: {} + decimal.js@10.5.0: + optional: true decode-uri-component@0.2.2: {} @@ -15033,8 +12662,6 @@ snapshots: delayed-stream@1.0.0: {} - delegates@1.0.0: {} - denque@2.1.0: {} depd@2.0.0: {} @@ -15048,53 +12675,64 @@ snapshots: destr@2.0.5: {} - destroy@1.2.0: {} - detect-indent@6.1.0: {} detect-libc@1.0.3: {} - detect-libc@2.0.3: {} + detect-libc@2.0.4: {} - detective-amd@5.0.2: + detective-amd@6.0.1: dependencies: - ast-module-types: 5.0.0 + ast-module-types: 6.0.1 escodegen: 2.1.0 - get-amd-module-type: 5.0.1 - node-source-walk: 6.0.2 + get-amd-module-type: 6.0.1 + node-source-walk: 7.0.1 - detective-cjs@5.0.1: + detective-cjs@6.0.1: dependencies: - ast-module-types: 5.0.0 - node-source-walk: 6.0.2 + ast-module-types: 6.0.1 + node-source-walk: 7.0.1 - detective-es6@4.0.1: + detective-es6@5.0.1: dependencies: - node-source-walk: 6.0.2 + node-source-walk: 7.0.1 - detective-postcss@6.1.3: + detective-postcss@7.0.1(postcss@8.5.3): dependencies: is-url: 1.2.4 postcss: 8.5.3 postcss-values-parser: 6.0.2(postcss@8.5.3) - detective-sass@5.0.3: + detective-sass@6.0.1: dependencies: gonzales-pe: 4.3.0 - node-source-walk: 6.0.2 + node-source-walk: 7.0.1 - detective-scss@4.0.3: + detective-scss@5.0.1: dependencies: gonzales-pe: 4.3.0 - node-source-walk: 6.0.2 + node-source-walk: 7.0.1 - detective-stylus@4.0.0: {} + detective-stylus@5.0.1: {} - detective-typescript@11.2.0: + detective-typescript@14.0.0(typescript@5.8.3): dependencies: - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.8.3) - ast-module-types: 5.0.0 - node-source-walk: 6.0.2 + '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.8.3) + ast-module-types: 6.0.1 + node-source-walk: 7.0.1 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + detective-vue2@2.2.0(typescript@5.8.3): + dependencies: + '@dependents/detective-less': 5.0.1 + '@vue/compiler-sfc': 3.5.14 + detective-es6: 5.0.1 + detective-sass: 6.0.1 + detective-scss: 5.0.1 + detective-stylus: 5.0.1 + detective-typescript: 14.0.0(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -15111,7 +12749,7 @@ snapshots: diffie-hellman@5.0.3: dependencies: - bn.js: 4.12.1 + bn.js: 4.12.2 miller-rabin: 4.0.1 randombytes: 2.1.0 @@ -15127,10 +12765,7 @@ snapshots: dependencies: esutils: 2.0.3 - dom-helpers@5.2.1: - dependencies: - '@babel/runtime': 7.26.10 - csstype: 3.1.3 + dom-accessibility-api@0.5.16: {} dom-serializer@1.4.1: dependencies: @@ -15146,8 +12781,6 @@ snapshots: dom-walk@0.1.2: {} - domain-browser@4.22.0: {} - domelementtype@2.3.0: {} domhandler@4.3.1: @@ -15172,14 +12805,16 @@ snapshots: dot-prop@9.0.0: dependencies: - type-fest: 4.39.1 + type-fest: 4.41.0 - dotenv-expand@10.0.0: {} - - dotenv@16.3.2: {} + dotenv-expand@11.0.7: + dependencies: + dotenv: 16.4.7 dotenv@16.4.7: {} + dotenv@16.5.0: {} + dotenv@8.6.0: {} dunder-proto@1.0.1: @@ -15197,17 +12832,15 @@ snapshots: '@one-ini/wasm': 0.1.1 commander: 10.0.1 minimatch: 9.0.1 - semver: 7.7.1 + semver: 7.7.2 ee-first@1.1.1: {} - electron-to-chromium@1.5.118: {} - electron-to-chromium@1.5.155: {} elliptic@6.6.1: dependencies: - bn.js: 4.12.1 + bn.js: 4.12.2 brorand: 1.1.0 hash.js: 1.1.7 hmac-drbg: 1.0.1 @@ -15223,8 +12856,6 @@ snapshots: enabled@2.0.0: {} - encodeurl@1.0.2: {} - encodeurl@2.0.0: {} end-of-stream@1.4.4: @@ -15234,7 +12865,7 @@ snapshots: enhanced-resolve@5.18.1: dependencies: graceful-fs: 4.2.11 - tapable: 2.2.1 + tapable: 2.2.2 enquirer@2.3.6: dependencies: @@ -15249,14 +12880,15 @@ snapshots: entities@4.5.0: {} + entities@6.0.0: + optional: true + env-paths@3.0.0: {} error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 - error-stack-parser-es@0.1.5: {} - error-stack-parser-es@1.0.5: {} errx@0.1.0: {} @@ -15338,8 +12970,6 @@ snapshots: iterator.prototype: 1.1.5 safe-array-concat: 1.1.3 - es-module-lexer@1.6.0: {} - es-module-lexer@1.7.0: {} es-object-atoms@1.1.1: @@ -15363,6 +12993,23 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 + esbuild-plugin-polyfill-node@0.3.0(esbuild@0.25.4): + dependencies: + '@jspm/core': 2.1.0 + esbuild: 0.25.4 + import-meta-resolve: 3.1.1 + + esbuild-plugin-preserve-directives@0.0.11(esbuild@0.25.4): + dependencies: + esbuild: 0.25.4 + + esbuild-plugins-node-modules-polyfill@1.7.0(esbuild@0.25.4): + dependencies: + '@jspm/core': 2.1.0 + esbuild: 0.25.4 + local-pkg: 1.1.1 + resolve.exports: 2.0.3 + esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -15389,62 +13036,6 @@ snapshots: '@esbuild/win32-ia32': 0.21.5 '@esbuild/win32-x64': 0.21.5 - esbuild@0.25.1: - optionalDependencies: - '@esbuild/aix-ppc64': 0.25.1 - '@esbuild/android-arm': 0.25.1 - '@esbuild/android-arm64': 0.25.1 - '@esbuild/android-x64': 0.25.1 - '@esbuild/darwin-arm64': 0.25.1 - '@esbuild/darwin-x64': 0.25.1 - '@esbuild/freebsd-arm64': 0.25.1 - '@esbuild/freebsd-x64': 0.25.1 - '@esbuild/linux-arm': 0.25.1 - '@esbuild/linux-arm64': 0.25.1 - '@esbuild/linux-ia32': 0.25.1 - '@esbuild/linux-loong64': 0.25.1 - '@esbuild/linux-mips64el': 0.25.1 - '@esbuild/linux-ppc64': 0.25.1 - '@esbuild/linux-riscv64': 0.25.1 - '@esbuild/linux-s390x': 0.25.1 - '@esbuild/linux-x64': 0.25.1 - '@esbuild/netbsd-arm64': 0.25.1 - '@esbuild/netbsd-x64': 0.25.1 - '@esbuild/openbsd-arm64': 0.25.1 - '@esbuild/openbsd-x64': 0.25.1 - '@esbuild/sunos-x64': 0.25.1 - '@esbuild/win32-arm64': 0.25.1 - '@esbuild/win32-ia32': 0.25.1 - '@esbuild/win32-x64': 0.25.1 - - esbuild@0.25.2: - optionalDependencies: - '@esbuild/aix-ppc64': 0.25.2 - '@esbuild/android-arm': 0.25.2 - '@esbuild/android-arm64': 0.25.2 - '@esbuild/android-x64': 0.25.2 - '@esbuild/darwin-arm64': 0.25.2 - '@esbuild/darwin-x64': 0.25.2 - '@esbuild/freebsd-arm64': 0.25.2 - '@esbuild/freebsd-x64': 0.25.2 - '@esbuild/linux-arm': 0.25.2 - '@esbuild/linux-arm64': 0.25.2 - '@esbuild/linux-ia32': 0.25.2 - '@esbuild/linux-loong64': 0.25.2 - '@esbuild/linux-mips64el': 0.25.2 - '@esbuild/linux-ppc64': 0.25.2 - '@esbuild/linux-riscv64': 0.25.2 - '@esbuild/linux-s390x': 0.25.2 - '@esbuild/linux-x64': 0.25.2 - '@esbuild/netbsd-arm64': 0.25.2 - '@esbuild/netbsd-x64': 0.25.2 - '@esbuild/openbsd-arm64': 0.25.2 - '@esbuild/openbsd-x64': 0.25.2 - '@esbuild/sunos-x64': 0.25.2 - '@esbuild/win32-arm64': 0.25.2 - '@esbuild/win32-ia32': 0.25.2 - '@esbuild/win32-x64': 0.25.2 - esbuild@0.25.4: optionalDependencies: '@esbuild/aix-ppc64': 0.25.4 @@ -15491,48 +13082,92 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1))(eslint@8.57.1): + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0))(eslint@8.57.0): dependencies: confusing-browser-globals: 1.0.11 - eslint: 8.57.1 - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1) + eslint: 8.57.0 + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0) object.assign: 4.1.7 object.entries: 1.1.9 semver: 6.3.1 - eslint-config-airbnb-typescript@17.1.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1))(eslint@8.57.1): + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0))(eslint@8.57.0): + dependencies: + confusing-browser-globals: 1.0.11 + eslint: 8.57.0 + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0) + object.assign: 4.1.7 + object.entries: 1.1.9 + semver: 6.3.1 + + eslint-config-airbnb-typescript@17.1.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0)(typescript@5.1.6))(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0))(eslint@8.57.0): + dependencies: + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0)(typescript@5.1.6) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.1.6) + eslint: 8.57.0 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0) + + eslint-config-airbnb-typescript@17.1.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0)(typescript@5.7.3))(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0))(eslint@8.57.0): dependencies: - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6) - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.1.6) - eslint: 8.57.1 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1) + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0)(typescript@5.7.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.7.3) + eslint: 8.57.0 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0) - eslint-config-airbnb@19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.4(eslint@8.57.1))(eslint@8.57.1): + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.37.5(eslint@8.57.0))(eslint@8.57.0): dependencies: - eslint: 8.57.1 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1) - eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) - eslint-plugin-react: 7.37.4(eslint@8.57.1) - eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) + eslint: 8.57.0 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0) + eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.0) + eslint-plugin-react: 7.37.5(eslint@8.57.0) + eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) object.assign: 4.1.7 object.entries: 1.1.9 - eslint-config-flat-gitignore@2.1.0(eslint@8.57.1): + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.37.5(eslint@8.57.0))(eslint@8.57.0): dependencies: - '@eslint/compat': 1.2.8(eslint@8.57.1) - eslint: 8.57.1 + eslint: 8.57.0 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0) + eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.0) + eslint-plugin-react: 7.37.5(eslint@8.57.0) + eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) + object.assign: 4.1.7 + object.entries: 1.1.9 + + eslint-config-flat-gitignore@2.1.0(eslint@8.57.0): + dependencies: + '@eslint/compat': 1.2.9(eslint@8.57.0) + eslint: 8.57.0 - eslint-config-prettier@10.1.1(eslint@8.57.1): + eslint-config-next@15.3.2(eslint-plugin-import-x@4.12.2(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3): dependencies: - eslint: 8.57.1 + '@next/eslint-plugin-next': 15.3.2 + '@rushstack/eslint-patch': 1.11.0 + '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 7.18.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.28.0(jiti@2.4.2) + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.12.2(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-import@2.31.0)(eslint@9.28.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.28.0(jiti@2.4.2)) + eslint-plugin-react: 7.37.5(eslint@9.28.0(jiti@2.4.2)) + eslint-plugin-react-hooks: 5.2.0(eslint@9.28.0(jiti@2.4.2)) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - eslint-import-resolver-webpack + - eslint-plugin-import-x + - supports-color - eslint-config-prettier@8.10.0(eslint@8.57.1): + eslint-config-prettier@8.10.0(eslint@8.57.0): dependencies: - eslint: 8.57.1 + eslint: 8.57.0 - eslint-flat-config-utils@2.0.1: + eslint-flat-config-utils@2.1.0: dependencies: pathe: 2.0.3 @@ -15544,57 +13179,169 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-merge-processors@2.0.0(eslint@8.57.1): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.12.2(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-import@2.31.0)(eslint@9.28.0(jiti@2.4.2)): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.1 + eslint: 9.28.0(jiti@2.4.2) + get-tsconfig: 4.10.1 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.13 + unrs-resolver: 1.7.2 + optionalDependencies: + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2)) + eslint-plugin-import-x: 4.12.2(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + transitivePeerDependencies: + - supports-color + + eslint-merge-processors@2.0.0(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + + eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.1.6) + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): dependencies: - eslint: 8.57.1 + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.7.3) + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@7.18.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.28.0(jiti@2.4.2)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.1.6) - eslint: 8.57.1 + '@typescript-eslint/parser': 7.18.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.28.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.12.2(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-import@2.31.0)(eslint@9.28.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color - eslint-plugin-es@3.0.1(eslint@8.57.1): + eslint-plugin-es@3.0.1(eslint@8.57.0): dependencies: - eslint: 8.57.1 + eslint: 8.57.0 eslint-utils: 2.1.0 regexpp: 3.2.0 - eslint-plugin-eslint-plugin@5.5.1(eslint@8.57.1): + eslint-plugin-eslint-plugin@5.5.1(eslint@8.57.0): dependencies: - eslint: 8.57.1 - eslint-utils: 3.0.0(eslint@8.57.1) + eslint: 8.57.0 + eslint-utils: 3.0.0(eslint@8.57.0) estraverse: 5.3.0 - eslint-plugin-header@3.1.1(eslint@8.57.1): + eslint-plugin-header@3.1.1(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + + eslint-plugin-import-x@4.12.2(eslint@8.57.0)(typescript@5.8.3): + dependencies: + '@typescript-eslint/utils': 8.32.1(eslint@8.57.0)(typescript@5.8.3) + comment-parser: 1.4.1 + debug: 4.4.1 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + get-tsconfig: 4.10.1 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.2 + stable-hash: 0.0.5 + tslib: 2.8.1 + unrs-resolver: 1.7.2 + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-import-x@4.12.2(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3): + dependencies: + '@typescript-eslint/utils': 8.32.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + comment-parser: 1.4.1 + debug: 4.4.1 + eslint: 9.28.0(jiti@2.4.2) + eslint-import-resolver-node: 0.3.9 + get-tsconfig: 4.10.1 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.2 + stable-hash: 0.0.5 + tslib: 2.8.1 + unrs-resolver: 1.7.2 + transitivePeerDependencies: + - supports-color + - typescript + optional: true + + eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0): dependencies: - eslint: 8.57.1 + '@rtsao/scc': 1.1.0 + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.1.6) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color - eslint-plugin-import-x@4.10.5(eslint@8.57.1)(typescript@5.8.3): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0): dependencies: - '@pkgr/core': 0.2.4 - '@types/doctrine': 0.0.9 - '@typescript-eslint/utils': 8.30.1(eslint@8.57.1)(typescript@5.8.3) - debug: 4.4.0 - doctrine: 3.0.0 - eslint: 8.57.1 + '@rtsao/scc': 1.1.0 + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - get-tsconfig: 4.10.0 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + hasown: 2.0.2 + is-core-module: 2.16.1 is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.1 - stable-hash: 0.0.5 - tslib: 2.8.1 - unrs-resolver: 1.5.0 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.7.3) transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack - supports-color - - typescript - eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -15603,9 +13350,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 8.57.1 + eslint: 9.28.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.28.0(jiti@2.4.2)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -15617,40 +13364,68 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.1.6) + '@typescript-eslint/parser': 7.18.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6): + eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0)(typescript@5.1.6): + dependencies: + '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.1.6) + eslint: 8.57.0 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0)(typescript@5.1.6) + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0)(typescript@5.7.3): dependencies: - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.1.6) - eslint: 8.57.1 + '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.7.3) + eslint: 8.57.0 optionalDependencies: - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6) + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0)(typescript@5.7.3) transitivePeerDependencies: - supports-color - typescript - eslint-plugin-jsdoc@50.6.9(eslint@8.57.1): + eslint-plugin-jsdoc@50.6.17(eslint@8.57.0): dependencies: - '@es-joy/jsdoccomment': 0.49.0 + '@es-joy/jsdoccomment': 0.50.2 are-docs-informative: 0.0.2 comment-parser: 1.4.1 - debug: 4.4.0 + debug: 4.4.1 escape-string-regexp: 4.0.0 - eslint: 8.57.1 + eslint: 8.57.0 espree: 10.3.0 esquery: 1.6.0 - parse-imports: 2.2.1 - semver: 7.7.1 + parse-imports-exports: 0.2.4 + semver: 7.7.2 spdx-expression-parse: 4.0.0 - synckit: 0.9.2 transitivePeerDependencies: - supports-color - eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1): + eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.0): + dependencies: + aria-query: 5.3.2 + array-includes: 3.1.8 + array.prototype.flatmap: 1.3.3 + ast-types-flow: 0.0.8 + axe-core: 4.10.3 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 8.57.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + safe-regex-test: 1.1.0 + string.prototype.includes: 2.0.1 + + eslint-plugin-jsx-a11y@6.10.2(eslint@9.28.0(jiti@2.4.2)): dependencies: aria-query: 5.3.2 array-includes: 3.1.8 @@ -15660,7 +13435,7 @@ snapshots: axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 8.57.1 + eslint: 9.28.0(jiti@2.4.2) hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -15669,51 +13444,68 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 - eslint-plugin-node@11.1.0(eslint@8.57.1): + eslint-plugin-node@11.1.0(eslint@8.57.0): dependencies: - eslint: 8.57.1 - eslint-plugin-es: 3.0.1(eslint@8.57.1) + eslint: 8.57.0 + eslint-plugin-es: 3.0.1(eslint@8.57.0) eslint-utils: 2.1.0 ignore: 5.3.2 minimatch: 3.1.2 resolve: 1.22.10 semver: 6.3.1 - eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8): + eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@8.57.0)(prettier@2.8.8): dependencies: - eslint: 8.57.1 + eslint: 8.57.0 prettier: 2.8.8 prettier-linter-helpers: 1.0.0 optionalDependencies: - eslint-config-prettier: 8.10.0(eslint@8.57.1) + eslint-config-prettier: 8.10.0(eslint@8.57.0) - eslint-plugin-prettier@5.2.3(eslint-config-prettier@10.1.1(eslint@8.57.1))(eslint@8.57.1)(prettier@3.5.3): + eslint-plugin-prettier@5.4.0(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.5.3): dependencies: - eslint: 8.57.1 + eslint: 8.57.0 prettier: 3.5.3 prettier-linter-helpers: 1.0.0 - synckit: 0.9.2 + synckit: 0.11.6 optionalDependencies: - eslint-config-prettier: 10.1.1(eslint@8.57.1) + eslint-config-prettier: 8.10.0(eslint@8.57.0) - eslint-plugin-prettier@5.2.3(eslint-config-prettier@8.10.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.5.3): + eslint-plugin-react-hooks@4.6.2(eslint@8.57.0): dependencies: - eslint: 8.57.1 - prettier: 3.5.3 - prettier-linter-helpers: 1.0.0 - synckit: 0.9.2 - optionalDependencies: - eslint-config-prettier: 8.10.0(eslint@8.57.1) + eslint: 8.57.0 + + eslint-plugin-react-hooks@5.2.0(eslint@9.28.0(jiti@2.4.2)): + dependencies: + eslint: 9.28.0(jiti@2.4.2) - eslint-plugin-react-hooks@4.6.2(eslint@8.57.1): + eslint-plugin-react-refresh@0.4.20(eslint@9.28.0(jiti@2.4.2)): dependencies: - eslint: 8.57.1 + eslint: 9.28.0(jiti@2.4.2) - eslint-plugin-react-refresh@0.4.19(eslint@8.57.1): + eslint-plugin-react@7.37.5(eslint@8.57.0): dependencies: - eslint: 8.57.1 + array-includes: 3.1.8 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.2.1 + eslint: 8.57.0 + estraverse: 5.3.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 - eslint-plugin-react@7.37.4(eslint@8.57.1): + eslint-plugin-react@7.37.5(eslint@9.28.0(jiti@2.4.2)): dependencies: array-includes: 3.1.8 array.prototype.findlast: 1.2.5 @@ -15721,7 +13513,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.2.1 - eslint: 8.57.1 + eslint: 9.28.0(jiti@2.4.2) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -15735,21 +13527,29 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-regexp@2.7.0(eslint@8.57.1): + eslint-plugin-regexp@2.7.0(eslint@8.57.0): dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@8.57.1) + '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.0) '@eslint-community/regexpp': 4.12.1 comment-parser: 1.4.1 - eslint: 8.57.1 + eslint: 8.57.0 jsdoc-type-pratt-parser: 4.1.0 refa: 0.12.1 regexp-ast-analysis: 0.7.1 scslre: 0.3.0 - eslint-plugin-testing-library@5.11.1(eslint@8.57.1)(typescript@5.1.6): + eslint-plugin-testing-library@5.11.1(eslint@8.57.0)(typescript@5.1.6): + dependencies: + '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.1.6) + eslint: 8.57.0 + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-testing-library@5.11.1(eslint@8.57.0)(typescript@5.7.3): dependencies: - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.1.6) - eslint: 8.57.1 + '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.7.3) + eslint: 8.57.0 transitivePeerDependencies: - supports-color - typescript @@ -15759,67 +13559,64 @@ snapshots: '@microsoft/tsdoc': 0.14.2 '@microsoft/tsdoc-config': 0.16.2 - eslint-plugin-typescript-sort-keys@2.3.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6): + eslint-plugin-typescript-sort-keys@2.3.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.1.6))(eslint@8.57.0)(typescript@5.1.6): dependencies: - '@typescript-eslint/experimental-utils': 5.62.0(eslint@8.57.1)(typescript@5.1.6) - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.1.6) - eslint: 8.57.1 + '@typescript-eslint/experimental-utils': 5.62.0(eslint@8.57.0)(typescript@5.1.6) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.1.6) + eslint: 8.57.0 json-schema: 0.4.0 natural-compare-lite: 1.4.0 typescript: 5.1.6 transitivePeerDependencies: - supports-color - eslint-plugin-unicorn@58.0.0(eslint@8.57.1): + eslint-plugin-typescript-sort-keys@2.3.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.7.3))(eslint@8.57.0)(typescript@5.7.3): + dependencies: + '@typescript-eslint/experimental-utils': 5.62.0(eslint@8.57.0)(typescript@5.7.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.7.3) + eslint: 8.57.0 + json-schema: 0.4.0 + natural-compare-lite: 1.4.0 + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + eslint-plugin-unicorn@59.0.1(eslint@8.57.0): dependencies: - '@babel/helper-validator-identifier': 7.25.9 - '@eslint-community/eslint-utils': 4.5.1(eslint@8.57.1) + '@babel/helper-validator-identifier': 7.27.1 + '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.0) '@eslint/plugin-kit': 0.2.8 ci-info: 4.2.0 clean-regexp: 1.0.0 - core-js-compat: 3.41.0 - eslint: 8.57.1 + core-js-compat: 3.42.0 + eslint: 8.57.0 esquery: 1.6.0 - globals: 16.0.0 + find-up-simple: 1.0.1 + globals: 16.1.0 indent-string: 5.0.0 is-builtin-module: 5.0.0 jsesc: 3.1.0 pluralize: 8.0.0 - read-package-up: 11.0.0 regexp-tree: 0.1.27 regjsparser: 0.12.0 - semver: 7.7.1 + semver: 7.7.2 strip-indent: 4.0.0 - eslint-plugin-vue@10.0.0(eslint@8.57.1)(vue-eslint-parser@10.1.1(eslint@8.57.1)): + eslint-plugin-vue@10.1.0(eslint@8.57.0)(vue-eslint-parser@10.1.3(eslint@8.57.0)): dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@8.57.1) - eslint: 8.57.1 + '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.0) + eslint: 8.57.0 natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 6.1.2 - semver: 7.7.1 - vue-eslint-parser: 10.1.1(eslint@8.57.1) - xml-name-validator: 4.0.0 - - eslint-plugin-vue@9.33.0(eslint@8.57.1): - dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@8.57.1) - eslint: 8.57.1 - globals: 13.24.0 - natural-compare: 1.4.0 - nth-check: 2.1.1 - postcss-selector-parser: 6.1.2 - semver: 7.7.1 - vue-eslint-parser: 9.4.3(eslint@8.57.1) + semver: 7.7.2 + vue-eslint-parser: 10.1.3(eslint@8.57.0) xml-name-validator: 4.0.0 - transitivePeerDependencies: - - supports-color - eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.13)(eslint@8.57.1): + eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.14)(eslint@8.57.0): dependencies: - '@vue/compiler-sfc': 3.5.13 - eslint: 8.57.1 + '@vue/compiler-sfc': 3.5.14 + eslint: 8.57.0 eslint-scope@5.1.1: dependencies: @@ -15840,9 +13637,9 @@ snapshots: dependencies: eslint-visitor-keys: 1.3.0 - eslint-utils@3.0.0(eslint@8.57.1): + eslint-utils@3.0.0(eslint@8.57.0): dependencies: - eslint: 8.57.1 + eslint: 8.57.0 eslint-visitor-keys: 2.1.0 eslint-visitor-keys@1.3.0: {} @@ -15853,20 +13650,20 @@ snapshots: eslint-visitor-keys@4.2.0: {} - eslint@8.57.1: + eslint@8.57.0: dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@8.57.1) + '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.0) '@eslint-community/regexpp': 4.12.1 '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.57.1 - '@humanwhocodes/config-array': 0.13.0 + '@eslint/js': 8.57.0 + '@humanwhocodes/config-array': 0.11.14 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 '@ungap/structured-clone': 1.3.0 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.0 + debug: 4.4.1 doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -15896,6 +13693,48 @@ snapshots: transitivePeerDependencies: - supports-color + eslint@9.28.0(jiti@2.4.2): + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0(jiti@2.4.2)) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.20.0 + '@eslint/config-helpers': 0.2.2 + '@eslint/core': 0.14.0 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.28.0 + '@eslint/plugin-kit': 0.3.1 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.7 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.1 + escape-string-regexp: 4.0.0 + eslint-scope: 8.3.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.4.2 + transitivePeerDependencies: + - supports-color + espree@10.3.0: dependencies: acorn: 8.14.1 @@ -15943,18 +13782,6 @@ snapshots: md5.js: 1.3.5 safe-buffer: 5.2.1 - execa@7.2.0: - dependencies: - cross-spawn: 7.0.6 - get-stream: 6.0.1 - human-signals: 4.3.1 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.3.0 - onetime: 6.0.0 - signal-exit: 3.0.7 - strip-final-newline: 3.0.0 - execa@8.0.1: dependencies: cross-spawn: 7.0.6 @@ -15967,24 +13794,7 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 - execa@9.5.2: - dependencies: - '@sindresorhus/merge-streams': 4.0.0 - cross-spawn: 7.0.6 - figures: 6.1.0 - get-stream: 9.0.1 - human-signals: 8.0.0 - is-plain-obj: 4.1.0 - is-stream: 4.0.1 - npm-run-path: 6.0.0 - pretty-ms: 9.2.0 - signal-exit: 4.1.0 - strip-final-newline: 4.0.0 - yoctocolors: 2.1.1 - - expect-type@1.2.0: {} - - exsolve@1.0.4: {} + expect-type@1.2.1: {} exsolve@1.0.5: {} @@ -16001,11 +13811,11 @@ snapshots: enhanced-resolve: 5.18.1 mlly: 1.7.4 pathe: 1.1.2 - ufo: 1.5.4 + ufo: 1.6.1 extract-zip@2.0.1: dependencies: - debug: 4.4.0 + debug: 4.4.1 get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -16013,7 +13823,7 @@ snapshots: transitivePeerDependencies: - supports-color - fake-indexeddb@6.0.0: {} + fake-indexeddb@6.0.1: {} fast-deep-equal@3.1.3: {} @@ -16021,6 +13831,14 @@ snapshots: fast-fifo@1.3.2: {} + fast-glob@3.3.1: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -16033,7 +13851,7 @@ snapshots: fast-levenshtein@2.0.6: {} - fast-npm-meta@0.4.2: {} + fast-npm-meta@0.4.3: {} fast-sha256@1.3.0: {} @@ -16049,10 +13867,6 @@ snapshots: dependencies: pend: 1.2.0 - fdir@6.4.3(picomatch@4.0.2): - optionalDependencies: - picomatch: 4.0.2 - fdir@6.4.4(picomatch@4.0.2): optionalDependencies: picomatch: 4.0.2 @@ -16068,14 +13882,14 @@ snapshots: dependencies: escape-string-regexp: 1.0.5 - figures@6.1.0: - dependencies: - is-unicode-supported: 2.1.0 - file-entry-cache@6.0.1: dependencies: flat-cache: 3.2.0 + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + file-uri-to-path@1.0.0: {} fill-range@7.1.1: @@ -16084,9 +13898,7 @@ snapshots: filter-obj@1.1.0: {} - filter-obj@5.1.0: {} - - find-root@1.1.0: {} + filter-obj@6.1.0: {} find-up-simple@1.0.1: {} @@ -16100,11 +13912,6 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - find-up@6.3.0: - dependencies: - locate-path: 7.2.0 - path-exists: 5.0.0 - find-up@7.0.0: dependencies: locate-path: 7.2.0 @@ -16115,7 +13922,7 @@ snapshots: dependencies: magic-string: 0.30.17 mlly: 1.7.4 - rollup: 4.39.0 + rollup: 4.40.2 flat-cache@3.2.0: dependencies: @@ -16123,6 +13930,11 @@ snapshots: keyv: 4.5.4 rimraf: 3.0.2 + flat-cache@4.0.1: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + flat@5.0.2: {} flatted@3.3.3: {} @@ -16157,10 +13969,12 @@ snapshots: fraction.js@4.3.7: {} - fresh@0.5.2: {} - fresh@2.0.0: {} + front-matter@4.0.2: + dependencies: + js-yaml: 3.14.1 + fs-constants@1.0.0: {} fs-extra@10.1.0: @@ -16169,12 +13983,6 @@ snapshots: jsonfile: 6.1.0 universalify: 2.0.1 - fs-extra@11.3.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 - fs-extra@7.0.1: dependencies: graceful-fs: 4.2.11 @@ -16187,12 +13995,11 @@ snapshots: jsonfile: 4.0.0 universalify: 0.1.2 - fs-minipass@2.1.0: - dependencies: - minipass: 3.3.6 - fs.realpath@1.0.0: {} + fsevents@2.3.2: + optional: true + fsevents@2.3.3: optional: true @@ -16211,24 +14018,12 @@ snapshots: fuse.js@7.1.0: {} - gauge@3.0.2: - dependencies: - aproba: 2.0.0 - color-support: 1.1.3 - console-control-strings: 1.1.0 - has-unicode: 2.0.1 - object-assign: 4.1.1 - signal-exit: 3.0.7 - string-width: 4.2.3 - strip-ansi: 6.0.1 - wide-align: 1.1.5 - gensync@1.0.0-beta.2: {} - get-amd-module-type@5.0.1: + get-amd-module-type@6.0.1: dependencies: - ast-module-types: 5.0.0 - node-source-walk: 6.0.2 + ast-module-types: 6.0.1 + node-source-walk: 7.0.1 get-caller-file@2.0.5: {} @@ -16256,26 +14051,23 @@ snapshots: dependencies: global: 4.4.0 + get-random-values@3.0.0: + dependencies: + global: 4.4.0 + get-stream@5.2.0: dependencies: pump: 3.0.2 - get-stream@6.0.1: {} - get-stream@8.0.1: {} - get-stream@9.0.1: - dependencies: - '@sec-ant/readable-stream': 0.4.1 - is-stream: 4.0.1 - get-symbol-description@1.1.0: dependencies: call-bound: 1.0.4 es-errors: 1.3.0 get-intrinsic: 1.3.0 - get-tsconfig@4.10.0: + get-tsconfig@4.10.1: dependencies: resolve-pkg-maps: 1.0.0 @@ -16288,14 +14080,14 @@ snapshots: nypm: 0.6.0 pathe: 2.0.3 - git-up@8.1.0: + git-up@8.1.1: dependencies: is-ssh: 1.4.1 parse-url: 9.2.0 - git-url-parse@16.0.1: + git-url-parse@16.1.0: dependencies: - git-up: 8.1.0 + git-up: 8.1.1 glob-parent@5.1.2: dependencies: @@ -16314,6 +14106,15 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 + glob@11.0.2: + dependencies: + foreground-child: 3.3.1 + jackspeak: 4.1.1 + minimatch: 10.0.1 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 2.0.0 + glob@7.1.7: dependencies: fs.realpath: 1.0.0 @@ -16365,7 +14166,9 @@ snapshots: dependencies: type-fest: 0.20.2 - globals@16.0.0: {} + globals@14.0.0: {} + + globals@16.1.0: {} globalthis@1.0.4: dependencies: @@ -16385,7 +14188,7 @@ snapshots: dependencies: '@sindresorhus/merge-streams': 2.3.0 fast-glob: 3.3.3 - ignore: 7.0.3 + ignore: 7.0.4 path-type: 6.0.0 slash: 5.1.0 unicorn-magic: 0.3.0 @@ -16406,22 +14209,10 @@ snapshots: dependencies: duplexer: 0.1.2 - h3@1.15.1: - dependencies: - cookie-es: 1.2.2 - crossws: 0.3.4 - defu: 6.1.4 - destr: 2.0.5 - iron-webcrypto: 1.2.1 - node-mock-http: 1.0.0 - radix3: 1.1.2 - ufo: 1.5.4 - uncrypto: 0.1.3 - h3@1.15.3: dependencies: cookie-es: 1.2.2 - crossws: 0.3.4 + crossws: 0.3.5 defu: 6.1.4 destr: 2.0.5 iron-webcrypto: 1.2.1 @@ -16450,8 +14241,6 @@ snapshots: dependencies: has-symbols: 1.1.0 - has-unicode@2.0.1: {} - hash-base@3.0.5: dependencies: inherits: 2.0.4 @@ -16475,7 +14264,7 @@ snapshots: hast-util-whitespace: 3.0.0 html-void-elements: 3.0.0 mdast-util-to-hast: 13.2.0 - property-information: 7.0.0 + property-information: 7.1.0 space-separated-tokens: 2.0.2 stringify-entities: 4.0.4 zwitch: 2.0.4 @@ -16492,10 +14281,6 @@ snapshots: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 - hoist-non-react-statics@3.3.2: - dependencies: - react-is: 16.13.1 - hookable@5.5.3: {} hosted-git-info@2.8.9: {} @@ -16511,6 +14296,7 @@ snapshots: html-encoding-sniffer@4.0.0: dependencies: whatwg-encoding: 3.1.1 + optional: true html-escaper@2.0.2: {} @@ -16529,25 +14315,17 @@ snapshots: http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.3 - debug: 4.4.0 + debug: 4.4.1 transitivePeerDependencies: - supports-color + optional: true http-shutdown@1.2.2: {} - https-browserify@1.0.0: {} - - https-proxy-agent@5.0.1: - dependencies: - agent-base: 6.0.2 - debug: 4.4.0 - transitivePeerDependencies: - - supports-color - https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.3 - debug: 4.4.0 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -16555,12 +14333,8 @@ snapshots: human-id@4.1.1: {} - human-signals@4.3.1: {} - human-signals@5.0.0: {} - human-signals@8.0.0: {} - iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 @@ -16568,6 +14342,7 @@ snapshots: iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 + optional: true icss-utils@5.1.0(postcss@8.5.3): dependencies: @@ -16577,13 +14352,11 @@ snapshots: ignore@5.3.2: {} - ignore@7.0.3: {} - ignore@7.0.4: {} image-meta@0.2.1: {} - immutable@5.0.3: {} + immutable@5.1.2: {} import-fresh@3.3.1: dependencies: @@ -16592,15 +14365,7 @@ snapshots: import-lazy@4.0.0: {} - impound@0.2.2(rollup@4.39.0): - dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.39.0) - mlly: 1.7.4 - mocked-exports: 0.1.1 - pathe: 2.0.3 - unplugin: 2.2.2 - transitivePeerDependencies: - - rollup + import-meta-resolve@3.1.1: {} impound@1.0.0: dependencies: @@ -16635,25 +14400,11 @@ snapshots: hasown: 2.0.2 side-channel: 1.1.0 - ioredis@5.6.0: - dependencies: - '@ioredis/commands': 1.2.0 - cluster-key-slot: 1.1.2 - debug: 4.4.0 - denque: 2.1.0 - lodash.defaults: 4.2.0 - lodash.isarguments: 3.1.0 - redis-errors: 1.2.0 - redis-parser: 3.0.0 - standard-as-callback: 2.1.0 - transitivePeerDependencies: - - supports-color - ioredis@5.6.1: dependencies: '@ioredis/commands': 1.2.0 cluster-key-slot: 1.1.2 - debug: 4.4.0 + debug: 4.4.1 denque: 2.1.0 lodash.defaults: 4.2.0 lodash.isarguments: 3.1.0 @@ -16665,11 +14416,6 @@ snapshots: iron-webcrypto@1.2.1: {} - is-arguments@1.2.0: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - is-array-buffer@3.0.5: dependencies: call-bind: 1.0.8 @@ -16705,6 +14451,10 @@ snapshots: dependencies: builtin-modules: 5.0.0 + is-bun-module@2.0.0: + dependencies: + semver: 7.7.2 + is-callable@1.2.7: {} is-core-module@2.16.1: @@ -16760,11 +14510,6 @@ snapshots: is-module@1.0.0: {} - is-nan@1.3.2: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - is-number-object@1.1.1: dependencies: call-bound: 1.0.4 @@ -16780,15 +14525,14 @@ snapshots: is-plain-obj@2.1.0: {} - is-plain-obj@4.1.0: {} - is-plain-object@5.0.0: {} - is-potential-custom-element-name@1.0.1: {} + is-potential-custom-element-name@1.0.1: + optional: true is-reference@1.2.1: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 is-regex@1.2.1: dependencies: @@ -16834,8 +14578,6 @@ snapshots: is-unicode-supported@0.1.0: {} - is-unicode-supported@2.1.0: {} - is-url-superb@4.0.0: {} is-url@1.2.4: {} @@ -16875,8 +14617,6 @@ snapshots: isexe@3.1.1: {} - isomorphic-timers-promises@1.0.1: {} - istanbul-lib-coverage@3.2.2: {} istanbul-lib-report@3.0.1: @@ -16888,7 +14628,7 @@ snapshots: istanbul-lib-source-maps@5.0.6: dependencies: '@jridgewell/trace-mapping': 0.3.25 - debug: 4.4.0 + debug: 4.4.1 istanbul-lib-coverage: 3.2.2 transitivePeerDependencies: - supports-color @@ -16913,6 +14653,10 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 + jackspeak@4.1.1: + dependencies: + '@isaacs/cliui': 8.0.2 + jest-diff@29.7.0: dependencies: chalk: 4.1.2 @@ -16932,6 +14676,8 @@ snapshots: jose@5.10.0: {} + jose@6.0.11: {} + js-beautify@1.15.4: dependencies: config-chain: 1.1.13 @@ -16957,18 +14703,17 @@ snapshots: jsdoc-type-pratt-parser@4.1.0: {} - jsdom@26.0.0: + jsdom@26.1.0: dependencies: - cssstyle: 4.3.0 + cssstyle: 4.3.1 data-urls: 5.0.0 decimal.js: 10.5.0 - form-data: 4.0.2 html-encoding-sniffer: 4.0.0 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.18 - parse5: 7.2.1 + nwsapi: 2.2.20 + parse5: 7.3.0 rrweb-cssom: 0.8.0 saxes: 6.0.0 symbol-tree: 3.2.4 @@ -16978,12 +14723,13 @@ snapshots: whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 whatwg-url: 14.2.0 - ws: 8.18.1 + ws: 8.18.2 xml-name-validator: 5.0.0 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate + optional: true jsesc@3.0.2: {} @@ -16993,8 +14739,6 @@ snapshots: json-parse-even-better-errors@2.3.1: {} - json-parse-even-better-errors@4.0.0: {} - json-schema-traverse@0.4.1: {} json-schema-traverse@1.0.0: {} @@ -17048,8 +14792,6 @@ snapshots: known-css-properties@0.26.0: {} - kolorist@1.8.0: {} - kuler@2.0.0: {} lambda-local@2.2.0: @@ -17084,7 +14826,7 @@ snapshots: lines-and-columns@1.2.4: {} - lines-and-columns@2.0.4: {} + lines-and-columns@2.0.3: {} listhen@1.9.0: dependencies: @@ -17093,17 +14835,17 @@ snapshots: citty: 0.1.6 clipboardy: 4.0.0 consola: 3.4.2 - crossws: 0.3.4 + crossws: 0.3.5 defu: 6.1.4 get-port-please: 3.1.2 - h3: 1.15.1 + h3: 1.15.3 http-shutdown: 1.2.2 jiti: 2.4.2 mlly: 1.7.4 node-forge: 1.3.1 pathe: 1.1.2 - std-env: 3.8.1 - ufo: 1.5.4 + std-env: 3.9.0 + ufo: 1.6.1 untun: 0.1.3 uqr: 0.1.2 @@ -17111,7 +14853,7 @@ snapshots: dependencies: mlly: 1.7.4 pkg-types: 2.1.0 - quansync: 0.2.8 + quansync: 0.2.10 locate-path@5.0.0: dependencies: @@ -17131,16 +14873,10 @@ snapshots: lodash.defaults@4.2.0: {} - lodash.difference@4.5.0: {} - - lodash.flatten@4.4.0: {} - lodash.isarguments@3.1.0: {} lodash.isempty@4.4.0: {} - lodash.isplainobject@4.0.6: {} - lodash.memoize@4.1.2: {} lodash.merge@4.6.2: {} @@ -17149,8 +14885,6 @@ snapshots: lodash.truncate@4.4.2: {} - lodash.union@4.6.0: {} - lodash.uniq@4.5.0: {} lodash@4.17.21: {} @@ -17177,6 +14911,8 @@ snapshots: lru-cache@10.4.3: {} + lru-cache@11.1.0: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -17187,6 +14923,8 @@ snapshots: luxon@3.6.1: {} + lz-string@1.5.0: {} + magic-regexp@0.8.0: dependencies: estree-walker: 3.0.3 @@ -17194,7 +14932,7 @@ snapshots: mlly: 1.7.4 regexp-tree: 0.1.27 type-level-regexp: 0.1.17 - ufo: 1.5.4 + ufo: 1.6.1 unplugin: 1.16.1 magic-string-ast@0.7.1: @@ -17207,17 +14945,13 @@ snapshots: magicast@0.3.5: dependencies: - '@babel/parser': 7.26.10 - '@babel/types': 7.26.10 + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 source-map-js: 1.2.1 - make-dir@3.1.0: - dependencies: - semver: 6.3.1 - make-dir@4.0.0: dependencies: - semver: 7.7.1 + semver: 7.7.2 map-obj@1.0.1: {} @@ -17255,8 +14989,6 @@ snapshots: memory-cache@0.2.0: {} - memorystream@0.3.1: {} - meow@9.0.0: dependencies: '@types/minimist': 1.2.5 @@ -17306,7 +15038,7 @@ snapshots: miller-rabin@4.0.1: dependencies: - bn.js: 4.12.1 + bn.js: 4.12.2 brorand: 1.1.0 mime-db@1.52.0: {} @@ -17321,8 +15053,6 @@ snapshots: dependencies: mime-db: 1.54.0 - mime@1.6.0: {} - mime@3.0.0: {} mime@4.0.7: {} @@ -17343,6 +15073,10 @@ snapshots: minimalistic-crypto-utils@1.0.1: {} + minimatch@10.0.1: + dependencies: + brace-expansion: 2.0.1 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -17371,89 +15105,74 @@ snapshots: minimist@1.2.8: {} - minipass@3.3.6: - dependencies: - yallist: 4.0.0 - - minipass@5.0.0: {} - minipass@7.1.2: {} minisearch@7.1.2: {} - minizlib@2.1.2: - dependencies: - minipass: 3.3.6 - yallist: 4.0.0 - minizlib@3.0.2: dependencies: minipass: 7.1.2 mitt@3.0.1: {} - mkdirp@1.0.4: {} - mkdirp@3.0.1: {} - mkdist@2.3.0(sass@1.85.1)(typescript@5.8.3)(vue-sfc-transformer@0.1.11(esbuild@0.25.4)(vue@3.5.13(typescript@5.8.3)))(vue-tsc@2.2.8(typescript@5.8.3))(vue@3.5.13(typescript@5.8.3)): + mkdist@2.3.0(sass@1.89.0)(typescript@5.8.3)(vue-sfc-transformer@0.1.16(@vue/compiler-core@3.5.14)(esbuild@0.25.4)(vue@3.5.14(typescript@5.8.3)))(vue-tsc@2.2.10(typescript@5.8.3))(vue@3.5.14(typescript@5.8.3)): dependencies: autoprefixer: 10.4.21(postcss@8.5.3) citty: 0.1.6 - cssnano: 7.0.6(postcss@8.5.3) + cssnano: 7.0.7(postcss@8.5.3) defu: 6.1.4 - esbuild: 0.25.2 + esbuild: 0.25.4 jiti: 1.21.7 mlly: 1.7.4 pathe: 2.0.3 pkg-types: 2.1.0 postcss: 8.5.3 postcss-nested: 7.0.2(postcss@8.5.3) - semver: 7.7.1 - tinyglobby: 0.2.12 + semver: 7.7.2 + tinyglobby: 0.2.13 optionalDependencies: - sass: 1.85.1 + sass: 1.89.0 typescript: 5.8.3 - vue: 3.5.13(typescript@5.8.3) - vue-sfc-transformer: 0.1.11(esbuild@0.25.4)(vue@3.5.13(typescript@5.8.3)) - vue-tsc: 2.2.8(typescript@5.8.3) + vue: 3.5.14(typescript@5.8.3) + vue-sfc-transformer: 0.1.16(@vue/compiler-core@3.5.14)(esbuild@0.25.4)(vue@3.5.14(typescript@5.8.3)) + vue-tsc: 2.2.10(typescript@5.8.3) mlly@1.7.4: dependencies: acorn: 8.14.1 pathe: 2.0.3 pkg-types: 1.3.1 - ufo: 1.5.4 + ufo: 1.6.1 mocked-exports@0.1.1: {} - module-definition@5.0.1: + module-definition@6.0.1: dependencies: - ast-module-types: 5.0.0 - node-source-walk: 6.0.2 + ast-module-types: 6.0.1 + node-source-walk: 7.0.1 mri@1.2.0: {} mrmime@2.0.1: {} - ms@2.0.0: {} - ms@2.1.3: {} muggle-string@0.4.1: {} - nanoid@3.3.9: {} + nanoid@3.3.11: {} - nanoid@5.1.3: {} + nanoid@5.1.5: {} nanotar@0.2.0: {} + napi-postinstall@0.2.4: {} + natural-compare-lite@1.4.0: {} natural-compare@1.4.0: {} - nested-error-stacks@2.1.1: {} - netlify@13.3.5: dependencies: '@netlify/open-api': 2.37.0 @@ -17463,10 +15182,36 @@ snapshots: p-wait-for: 5.0.2 qs: 6.14.0 + next@15.3.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.0): + dependencies: + '@next/env': 15.3.2 + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.15 + busboy: 1.6.0 + caniuse-lite: 1.0.30001718 + postcss: 8.4.31 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + styled-jsx: 5.1.6(react@19.1.0) + optionalDependencies: + '@next/swc-darwin-arm64': 15.3.2 + '@next/swc-darwin-x64': 15.3.2 + '@next/swc-linux-arm64-gnu': 15.3.2 + '@next/swc-linux-arm64-musl': 15.3.2 + '@next/swc-linux-x64-gnu': 15.3.2 + '@next/swc-linux-x64-musl': 15.3.2 + '@next/swc-win32-arm64-msvc': 15.3.2 + '@next/swc-win32-x64-msvc': 15.3.2 + sass: 1.89.0 + sharp: 0.34.2 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + nitropack@2.11.12: dependencies: '@cloudflare/kv-asset-handler': 0.4.0 - '@netlify/functions': 3.1.8(rollup@4.40.2) + '@netlify/functions': 3.1.9(rollup@4.40.2) '@rollup/plugin-alias': 5.1.1(rollup@4.40.2) '@rollup/plugin-commonjs': 28.0.3(rollup@4.40.2) '@rollup/plugin-inject': 5.0.5(rollup@4.40.2) @@ -17474,9 +15219,9 @@ snapshots: '@rollup/plugin-node-resolve': 16.0.1(rollup@4.40.2) '@rollup/plugin-replace': 6.0.2(rollup@4.40.2) '@rollup/plugin-terser': 0.4.4(rollup@4.40.2) - '@vercel/nft': 0.29.2(rollup@4.40.2) + '@vercel/nft': 0.29.3(rollup@4.40.2) archiver: 7.0.1 - c12: 3.0.3(magicast@0.3.5) + c12: 3.0.4(magicast@0.3.5) chokidar: 4.0.3 citty: 0.1.6 compatx: 0.2.0 @@ -17563,106 +15308,6 @@ snapshots: - supports-color - uploadthing - nitropack@2.11.8: - dependencies: - '@cloudflare/kv-asset-handler': 0.4.0 - '@netlify/functions': 3.0.4 - '@rollup/plugin-alias': 5.1.1(rollup@4.39.0) - '@rollup/plugin-commonjs': 28.0.3(rollup@4.39.0) - '@rollup/plugin-inject': 5.0.5(rollup@4.39.0) - '@rollup/plugin-json': 6.1.0(rollup@4.39.0) - '@rollup/plugin-node-resolve': 16.0.1(rollup@4.39.0) - '@rollup/plugin-replace': 6.0.2(rollup@4.39.0) - '@rollup/plugin-terser': 0.4.4(rollup@4.39.0) - '@vercel/nft': 0.29.2(rollup@4.39.0) - archiver: 7.0.1 - c12: 3.0.3(magicast@0.3.5) - chokidar: 4.0.3 - citty: 0.1.6 - compatx: 0.1.8 - confbox: 0.2.2 - consola: 3.4.2 - cookie-es: 2.0.0 - croner: 9.0.0 - crossws: 0.3.4 - db0: 0.3.1 - defu: 6.1.4 - destr: 2.0.5 - dot-prop: 9.0.0 - esbuild: 0.25.2 - escape-string-regexp: 5.0.0 - etag: 1.8.1 - exsolve: 1.0.4 - globby: 14.1.0 - gzip-size: 7.0.0 - h3: 1.15.1 - hookable: 5.5.3 - httpxy: 0.1.7 - ioredis: 5.6.0 - jiti: 2.4.2 - klona: 2.0.6 - knitwork: 1.2.0 - listhen: 1.9.0 - magic-string: 0.30.17 - magicast: 0.3.5 - mime: 4.0.7 - mlly: 1.7.4 - node-fetch-native: 1.6.6 - node-mock-http: 1.0.0 - ofetch: 1.4.1 - ohash: 2.0.11 - pathe: 2.0.3 - perfect-debounce: 1.0.0 - pkg-types: 2.1.0 - pretty-bytes: 6.1.1 - radix3: 1.1.2 - rollup: 4.39.0 - rollup-plugin-visualizer: 5.14.0(rollup@4.39.0) - scule: 1.3.0 - semver: 7.7.1 - serve-placeholder: 2.0.2 - serve-static: 1.16.2 - source-map: 0.7.4 - std-env: 3.8.1 - ufo: 1.5.4 - ultrahtml: 1.6.0 - uncrypto: 0.1.3 - unctx: 2.4.1 - unenv: 2.0.0-rc.15 - unimport: 4.1.3 - unplugin-utils: 0.2.4 - unstorage: 1.15.0(db0@0.3.1)(ioredis@5.6.0) - untyped: 2.0.0 - unwasm: 0.3.9 - youch: 4.1.0-beta.6 - youch-core: 0.3.2 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@electric-sql/pglite' - - '@libsql/client' - - '@netlify/blobs' - - '@planetscale/database' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/kv' - - aws4fetch - - better-sqlite3 - - drizzle-orm - - encoding - - idb-keyval - - mysql2 - - rolldown - - sqlite3 - - supports-color - - uploadthing - node-addon-api@7.1.1: {} node-domexception@1.0.0: {} @@ -17689,43 +15334,9 @@ snapshots: node-releases@2.0.19: {} - node-source-walk@6.0.2: + node-source-walk@7.0.1: dependencies: - '@babel/parser': 7.27.0 - - node-stdlib-browser@1.3.1: - dependencies: - assert: 2.1.0 - browser-resolve: 2.0.0 - browserify-zlib: 0.2.0 - buffer: 5.7.1 - console-browserify: 1.2.0 - constants-browserify: 1.0.0 - create-require: 1.1.1 - crypto-browserify: 3.12.1 - domain-browser: 4.22.0 - events: 3.3.0 - https-browserify: 1.0.0 - isomorphic-timers-promises: 1.0.1 - os-browserify: 0.3.0 - path-browserify: 1.0.1 - pkg-dir: 5.0.0 - process: 0.11.10 - punycode: 1.4.1 - querystring-es3: 0.2.1 - readable-stream: 3.6.2 - stream-browserify: 3.0.0 - stream-http: 3.2.0 - string_decoder: 1.3.0 - timers-browserify: 2.0.12 - tty-browserify: 0.0.1 - url: 0.11.4 - util: 0.12.5 - vm-browserify: 1.1.2 - - nopt@5.0.0: - dependencies: - abbrev: 1.1.1 + '@babel/parser': 7.27.2 nopt@7.2.1: dependencies: @@ -17733,7 +15344,7 @@ snapshots: nopt@8.1.0: dependencies: - abbrev: 3.0.0 + abbrev: 3.0.1 normalize-package-data@2.5.0: dependencies: @@ -17746,13 +15357,13 @@ snapshots: dependencies: hosted-git-info: 4.1.0 is-core-module: 2.16.1 - semver: 7.7.1 + semver: 7.7.2 validate-npm-package-license: 3.0.4 normalize-package-data@6.0.2: dependencies: hosted-git-info: 7.0.2 - semver: 7.7.1 + semver: 7.7.2 validate-npm-package-license: 3.0.4 normalize-path@2.1.1: @@ -17765,176 +15376,35 @@ snapshots: normalize-url@6.1.0: {} - npm-normalize-package-bin@4.0.0: {} - - npm-run-all2@7.0.2: - dependencies: - ansi-styles: 6.2.1 - cross-spawn: 7.0.6 - memorystream: 0.3.1 - minimatch: 9.0.5 - pidtree: 0.6.0 - read-package-json-fast: 4.0.0 - shell-quote: 1.8.2 - which: 5.0.0 - npm-run-path@4.0.1: dependencies: - path-key: 3.1.1 - - npm-run-path@5.3.0: - dependencies: - path-key: 4.0.0 - - npm-run-path@6.0.0: - dependencies: - path-key: 4.0.0 - unicorn-magic: 0.3.0 - - npmlog@5.0.1: - dependencies: - are-we-there-yet: 2.0.0 - console-control-strings: 1.1.0 - gauge: 3.0.2 - set-blocking: 2.0.0 - - nth-check@2.1.1: - dependencies: - boolbase: 1.0.0 - - nuxt@3.16.2(@parcel/watcher@2.5.1)(@types/node@22.14.1)(db0@0.3.1)(eslint@8.57.1)(ioredis@5.6.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.39.0)(sass@1.85.1)(terser@5.39.0)(typescript@5.8.3)(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue-tsc@2.2.8(typescript@5.8.3))(yaml@2.7.1): - dependencies: - '@nuxt/cli': 3.24.1(magicast@0.3.5) - '@nuxt/devalue': 2.0.2 - '@nuxt/devtools': 2.4.0(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) - '@nuxt/kit': 3.16.2(magicast@0.3.5) - '@nuxt/schema': 3.16.2 - '@nuxt/telemetry': 2.6.6(magicast@0.3.5) - '@nuxt/vite-builder': 3.16.2(@types/node@22.14.1)(eslint@8.57.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.39.0)(sass@1.85.1)(terser@5.39.0)(typescript@5.8.3)(vue-tsc@2.2.8(typescript@5.8.3))(vue@3.5.13(typescript@5.8.3))(yaml@2.7.1) - '@oxc-parser/wasm': 0.60.0 - '@unhead/vue': 2.0.5(vue@3.5.13(typescript@5.8.3)) - '@vue/shared': 3.5.13 - c12: 3.0.3(magicast@0.3.5) - chokidar: 4.0.3 - compatx: 0.1.8 - consola: 3.4.2 - cookie-es: 2.0.0 - defu: 6.1.4 - destr: 2.0.5 - devalue: 5.1.1 - errx: 0.1.0 - esbuild: 0.25.2 - escape-string-regexp: 5.0.0 - estree-walker: 3.0.3 - exsolve: 1.0.4 - globby: 14.1.0 - h3: 1.15.1 - hookable: 5.5.3 - ignore: 7.0.3 - impound: 0.2.2(rollup@4.39.0) - jiti: 2.4.2 - klona: 2.0.6 - knitwork: 1.2.0 - magic-string: 0.30.17 - mlly: 1.7.4 - mocked-exports: 0.1.1 - nanotar: 0.2.0 - nitropack: 2.11.8 - nypm: 0.6.0 - ofetch: 1.4.1 - ohash: 2.0.11 - on-change: 5.0.1 - oxc-parser: 0.56.5 - pathe: 2.0.3 - perfect-debounce: 1.0.0 - pkg-types: 2.1.0 - radix3: 1.1.2 - scule: 1.3.0 - semver: 7.7.1 - std-env: 3.8.1 - strip-literal: 3.0.0 - tinyglobby: 0.2.12 - ufo: 1.5.4 - ultrahtml: 1.6.0 - uncrypto: 0.1.3 - unctx: 2.4.1 - unimport: 4.1.3 - unplugin: 2.2.2 - unplugin-vue-router: 0.12.0(vue-router@4.5.0(vue@3.5.13(typescript@5.8.3)))(vue@3.5.13(typescript@5.8.3)) - unstorage: 1.15.0(db0@0.3.1)(ioredis@5.6.0) - untyped: 2.0.0 - vue: 3.5.13(typescript@5.8.3) - vue-bundle-renderer: 2.1.1 - vue-devtools-stub: 0.1.0 - vue-router: 4.5.0(vue@3.5.13(typescript@5.8.3)) - optionalDependencies: - '@parcel/watcher': 2.5.1 - '@types/node': 22.14.1 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@biomejs/biome' - - '@capacitor/preferences' - - '@deno/kv' - - '@electric-sql/pglite' - - '@libsql/client' - - '@netlify/blobs' - - '@planetscale/database' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/kv' - - aws4fetch - - better-sqlite3 - - bufferutil - - db0 - - drizzle-orm - - encoding - - eslint - - idb-keyval - - ioredis - - less - - lightningcss - - magicast - - meow - - mysql2 - - optionator - - rolldown - - rollup - - sass - - sass-embedded - - sqlite3 - - stylelint - - stylus - - sugarss - - supports-color - - terser - - tsx - - typescript - - uploadthing - - utf-8-validate - - vite - - vls - - vti - - vue-tsc - - xml2js - - yaml + path-key: 3.1.1 + + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 - nuxt@3.17.3(@parcel/watcher@2.5.1)(@types/node@22.15.18)(db0@0.3.2)(eslint@8.57.1)(ioredis@5.6.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.40.2)(sass@1.85.1)(terser@5.39.0)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(yaml@2.7.1): + nuxt@3.17.4(@parcel/watcher@2.5.1)(@types/node@22.15.29)(db0@0.3.2)(eslint@8.57.0)(ioredis@5.6.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.40.2)(sass@1.89.0)(terser@5.39.2)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue-tsc@2.2.10(typescript@5.8.3))(yaml@2.8.0): dependencies: '@nuxt/cli': 3.25.1(magicast@0.3.5) '@nuxt/devalue': 2.0.2 - '@nuxt/devtools': 2.4.0(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) - '@nuxt/kit': 3.17.3(magicast@0.3.5) - '@nuxt/schema': 3.17.3 + '@nuxt/devtools': 2.4.1(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3)) + '@nuxt/kit': 3.17.4(magicast@0.3.5) + '@nuxt/schema': 3.17.4 '@nuxt/telemetry': 2.6.6(magicast@0.3.5) - '@nuxt/vite-builder': 3.17.3(@types/node@22.15.18)(eslint@8.57.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.40.2)(sass@1.85.1)(terser@5.39.0)(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3))(yaml@2.7.1) - '@unhead/vue': 2.0.8(vue@3.5.13(typescript@5.8.3)) - '@vue/shared': 3.5.13 - c12: 3.0.3(magicast@0.3.5) + '@nuxt/vite-builder': 3.17.4(@types/node@22.15.29)(eslint@8.57.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.40.2)(sass@1.89.0)(terser@5.39.2)(typescript@5.8.3)(vue-tsc@2.2.10(typescript@5.8.3))(vue@3.5.14(typescript@5.8.3))(yaml@2.8.0) + '@unhead/vue': 2.0.10(vue@3.5.14(typescript@5.8.3)) + '@vue/shared': 3.5.14 + c12: 3.0.4(magicast@0.3.5) chokidar: 4.0.3 compatx: 0.2.0 consola: 3.4.2 @@ -17964,13 +15434,13 @@ snapshots: ofetch: 1.4.1 ohash: 2.0.11 on-change: 5.0.1 - oxc-parser: 0.69.0 + oxc-parser: 0.71.0 pathe: 2.0.3 perfect-debounce: 1.0.0 pkg-types: 2.1.0 radix3: 1.1.2 scule: 1.3.0 - semver: 7.7.1 + semver: 7.7.2 std-env: 3.9.0 strip-literal: 3.0.0 tinyglobby: 0.2.13 @@ -17980,16 +15450,16 @@ snapshots: unctx: 2.4.1 unimport: 5.0.1 unplugin: 2.3.4 - unplugin-vue-router: 0.12.0(vue-router@4.5.1(vue@3.5.13(typescript@5.8.3)))(vue@3.5.13(typescript@5.8.3)) + unplugin-vue-router: 0.12.0(vue-router@4.5.1(vue@3.5.14(typescript@5.8.3)))(vue@3.5.14(typescript@5.8.3)) unstorage: 1.16.0(db0@0.3.2)(ioredis@5.6.1) untyped: 2.0.0 - vue: 3.5.13(typescript@5.8.3) + vue: 3.5.14(typescript@5.8.3) vue-bundle-renderer: 2.1.1 vue-devtools-stub: 0.1.0 - vue-router: 4.5.1(vue@3.5.13(typescript@5.8.3)) + vue-router: 4.5.1(vue@3.5.14(typescript@5.8.3)) optionalDependencies: '@parcel/watcher': 2.5.1 - '@types/node': 22.15.18 + '@types/node': 22.15.29 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -18043,55 +15513,56 @@ snapshots: - xml2js - yaml - nwsapi@2.2.18: {} + nwsapi@2.2.20: + optional: true - nx@18.2.4: + nx@20.8.1: dependencies: - '@nrwl/tao': 18.2.4 + '@napi-rs/wasm-runtime': 0.2.4 '@yarnpkg/lockfile': 1.1.0 - '@yarnpkg/parsers': 3.0.0-rc.46 - '@zkochan/js-yaml': 0.0.6 - axios: 1.8.3 + '@yarnpkg/parsers': 3.0.2 + '@zkochan/js-yaml': 0.0.7 + axios: 1.9.0 chalk: 4.1.2 cli-cursor: 3.1.0 cli-spinners: 2.6.1 cliui: 8.0.1 - dotenv: 16.3.2 - dotenv-expand: 10.0.0 + dotenv: 16.4.7 + dotenv-expand: 11.0.7 enquirer: 2.3.6 figures: 3.2.0 flat: 5.0.2 - fs-extra: 11.3.0 + front-matter: 4.0.2 ignore: 5.3.2 jest-diff: 29.7.0 - js-yaml: 4.1.0 jsonc-parser: 3.2.0 - lines-and-columns: 2.0.4 + lines-and-columns: 2.0.3 minimatch: 9.0.3 node-machine-id: 1.1.12 npm-run-path: 4.0.1 open: 8.4.2 ora: 5.3.0 - semver: 7.7.1 + resolve.exports: 2.0.3 + semver: 7.7.2 string-width: 4.2.3 - strong-log-transformer: 2.1.0 tar-stream: 2.2.0 tmp: 0.2.3 tsconfig-paths: 4.2.0 tslib: 2.8.1 + yaml: 2.8.0 yargs: 17.7.2 yargs-parser: 21.1.1 optionalDependencies: - '@nx/nx-darwin-arm64': 18.2.4 - '@nx/nx-darwin-x64': 18.2.4 - '@nx/nx-freebsd-x64': 18.2.4 - '@nx/nx-linux-arm-gnueabihf': 18.2.4 - '@nx/nx-linux-arm64-gnu': 18.2.4 - '@nx/nx-linux-arm64-musl': 18.2.4 - '@nx/nx-linux-x64-gnu': 18.2.4 - '@nx/nx-linux-x64-musl': 18.2.4 - '@nx/nx-win32-arm64-msvc': 18.2.4 - '@nx/nx-win32-x64-msvc': 18.2.4 + '@nx/nx-darwin-arm64': 20.8.1 + '@nx/nx-darwin-x64': 20.8.1 + '@nx/nx-freebsd-x64': 20.8.1 + '@nx/nx-linux-arm-gnueabihf': 20.8.1 + '@nx/nx-linux-arm64-gnu': 20.8.1 + '@nx/nx-linux-arm64-musl': 20.8.1 + '@nx/nx-linux-x64-gnu': 20.8.1 + '@nx/nx-linux-x64-musl': 20.8.1 + '@nx/nx-win32-arm64-msvc': 20.8.1 + '@nx/nx-win32-x64-msvc': 20.8.1 transitivePeerDependencies: - debug @@ -18107,11 +15578,6 @@ snapshots: object-inspect@1.13.4: {} - object-is@1.1.6: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - object-keys@1.1.1: {} object.assign@4.1.7: @@ -18154,7 +15620,7 @@ snapshots: dependencies: destr: 2.0.5 node-fetch-native: 1.6.6 - ufo: 1.5.4 + ufo: 1.6.1 ohash@2.0.11: {} @@ -18186,7 +15652,7 @@ snapshots: regex: 6.0.1 regex-recursion: 6.0.2 - open@10.1.0: + open@10.1.2: dependencies: default-browser: 5.2.1 define-lazy-prop: 3.0.0 @@ -18219,8 +15685,6 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 - os-browserify@0.3.0: {} - os-tmpdir@1.0.2: {} outdent@0.5.0: {} @@ -18231,42 +15695,28 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 - oxc-parser@0.56.5: + oxc-parser@0.71.0: dependencies: - '@oxc-project/types': 0.56.5 + '@oxc-project/types': 0.71.0 optionalDependencies: - '@oxc-parser/binding-darwin-arm64': 0.56.5 - '@oxc-parser/binding-darwin-x64': 0.56.5 - '@oxc-parser/binding-linux-arm-gnueabihf': 0.56.5 - '@oxc-parser/binding-linux-arm64-gnu': 0.56.5 - '@oxc-parser/binding-linux-arm64-musl': 0.56.5 - '@oxc-parser/binding-linux-x64-gnu': 0.56.5 - '@oxc-parser/binding-linux-x64-musl': 0.56.5 - '@oxc-parser/binding-wasm32-wasi': 0.56.5 - '@oxc-parser/binding-win32-arm64-msvc': 0.56.5 - '@oxc-parser/binding-win32-x64-msvc': 0.56.5 - - oxc-parser@0.69.0: - dependencies: - '@oxc-project/types': 0.69.0 - optionalDependencies: - '@oxc-parser/binding-darwin-arm64': 0.69.0 - '@oxc-parser/binding-darwin-x64': 0.69.0 - '@oxc-parser/binding-freebsd-x64': 0.69.0 - '@oxc-parser/binding-linux-arm-gnueabihf': 0.69.0 - '@oxc-parser/binding-linux-arm64-gnu': 0.69.0 - '@oxc-parser/binding-linux-arm64-musl': 0.69.0 - '@oxc-parser/binding-linux-riscv64-gnu': 0.69.0 - '@oxc-parser/binding-linux-s390x-gnu': 0.69.0 - '@oxc-parser/binding-linux-x64-gnu': 0.69.0 - '@oxc-parser/binding-linux-x64-musl': 0.69.0 - '@oxc-parser/binding-wasm32-wasi': 0.69.0 - '@oxc-parser/binding-win32-arm64-msvc': 0.69.0 - '@oxc-parser/binding-win32-x64-msvc': 0.69.0 - - p-event@5.0.1: - dependencies: - p-timeout: 5.1.0 + '@oxc-parser/binding-darwin-arm64': 0.71.0 + '@oxc-parser/binding-darwin-x64': 0.71.0 + '@oxc-parser/binding-freebsd-x64': 0.71.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.71.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.71.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.71.0 + '@oxc-parser/binding-linux-arm64-musl': 0.71.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.71.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.71.0 + '@oxc-parser/binding-linux-x64-gnu': 0.71.0 + '@oxc-parser/binding-linux-x64-musl': 0.71.0 + '@oxc-parser/binding-wasm32-wasi': 0.71.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.71.0 + '@oxc-parser/binding-win32-x64-msvc': 0.71.0 + + p-event@6.0.1: + dependencies: + p-timeout: 6.1.4 p-filter@2.1.0: dependencies: @@ -18311,8 +15761,6 @@ snapshots: dependencies: p-finally: 1.0.0 - p-timeout@5.1.0: {} - p-timeout@6.1.4: {} p-try@2.2.0: {} @@ -18325,11 +15773,9 @@ snapshots: package-manager-detector@0.2.11: dependencies: - quansync: 0.2.8 + quansync: 0.2.10 - package-manager-detector@1.1.0: {} - - pako@1.0.11: {} + package-manager-detector@1.3.0: {} parent-module@1.0.1: dependencies: @@ -18346,38 +15792,38 @@ snapshots: parse-gitignore@2.0.0: {} - parse-imports@2.2.1: + parse-imports-exports@0.2.4: dependencies: - es-module-lexer: 1.6.0 - slashes: 3.0.12 + parse-statements: 1.0.11 parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.26.2 + '@babel/code-frame': 7.27.1 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 parse-json@8.3.0: dependencies: - '@babel/code-frame': 7.26.2 + '@babel/code-frame': 7.27.1 index-to-position: 1.1.0 - type-fest: 4.39.1 - - parse-ms@4.0.0: {} + type-fest: 4.41.0 - parse-path@7.0.1: + parse-path@7.1.0: dependencies: protocols: 2.0.2 + parse-statements@1.0.11: {} + parse-url@9.2.0: dependencies: - '@types/parse-path': 7.0.3 - parse-path: 7.0.1 + '@types/parse-path': 7.1.0 + parse-path: 7.1.0 - parse5@7.2.1: + parse5@7.3.0: dependencies: - entities: 4.5.0 + entities: 6.0.0 + optional: true parseurl@1.3.3: {} @@ -18400,6 +15846,11 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 + path-scurry@2.0.0: + dependencies: + lru-cache: 11.1.0 + minipass: 7.1.2 + path-type@4.0.0: {} path-type@6.0.0: {} @@ -18428,14 +15879,8 @@ snapshots: picomatch@4.0.2: {} - pidtree@0.6.0: {} - pify@4.0.1: {} - pkg-dir@5.0.0: - dependencies: - find-up: 5.0.0 - pkg-types@1.3.1: dependencies: confbox: 0.1.8 @@ -18445,9 +15890,17 @@ snapshots: pkg-types@2.1.0: dependencies: confbox: 0.2.2 - exsolve: 1.0.4 + exsolve: 1.0.5 pathe: 2.0.3 + playwright-core@1.52.0: {} + + playwright@1.52.0: + dependencies: + playwright-core: 1.52.0 + optionalDependencies: + fsevents: 2.3.2 + pluralize@8.0.0: {} possible-typed-array-names@1.1.0: {} @@ -18466,15 +15919,7 @@ snapshots: postcss-colormin@5.3.1(postcss@8.5.3): dependencies: - browserslist: 4.24.4 - caniuse-api: 3.0.0 - colord: 2.9.3 - postcss: 8.5.3 - postcss-value-parser: 4.2.0 - - postcss-colormin@7.0.2(postcss@8.5.3): - dependencies: - browserslist: 4.24.4 + browserslist: 4.24.5 caniuse-api: 3.0.0 colord: 2.9.3 postcss: 8.5.3 @@ -18490,13 +15935,7 @@ snapshots: postcss-convert-values@5.1.3(postcss@8.5.3): dependencies: - browserslist: 4.24.4 - postcss: 8.5.3 - postcss-value-parser: 4.2.0 - - postcss-convert-values@7.0.4(postcss@8.5.3): - dependencies: - browserslist: 4.24.4 + browserslist: 4.24.5 postcss: 8.5.3 postcss-value-parser: 4.2.0 @@ -18510,11 +15949,6 @@ snapshots: dependencies: postcss: 8.5.3 - postcss-discard-comments@7.0.3(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - postcss-selector-parser: 6.1.2 - postcss-discard-comments@7.0.4(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -18524,10 +15958,6 @@ snapshots: dependencies: postcss: 8.5.3 - postcss-discard-duplicates@7.0.1(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - postcss-discard-duplicates@7.0.2(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -18536,10 +15966,6 @@ snapshots: dependencies: postcss: 8.5.3 - postcss-discard-empty@7.0.0(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - postcss-discard-empty@7.0.1(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -18548,10 +15974,6 @@ snapshots: dependencies: postcss: 8.5.3 - postcss-discard-overridden@7.0.0(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - postcss-discard-overridden@7.0.1(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -18564,12 +15986,6 @@ snapshots: postcss-value-parser: 4.2.0 stylehacks: 5.1.1(postcss@8.5.3) - postcss-merge-longhand@7.0.4(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - postcss-value-parser: 4.2.0 - stylehacks: 7.0.4(postcss@8.5.3) - postcss-merge-longhand@7.0.5(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -18578,20 +15994,12 @@ snapshots: postcss-merge-rules@5.1.4(postcss@8.5.3): dependencies: - browserslist: 4.24.4 + browserslist: 4.24.5 caniuse-api: 3.0.0 cssnano-utils: 3.1.0(postcss@8.5.3) postcss: 8.5.3 postcss-selector-parser: 6.1.2 - postcss-merge-rules@7.0.4(postcss@8.5.3): - dependencies: - browserslist: 4.24.4 - caniuse-api: 3.0.0 - cssnano-utils: 5.0.0(postcss@8.5.3) - postcss: 8.5.3 - postcss-selector-parser: 6.1.2 - postcss-merge-rules@7.0.5(postcss@8.5.3): dependencies: browserslist: 4.24.5 @@ -18605,11 +16013,6 @@ snapshots: postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-minify-font-values@7.0.0(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - postcss-value-parser: 4.2.0 - postcss-minify-font-values@7.0.1(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -18622,13 +16025,6 @@ snapshots: postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-minify-gradients@7.0.0(postcss@8.5.3): - dependencies: - colord: 2.9.3 - cssnano-utils: 5.0.0(postcss@8.5.3) - postcss: 8.5.3 - postcss-value-parser: 4.2.0 - postcss-minify-gradients@7.0.1(postcss@8.5.3): dependencies: colord: 2.9.3 @@ -18638,18 +16034,11 @@ snapshots: postcss-minify-params@5.1.4(postcss@8.5.3): dependencies: - browserslist: 4.24.4 + browserslist: 4.24.5 cssnano-utils: 3.1.0(postcss@8.5.3) postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-minify-params@7.0.2(postcss@8.5.3): - dependencies: - browserslist: 4.24.4 - cssnano-utils: 5.0.0(postcss@8.5.3) - postcss: 8.5.3 - postcss-value-parser: 4.2.0 - postcss-minify-params@7.0.3(postcss@8.5.3): dependencies: browserslist: 4.24.5 @@ -18662,12 +16051,6 @@ snapshots: postcss: 8.5.3 postcss-selector-parser: 6.1.2 - postcss-minify-selectors@7.0.4(postcss@8.5.3): - dependencies: - cssesc: 3.0.0 - postcss: 8.5.3 - postcss-selector-parser: 6.1.2 - postcss-minify-selectors@7.0.5(postcss@8.5.3): dependencies: cssesc: 3.0.0 @@ -18704,10 +16087,6 @@ snapshots: dependencies: postcss: 8.5.3 - postcss-normalize-charset@7.0.0(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - postcss-normalize-charset@7.0.1(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -18717,11 +16096,6 @@ snapshots: postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-normalize-display-values@7.0.0(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - postcss-value-parser: 4.2.0 - postcss-normalize-display-values@7.0.1(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -18732,11 +16106,6 @@ snapshots: postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-normalize-positions@7.0.0(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - postcss-value-parser: 4.2.0 - postcss-normalize-positions@7.0.1(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -18747,11 +16116,6 @@ snapshots: postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-normalize-repeat-style@7.0.0(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - postcss-value-parser: 4.2.0 - postcss-normalize-repeat-style@7.0.1(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -18762,11 +16126,6 @@ snapshots: postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-normalize-string@7.0.0(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - postcss-value-parser: 4.2.0 - postcss-normalize-string@7.0.1(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -18777,11 +16136,6 @@ snapshots: postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-normalize-timing-functions@7.0.0(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - postcss-value-parser: 4.2.0 - postcss-normalize-timing-functions@7.0.1(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -18789,13 +16143,7 @@ snapshots: postcss-normalize-unicode@5.1.1(postcss@8.5.3): dependencies: - browserslist: 4.24.4 - postcss: 8.5.3 - postcss-value-parser: 4.2.0 - - postcss-normalize-unicode@7.0.2(postcss@8.5.3): - dependencies: - browserslist: 4.24.4 + browserslist: 4.24.5 postcss: 8.5.3 postcss-value-parser: 4.2.0 @@ -18811,11 +16159,6 @@ snapshots: postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-normalize-url@7.0.0(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - postcss-value-parser: 4.2.0 - postcss-normalize-url@7.0.1(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -18826,11 +16169,6 @@ snapshots: postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-normalize-whitespace@7.0.0(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - postcss-value-parser: 4.2.0 - postcss-normalize-whitespace@7.0.1(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -18842,12 +16180,6 @@ snapshots: postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-ordered-values@7.0.1(postcss@8.5.3): - dependencies: - cssnano-utils: 5.0.0(postcss@8.5.3) - postcss: 8.5.3 - postcss-value-parser: 4.2.0 - postcss-ordered-values@7.0.2(postcss@8.5.3): dependencies: cssnano-utils: 5.0.1(postcss@8.5.3) @@ -18856,13 +16188,7 @@ snapshots: postcss-reduce-initial@5.1.2(postcss@8.5.3): dependencies: - browserslist: 4.24.4 - caniuse-api: 3.0.0 - postcss: 8.5.3 - - postcss-reduce-initial@7.0.2(postcss@8.5.3): - dependencies: - browserslist: 4.24.4 + browserslist: 4.24.5 caniuse-api: 3.0.0 postcss: 8.5.3 @@ -18877,11 +16203,6 @@ snapshots: postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-reduce-transforms@7.0.0(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - postcss-value-parser: 4.2.0 - postcss-reduce-transforms@7.0.1(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -18913,12 +16234,6 @@ snapshots: postcss-value-parser: 4.2.0 svgo: 2.8.0 - postcss-svgo@7.0.1(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - postcss-value-parser: 4.2.0 - svgo: 3.3.2 - postcss-svgo@7.0.2(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -18930,11 +16245,6 @@ snapshots: postcss: 8.5.3 postcss-selector-parser: 6.1.2 - postcss-unique-selectors@7.0.3(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - postcss-selector-parser: 6.1.2 - postcss-unique-selectors@7.0.4(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -18949,28 +16259,37 @@ snapshots: postcss: 8.5.3 quote-unquote: 1.0.0 - postcss@8.5.3: + postcss@8.4.31: dependencies: - nanoid: 3.3.9 + nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 - preact@10.26.4: {} - - precinct@11.0.5: + postcss@8.5.3: dependencies: - '@dependents/detective-less': 4.1.0 - commander: 10.0.1 - detective-amd: 5.0.2 - detective-cjs: 5.0.1 - detective-es6: 4.0.1 - detective-postcss: 6.1.3 - detective-sass: 5.0.3 - detective-scss: 4.0.3 - detective-stylus: 4.0.0 - detective-typescript: 11.2.0 - module-definition: 5.0.1 - node-source-walk: 6.0.2 + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + preact@10.26.7: {} + + precinct@12.2.0: + dependencies: + '@dependents/detective-less': 5.0.1 + commander: 12.1.0 + detective-amd: 6.0.1 + detective-cjs: 6.0.1 + detective-es6: 5.0.1 + detective-postcss: 7.0.1(postcss@8.5.3) + detective-sass: 6.0.1 + detective-scss: 5.0.1 + detective-stylus: 5.0.1 + detective-typescript: 14.0.0(typescript@5.8.3) + detective-vue2: 2.2.0(typescript@5.8.3) + module-definition: 6.0.1 + node-source-walk: 7.0.1 + postcss: 8.5.3 + typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -18986,16 +16305,18 @@ snapshots: pretty-bytes@6.1.1: {} + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + pretty-format@29.7.0: dependencies: '@jest/schemas': 29.6.3 ansi-styles: 5.2.0 react-is: 18.3.1 - pretty-ms@9.2.0: - dependencies: - parse-ms: 4.0.0 - process-nextick-args@2.0.1: {} process@0.11.10: {} @@ -19011,7 +16332,7 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 - property-information@7.0.0: {} + property-information@7.1.0: {} proto-list@1.2.4: {} @@ -19021,7 +16342,7 @@ snapshots: public-encrypt@4.0.3: dependencies: - bn.js: 4.12.1 + bn.js: 4.12.2 browserify-rsa: 4.1.1 create-hash: 1.2.0 parse-asn1: 5.1.7 @@ -19033,15 +16354,13 @@ snapshots: end-of-stream: 1.4.4 once: 1.4.0 - punycode@1.4.1: {} - punycode@2.3.1: {} qs@6.14.0: dependencies: side-channel: 1.1.0 - quansync@0.2.8: {} + quansync@0.2.10: {} query-string@7.1.3: dependencies: @@ -19050,8 +16369,6 @@ snapshots: split-on-first: 1.1.0 strict-uri-encode: 2.0.0 - querystring-es3@0.2.1: {} - queue-microtask@1.2.3: {} quick-lru@4.0.1: {} @@ -19076,50 +16393,26 @@ snapshots: defu: 6.1.4 destr: 2.0.5 - react-dom@18.3.1(react@18.3.1): + react-dom@19.1.0(react@19.1.0): dependencies: - loose-envify: 1.4.0 - react: 18.3.1 - scheduler: 0.23.2 + react: 19.1.0 + scheduler: 0.26.0 react-is@16.13.1: {} - react-is@18.3.1: {} - - react-is@19.0.0: {} - - react-refresh@0.14.2: {} - - react-transition-group@4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.26.10 - dom-helpers: 5.2.1 - loose-envify: 1.4.0 - prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react-is@17.0.2: {} - react-world-flags@1.6.0(react@18.3.1): - dependencies: - react: 18.3.1 - svg-country-flags: 1.2.10 - svgo: 3.3.2 - world-countries: 5.1.0 + react-is@18.3.1: {} - react@18.3.1: - dependencies: - loose-envify: 1.4.0 + react-refresh@0.17.0: {} - read-package-json-fast@4.0.0: - dependencies: - json-parse-even-better-errors: 4.0.0 - npm-normalize-package-bin: 4.0.0 + react@19.1.0: {} read-package-up@11.0.0: dependencies: find-up-simple: 1.0.1 read-pkg: 9.0.1 - type-fest: 4.39.1 + type-fest: 4.41.0 read-pkg-up@7.0.1: dependencies: @@ -19139,7 +16432,7 @@ snapshots: '@types/normalize-package-data': 2.4.4 normalize-package-data: 6.0.2 parse-json: 8.3.0 - type-fest: 4.39.1 + type-fest: 4.41.0 unicorn-magic: 0.1.0 read-yaml-file@1.1.0: @@ -19205,8 +16498,6 @@ snapshots: get-proto: 1.0.1 which-builtin-type: 1.2.1 - regenerator-runtime@0.14.1: {} - regex-recursion@6.0.2: dependencies: regex-utilities: 2.3.0 @@ -19249,14 +16540,14 @@ snapshots: requireindex@1.2.0: {} - reselect@4.1.8: {} - resolve-from@4.0.0: {} resolve-from@5.0.0: {} resolve-pkg-maps@1.0.0: {} + resolve.exports@2.0.3: {} + resolve@1.19.0: dependencies: is-core-module: 2.16.1 @@ -19287,33 +16578,38 @@ snapshots: dependencies: glob: 7.2.3 + rimraf@6.0.1: + dependencies: + glob: 11.0.2 + package-json-from-dist: 1.0.1 + ripemd160@2.0.2: dependencies: hash-base: 3.0.5 inherits: 2.0.4 - rollup-plugin-dts@6.1.1(rollup@4.35.0)(typescript@5.1.6): + rollup-plugin-dts@6.2.1(rollup@4.40.2)(typescript@5.1.6): dependencies: magic-string: 0.30.17 - rollup: 4.35.0 + rollup: 4.40.2 typescript: 5.1.6 optionalDependencies: - '@babel/code-frame': 7.26.2 + '@babel/code-frame': 7.27.1 - rollup-plugin-dts@6.1.1(rollup@4.39.0)(typescript@5.8.3): + rollup-plugin-dts@6.2.1(rollup@4.40.2)(typescript@5.8.3): dependencies: magic-string: 0.30.17 - rollup: 4.39.0 + rollup: 4.40.2 typescript: 5.8.3 optionalDependencies: - '@babel/code-frame': 7.26.2 + '@babel/code-frame': 7.27.1 - rollup-plugin-polyfill-node@0.13.0(rollup@4.35.0): + rollup-plugin-polyfill-node@0.13.0(rollup@4.40.2): dependencies: - '@rollup/plugin-inject': 5.0.5(rollup@4.35.0) - rollup: 4.35.0 + '@rollup/plugin-inject': 5.0.5(rollup@4.40.2) + rollup: 4.40.2 - rollup-plugin-styles@4.0.0(rollup@4.35.0): + rollup-plugin-styles@4.0.0(rollup@4.40.2): dependencies: '@rollup/pluginutils': 4.2.1 '@types/cssnano': 5.1.3(postcss@8.5.3) @@ -19331,19 +16627,10 @@ snapshots: postcss-value-parser: 4.2.0 query-string: 7.1.3 resolve: 1.22.10 - rollup: 4.35.0 + rollup: 4.40.2 source-map-js: 1.2.1 tslib: 2.8.1 - rollup-plugin-visualizer@5.14.0(rollup@4.39.0): - dependencies: - open: 8.4.2 - picomatch: 4.0.2 - source-map: 0.7.4 - yargs: 17.7.2 - optionalDependencies: - rollup: 4.39.0 - rollup-plugin-visualizer@5.14.0(rollup@4.40.2): dependencies: open: 8.4.2 @@ -19353,57 +16640,6 @@ snapshots: optionalDependencies: rollup: 4.40.2 - rollup@4.35.0: - dependencies: - '@types/estree': 1.0.6 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.35.0 - '@rollup/rollup-android-arm64': 4.35.0 - '@rollup/rollup-darwin-arm64': 4.35.0 - '@rollup/rollup-darwin-x64': 4.35.0 - '@rollup/rollup-freebsd-arm64': 4.35.0 - '@rollup/rollup-freebsd-x64': 4.35.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.35.0 - '@rollup/rollup-linux-arm-musleabihf': 4.35.0 - '@rollup/rollup-linux-arm64-gnu': 4.35.0 - '@rollup/rollup-linux-arm64-musl': 4.35.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.35.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.35.0 - '@rollup/rollup-linux-riscv64-gnu': 4.35.0 - '@rollup/rollup-linux-s390x-gnu': 4.35.0 - '@rollup/rollup-linux-x64-gnu': 4.35.0 - '@rollup/rollup-linux-x64-musl': 4.35.0 - '@rollup/rollup-win32-arm64-msvc': 4.35.0 - '@rollup/rollup-win32-ia32-msvc': 4.35.0 - '@rollup/rollup-win32-x64-msvc': 4.35.0 - fsevents: 2.3.3 - - rollup@4.39.0: - dependencies: - '@types/estree': 1.0.7 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.39.0 - '@rollup/rollup-android-arm64': 4.39.0 - '@rollup/rollup-darwin-arm64': 4.39.0 - '@rollup/rollup-darwin-x64': 4.39.0 - '@rollup/rollup-freebsd-arm64': 4.39.0 - '@rollup/rollup-freebsd-x64': 4.39.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.39.0 - '@rollup/rollup-linux-arm-musleabihf': 4.39.0 - '@rollup/rollup-linux-arm64-gnu': 4.39.0 - '@rollup/rollup-linux-arm64-musl': 4.39.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.39.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.39.0 - '@rollup/rollup-linux-riscv64-gnu': 4.39.0 - '@rollup/rollup-linux-riscv64-musl': 4.39.0 - '@rollup/rollup-linux-s390x-gnu': 4.39.0 - '@rollup/rollup-linux-x64-gnu': 4.39.0 - '@rollup/rollup-linux-x64-musl': 4.39.0 - '@rollup/rollup-win32-arm64-msvc': 4.39.0 - '@rollup/rollup-win32-ia32-msvc': 4.39.0 - '@rollup/rollup-win32-x64-msvc': 4.39.0 - fsevents: 2.3.3 - rollup@4.40.2: dependencies: '@types/estree': 1.0.7 @@ -19430,7 +16666,8 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.40.2 fsevents: 2.3.3 - rrweb-cssom@0.8.0: {} + rrweb-cssom@0.8.0: + optional: true run-applescript@7.0.0: {} @@ -19465,10 +16702,10 @@ snapshots: safer-buffer@2.1.2: {} - sass@1.85.1: + sass@1.89.0: dependencies: chokidar: 4.0.3 - immutable: 5.0.3 + immutable: 5.1.2 source-map-js: 1.2.1 optionalDependencies: '@parcel/watcher': 2.5.1 @@ -19476,10 +16713,9 @@ snapshots: saxes@6.0.0: dependencies: xmlchars: 2.2.0 + optional: true - scheduler@0.23.2: - dependencies: - loose-envify: 1.4.0 + scheduler@0.26.0: {} scslre@0.3.0: dependencies: @@ -19495,39 +16731,27 @@ snapshots: dependencies: secure-random-octet: 2.0.0 + secure-random-bytes@5.0.1: + dependencies: + secure-random-octet: 4.0.1 + secure-random-octet@2.0.0: dependencies: get-random-values: 1.2.2 + secure-random-octet@4.0.1: + dependencies: + get-random-values: 3.0.0 + semver@5.7.2: {} semver@6.3.1: {} - semver@7.7.1: {} - semver@7.7.2: {} - send@0.19.0: - dependencies: - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 0.5.2 - http-errors: 2.0.0 - mime: 1.6.0 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - send@1.2.0: dependencies: - debug: 4.4.0 + debug: 4.4.1 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 @@ -19549,15 +16773,6 @@ snapshots: dependencies: defu: 6.1.4 - serve-static@1.16.2: - dependencies: - encodeurl: 2.0.0 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 0.19.0 - transitivePeerDependencies: - - supports-color - serve-static@2.2.0: dependencies: encodeurl: 2.0.0 @@ -19567,8 +16782,6 @@ snapshots: transitivePeerDependencies: - supports-color - set-blocking@2.0.0: {} - set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -19591,8 +16804,6 @@ snapshots: es-errors: 1.3.0 es-object-atoms: 1.1.1 - setimmediate@1.0.5: {} - setprototypeof@1.2.0: {} sha.js@2.4.11: @@ -19600,6 +16811,35 @@ snapshots: inherits: 2.0.4 safe-buffer: 5.2.1 + sharp@0.34.2: + dependencies: + color: 4.2.3 + detect-libc: 2.0.4 + semver: 7.7.2 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.2 + '@img/sharp-darwin-x64': 0.34.2 + '@img/sharp-libvips-darwin-arm64': 1.1.0 + '@img/sharp-libvips-darwin-x64': 1.1.0 + '@img/sharp-libvips-linux-arm': 1.1.0 + '@img/sharp-libvips-linux-arm64': 1.1.0 + '@img/sharp-libvips-linux-ppc64': 1.1.0 + '@img/sharp-libvips-linux-s390x': 1.1.0 + '@img/sharp-libvips-linux-x64': 1.1.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + '@img/sharp-linux-arm': 0.34.2 + '@img/sharp-linux-arm64': 0.34.2 + '@img/sharp-linux-s390x': 0.34.2 + '@img/sharp-linux-x64': 0.34.2 + '@img/sharp-linuxmusl-arm64': 0.34.2 + '@img/sharp-linuxmusl-x64': 0.34.2 + '@img/sharp-wasm32': 0.34.2 + '@img/sharp-win32-arm64': 0.34.2 + '@img/sharp-win32-ia32': 0.34.2 + '@img/sharp-win32-x64': 0.34.2 + optional: true + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -19657,7 +16897,7 @@ snapshots: dependencies: '@kwsites/file-exists': 1.1.1 '@kwsites/promise-deferred': 1.1.1 - debug: 4.4.0 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -19667,7 +16907,7 @@ snapshots: sirv@3.0.1: dependencies: - '@polka/url': 1.0.0-next.28 + '@polka/url': 1.0.0-next.29 mrmime: 2.0.1 totalist: 3.0.1 @@ -19677,8 +16917,6 @@ snapshots: slash@5.1.0: {} - slashes@3.0.12: {} - slice-ansi@4.0.0: dependencies: ansi-styles: 4.3.0 @@ -19694,8 +16932,6 @@ snapshots: buffer-from: 1.1.2 source-map: 0.6.1 - source-map@0.5.7: {} - source-map@0.6.1: {} source-map@0.7.4: {} @@ -19744,8 +16980,6 @@ snapshots: statuses@2.0.1: {} - std-env@3.8.1: {} - std-env@3.9.0: {} stream-browserify@3.0.0: @@ -19753,12 +16987,7 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - stream-http@3.2.0: - dependencies: - builtin-status-codes: 3.0.0 - inherits: 2.0.4 - readable-stream: 3.6.2 - xtend: 4.0.2 + streamsearch@1.1.0: {} streamx@2.22.0: dependencies: @@ -19856,8 +17085,6 @@ snapshots: strip-final-newline@3.0.0: {} - strip-final-newline@4.0.0: {} - strip-indent@3.0.0: dependencies: min-indent: 1.0.1 @@ -19872,25 +17099,18 @@ snapshots: dependencies: js-tokens: 9.0.1 - strong-log-transformer@2.1.0: - dependencies: - duplexer: 0.1.2 - minimist: 1.2.8 - through: 2.3.8 - structured-clone-es@1.0.0: {} style-search@0.1.0: {} - stylehacks@5.1.1(postcss@8.5.3): + styled-jsx@5.1.6(react@19.1.0): dependencies: - browserslist: 4.24.4 - postcss: 8.5.3 - postcss-selector-parser: 6.1.2 + client-only: 0.0.1 + react: 19.1.0 - stylehacks@7.0.4(postcss@8.5.3): + stylehacks@5.1.1(postcss@8.5.3): dependencies: - browserslist: 4.24.4 + browserslist: 4.24.5 postcss: 8.5.3 postcss-selector-parser: 6.1.2 @@ -19945,7 +17165,7 @@ snapshots: cosmiconfig: 8.3.6(typescript@5.1.6) css-functions-list: 3.2.3 css-tree: 2.3.1 - debug: 4.4.0 + debug: 4.4.1 fast-glob: 3.3.3 fastest-levenshtein: 1.0.16 file-entry-cache: 6.0.1 @@ -19982,8 +17202,6 @@ snapshots: - supports-color - typescript - stylis@4.2.0: {} - superjson@2.2.2: dependencies: copy-anything: 3.0.5 @@ -20001,8 +17219,6 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svg-country-flags@1.2.10: {} - svg-tags@1.0.0: {} svgo@2.8.0: @@ -20025,12 +17241,12 @@ snapshots: csso: 5.0.5 picocolors: 1.1.1 - symbol-tree@3.2.4: {} + symbol-tree@3.2.4: + optional: true - synckit@0.9.2: + synckit@0.11.6: dependencies: - '@pkgr/core': 0.1.1 - tslib: 2.8.1 + '@pkgr/core': 0.2.4 system-architecture@0.1.0: {} @@ -20044,7 +17260,7 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - tapable@2.2.1: {} + tapable@2.2.2: {} tar-stream@2.2.0: dependencies: @@ -20060,15 +17276,6 @@ snapshots: fast-fifo: 1.3.2 streamx: 2.22.0 - tar@6.2.1: - dependencies: - chownr: 2.0.0 - fs-minipass: 2.1.0 - minipass: 5.0.0 - minizlib: 2.1.2 - mkdirp: 1.0.4 - yallist: 4.0.0 - tar@7.4.3: dependencies: '@isaacs/fs-minipass': 4.0.1 @@ -20080,7 +17287,7 @@ snapshots: term-size@2.2.1: {} - terser@5.39.0: + terser@5.39.2: dependencies: '@jridgewell/source-map': 0.3.6 acorn: 8.14.1 @@ -20101,12 +17308,6 @@ snapshots: text-table@0.2.0: {} - through@2.3.8: {} - - timers-browserify@2.0.12: - dependencies: - setimmediate: 1.0.5 - tiny-invariant@1.3.3: {} tinybench@2.9.0: {} @@ -20115,11 +17316,6 @@ snapshots: tinyexec@1.0.1: {} - tinyglobby@0.2.12: - dependencies: - fdir: 6.4.3(picomatch@4.0.2) - picomatch: 4.0.2 - tinyglobby@0.2.13: dependencies: fdir: 6.4.4(picomatch@4.0.2) @@ -20131,11 +17327,13 @@ snapshots: tinyspy@3.0.2: {} - tldts-core@6.1.84: {} + tldts-core@6.1.86: + optional: true - tldts@6.1.84: + tldts@6.1.86: dependencies: - tldts-core: 6.1.84 + tldts-core: 6.1.86 + optional: true tmp-promise@3.0.3: dependencies: @@ -20159,13 +17357,15 @@ snapshots: tough-cookie@5.1.2: dependencies: - tldts: 6.1.84 + tldts: 6.1.86 + optional: true tr46@0.0.3: {} - tr46@5.1.0: + tr46@5.1.1: dependencies: punycode: 2.3.1 + optional: true trim-lines@3.0.1: {} @@ -20177,15 +17377,15 @@ snapshots: dependencies: typescript: 5.1.6 - ts-api-utils@2.0.1(typescript@5.1.6): + ts-api-utils@1.4.3(typescript@5.8.3): dependencies: - typescript: 5.1.6 + typescript: 5.8.3 - ts-api-utils@2.0.1(typescript@5.8.3): + ts-api-utils@2.1.0(typescript@5.8.3): dependencies: typescript: 5.8.3 - tsconfck@3.1.5(typescript@5.8.3): + tsconfck@3.1.6(typescript@5.8.3): optionalDependencies: typescript: 5.8.3 @@ -20211,12 +17411,10 @@ snapshots: tslib: 1.14.1 typescript: 5.1.6 - tsutils@3.21.0(typescript@5.8.3): + tsutils@3.21.0(typescript@5.7.3): dependencies: tslib: 1.14.1 - typescript: 5.8.3 - - tty-browserify@0.0.1: {} + typescript: 5.7.3 type-check@0.4.0: dependencies: @@ -20230,7 +17428,7 @@ snapshots: type-fest@0.8.1: {} - type-fest@4.39.1: {} + type-fest@4.41.0: {} type-level-regexp@0.1.17: {} @@ -20267,21 +17465,21 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.26.1(eslint@8.57.1)(typescript@5.1.6): + typescript-eslint@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.26.1(@typescript-eslint/parser@8.26.1(eslint@8.57.1)(typescript@5.1.6))(eslint@8.57.1)(typescript@5.1.6) - '@typescript-eslint/parser': 8.26.1(eslint@8.57.1)(typescript@5.1.6) - '@typescript-eslint/utils': 8.26.1(eslint@8.57.1)(typescript@5.1.6) - eslint: 8.57.1 - typescript: 5.1.6 + '@typescript-eslint/eslint-plugin': 8.33.1(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.28.0(jiti@2.4.2) + typescript: 5.8.3 transitivePeerDependencies: - supports-color typescript@5.1.6: {} - typescript@5.8.3: {} + typescript@5.7.3: {} - ufo@1.5.4: {} + typescript@5.8.3: {} ufo@1.6.1: {} @@ -20294,31 +17492,31 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 - unbuild@3.5.0(sass@1.85.1)(typescript@5.8.3)(vue-sfc-transformer@0.1.11(esbuild@0.25.4)(vue@3.5.13(typescript@5.8.3)))(vue-tsc@2.2.8(typescript@5.8.3))(vue@3.5.13(typescript@5.8.3)): + unbuild@3.5.0(sass@1.89.0)(typescript@5.8.3)(vue-sfc-transformer@0.1.16(@vue/compiler-core@3.5.14)(esbuild@0.25.4)(vue@3.5.14(typescript@5.8.3)))(vue-tsc@2.2.10(typescript@5.8.3))(vue@3.5.14(typescript@5.8.3)): dependencies: - '@rollup/plugin-alias': 5.1.1(rollup@4.39.0) - '@rollup/plugin-commonjs': 28.0.3(rollup@4.39.0) - '@rollup/plugin-json': 6.1.0(rollup@4.39.0) - '@rollup/plugin-node-resolve': 16.0.1(rollup@4.39.0) - '@rollup/plugin-replace': 6.0.2(rollup@4.39.0) - '@rollup/pluginutils': 5.1.4(rollup@4.39.0) + '@rollup/plugin-alias': 5.1.1(rollup@4.40.2) + '@rollup/plugin-commonjs': 28.0.3(rollup@4.40.2) + '@rollup/plugin-json': 6.1.0(rollup@4.40.2) + '@rollup/plugin-node-resolve': 16.0.1(rollup@4.40.2) + '@rollup/plugin-replace': 6.0.2(rollup@4.40.2) + '@rollup/pluginutils': 5.1.4(rollup@4.40.2) citty: 0.1.6 consola: 3.4.2 defu: 6.1.4 - esbuild: 0.25.2 + esbuild: 0.25.4 fix-dts-default-cjs-exports: 1.0.1 hookable: 5.5.3 jiti: 2.4.2 magic-string: 0.30.17 - mkdist: 2.3.0(sass@1.85.1)(typescript@5.8.3)(vue-sfc-transformer@0.1.11(esbuild@0.25.4)(vue@3.5.13(typescript@5.8.3)))(vue-tsc@2.2.8(typescript@5.8.3))(vue@3.5.13(typescript@5.8.3)) + mkdist: 2.3.0(sass@1.89.0)(typescript@5.8.3)(vue-sfc-transformer@0.1.16(@vue/compiler-core@3.5.14)(esbuild@0.25.4)(vue@3.5.14(typescript@5.8.3)))(vue-tsc@2.2.10(typescript@5.8.3))(vue@3.5.14(typescript@5.8.3)) mlly: 1.7.4 pathe: 2.0.3 pkg-types: 2.1.0 pretty-bytes: 6.1.1 - rollup: 4.39.0 - rollup-plugin-dts: 6.1.1(rollup@4.39.0)(typescript@5.8.3) + rollup: 4.40.2 + rollup-plugin-dts: 6.2.1(rollup@4.40.2)(typescript@5.8.3) scule: 1.3.0 - tinyglobby: 0.2.12 + tinyglobby: 0.2.13 untyped: 2.0.0 optionalDependencies: typescript: 5.8.3 @@ -20335,22 +17533,12 @@ snapshots: acorn: 8.14.1 estree-walker: 3.0.3 magic-string: 0.30.17 - unplugin: 2.2.2 + unplugin: 2.3.4 undici-types@6.19.8: {} - undici-types@6.20.0: {} - undici-types@6.21.0: {} - unenv@2.0.0-rc.15: - dependencies: - defu: 6.1.4 - exsolve: 1.0.4 - ohash: 2.0.11 - pathe: 2.0.3 - ufo: 1.5.4 - unenv@2.0.0-rc.17: dependencies: defu: 6.1.4 @@ -20359,11 +17547,7 @@ snapshots: pathe: 2.0.3 ufo: 1.6.1 - unhead@2.0.5: - dependencies: - hookable: 5.5.3 - - unhead@2.0.8: + unhead@2.0.10: dependencies: hookable: 5.5.3 @@ -20371,23 +17555,6 @@ snapshots: unicorn-magic@0.3.0: {} - unimport@4.1.3: - dependencies: - acorn: 8.14.1 - escape-string-regexp: 5.0.0 - estree-walker: 3.0.3 - local-pkg: 1.1.1 - magic-string: 0.30.17 - mlly: 1.7.4 - pathe: 2.0.3 - picomatch: 4.0.2 - pkg-types: 2.1.0 - scule: 1.3.0 - strip-literal: 3.0.0 - tinyglobby: 0.2.12 - unplugin: 2.2.2 - unplugin-utils: 0.2.4 - unimport@5.0.1: dependencies: acorn: 8.14.1 @@ -20441,32 +17608,10 @@ snapshots: pathe: 2.0.3 picomatch: 4.0.2 - unplugin-vue-router@0.12.0(vue-router@4.5.0(vue@3.5.13(typescript@5.8.3)))(vue@3.5.13(typescript@5.8.3)): - dependencies: - '@babel/types': 7.26.10 - '@vue-macros/common': 1.16.1(vue@3.5.13(typescript@5.8.3)) - ast-walker-scope: 0.6.2 - chokidar: 4.0.3 - fast-glob: 3.3.3 - json5: 2.2.3 - local-pkg: 1.1.1 - magic-string: 0.30.17 - micromatch: 4.0.8 - mlly: 1.7.4 - pathe: 2.0.3 - scule: 1.3.0 - unplugin: 2.2.2 - unplugin-utils: 0.2.4 - yaml: 2.7.1 - optionalDependencies: - vue-router: 4.5.0(vue@3.5.13(typescript@5.8.3)) - transitivePeerDependencies: - - vue - - unplugin-vue-router@0.12.0(vue-router@4.5.1(vue@3.5.13(typescript@5.8.3)))(vue@3.5.13(typescript@5.8.3)): + unplugin-vue-router@0.12.0(vue-router@4.5.1(vue@3.5.14(typescript@5.8.3)))(vue@3.5.14(typescript@5.8.3)): dependencies: - '@babel/types': 7.26.10 - '@vue-macros/common': 1.16.1(vue@3.5.13(typescript@5.8.3)) + '@babel/types': 7.27.1 + '@vue-macros/common': 1.16.1(vue@3.5.14(typescript@5.8.3)) ast-walker-scope: 0.6.2 chokidar: 4.0.3 fast-glob: 3.3.3 @@ -20477,11 +17622,11 @@ snapshots: mlly: 1.7.4 pathe: 2.0.3 scule: 1.3.0 - unplugin: 2.2.2 + unplugin: 2.3.4 unplugin-utils: 0.2.4 - yaml: 2.7.1 + yaml: 2.8.0 optionalDependencies: - vue-router: 4.5.1(vue@3.5.13(typescript@5.8.3)) + vue-router: 4.5.1(vue@3.5.14(typescript@5.8.3)) transitivePeerDependencies: - vue @@ -20490,49 +17635,33 @@ snapshots: acorn: 8.14.1 webpack-virtual-modules: 0.6.2 - unplugin@2.2.2: - dependencies: - acorn: 8.14.1 - webpack-virtual-modules: 0.6.2 - unplugin@2.3.4: dependencies: acorn: 8.14.1 picomatch: 4.0.2 webpack-virtual-modules: 0.6.2 - unrs-resolver@1.5.0: - optionalDependencies: - '@unrs/resolver-binding-darwin-arm64': 1.5.0 - '@unrs/resolver-binding-darwin-x64': 1.5.0 - '@unrs/resolver-binding-freebsd-x64': 1.5.0 - '@unrs/resolver-binding-linux-arm-gnueabihf': 1.5.0 - '@unrs/resolver-binding-linux-arm-musleabihf': 1.5.0 - '@unrs/resolver-binding-linux-arm64-gnu': 1.5.0 - '@unrs/resolver-binding-linux-arm64-musl': 1.5.0 - '@unrs/resolver-binding-linux-ppc64-gnu': 1.5.0 - '@unrs/resolver-binding-linux-riscv64-gnu': 1.5.0 - '@unrs/resolver-binding-linux-s390x-gnu': 1.5.0 - '@unrs/resolver-binding-linux-x64-gnu': 1.5.0 - '@unrs/resolver-binding-linux-x64-musl': 1.5.0 - '@unrs/resolver-binding-wasm32-wasi': 1.5.0 - '@unrs/resolver-binding-win32-arm64-msvc': 1.5.0 - '@unrs/resolver-binding-win32-ia32-msvc': 1.5.0 - '@unrs/resolver-binding-win32-x64-msvc': 1.5.0 - - unstorage@1.15.0(db0@0.3.1)(ioredis@5.6.0): + unrs-resolver@1.7.2: dependencies: - anymatch: 3.1.3 - chokidar: 4.0.3 - destr: 2.0.5 - h3: 1.15.1 - lru-cache: 10.4.3 - node-fetch-native: 1.6.6 - ofetch: 1.4.1 - ufo: 1.5.4 + napi-postinstall: 0.2.4 optionalDependencies: - db0: 0.3.1 - ioredis: 5.6.0 + '@unrs/resolver-binding-darwin-arm64': 1.7.2 + '@unrs/resolver-binding-darwin-x64': 1.7.2 + '@unrs/resolver-binding-freebsd-x64': 1.7.2 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.7.2 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.7.2 + '@unrs/resolver-binding-linux-arm64-gnu': 1.7.2 + '@unrs/resolver-binding-linux-arm64-musl': 1.7.2 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.7.2 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.7.2 + '@unrs/resolver-binding-linux-riscv64-musl': 1.7.2 + '@unrs/resolver-binding-linux-s390x-gnu': 1.7.2 + '@unrs/resolver-binding-linux-x64-gnu': 1.7.2 + '@unrs/resolver-binding-linux-x64-musl': 1.7.2 + '@unrs/resolver-binding-wasm32-wasi': 1.7.2 + '@unrs/resolver-binding-win32-arm64-msvc': 1.7.2 + '@unrs/resolver-binding-win32-ia32-msvc': 1.7.2 + '@unrs/resolver-binding-win32-x64-msvc': 1.7.2 unstorage@1.16.0(db0@0.3.2)(ioredis@5.6.1): dependencies: @@ -20571,12 +17700,6 @@ snapshots: pkg-types: 1.3.1 unplugin: 1.16.1 - update-browserslist-db@1.1.3(browserslist@4.24.4): - dependencies: - browserslist: 4.24.4 - escalade: 3.2.0 - picocolors: 1.1.1 - update-browserslist-db@1.1.3(browserslist@4.24.5): dependencies: browserslist: 4.24.5 @@ -20589,25 +17712,12 @@ snapshots: dependencies: punycode: 2.3.1 - url@0.11.4: - dependencies: - punycode: 1.4.1 - qs: 6.14.0 - urlpattern-polyfill@10.1.0: {} urlpattern-polyfill@8.0.2: {} util-deprecate@1.0.2: {} - util@0.12.5: - dependencies: - inherits: 2.0.4 - is-arguments: 1.2.0 - is-generator-function: 1.1.0 - is-typed-array: 1.1.15 - which-typed-array: 1.1.19 - uuid@11.1.0: {} uuid@8.3.2: {} @@ -20629,45 +17739,23 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite-dev-rpc@1.0.7(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)): - dependencies: - birpc: 2.3.0 - vite: 6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vite-hot-client: 2.0.4(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) - - vite-dev-rpc@1.0.7(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)): + vite-dev-rpc@1.0.7(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0)): dependencies: birpc: 2.3.0 - vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vite-hot-client: 2.0.4(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) - - vite-hot-client@0.2.4(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)): - dependencies: - vite: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - - vite-hot-client@0.2.4(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)): - dependencies: - vite: 6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - - vite-hot-client@0.2.4(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)): - dependencies: - vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + vite-hot-client: 2.0.4(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0)) - vite-hot-client@2.0.4(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)): + vite-hot-client@2.0.4(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0)): dependencies: - vite: 6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) - vite-hot-client@2.0.4(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)): - dependencies: - vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - - vite-node@3.0.8(@types/node@20.17.24)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1): + vite-node@3.1.3(@types/node@20.17.50)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0): dependencies: cac: 6.7.14 - debug: 4.4.0 - es-module-lexer: 1.6.0 + debug: 4.4.1 + es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.2.2(@types/node@20.17.24)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.5(@types/node@20.17.50)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) transitivePeerDependencies: - '@types/node' - jiti @@ -20682,13 +17770,13 @@ snapshots: - tsx - yaml - vite-node@3.0.8(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1): + vite-node@3.1.3(@types/node@22.15.18)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0): dependencies: cac: 6.7.14 - debug: 4.4.0 - es-module-lexer: 1.6.0 + debug: 4.4.1 + es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) transitivePeerDependencies: - '@types/node' - jiti @@ -20703,13 +17791,13 @@ snapshots: - tsx - yaml - vite-node@3.1.1(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1): + vite-node@3.1.3(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0): dependencies: cac: 6.7.14 - debug: 4.4.0 - es-module-lexer: 1.6.0 + debug: 4.4.1 + es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) transitivePeerDependencies: - '@types/node' - jiti @@ -20724,13 +17812,13 @@ snapshots: - tsx - yaml - vite-node@3.1.3(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1): + vite-node@3.1.4(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0): dependencies: cac: 6.7.14 - debug: 4.4.0 + debug: 4.4.1 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) transitivePeerDependencies: - '@types/node' - jiti @@ -20745,25 +17833,7 @@ snapshots: - tsx - yaml - vite-plugin-checker@0.9.1(eslint@8.57.1)(optionator@0.9.4)(typescript@5.8.3)(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue-tsc@2.2.8(typescript@5.8.3)): - dependencies: - '@babel/code-frame': 7.26.2 - chokidar: 4.0.3 - npm-run-path: 6.0.0 - picocolors: 1.1.1 - picomatch: 4.0.2 - strip-ansi: 7.1.0 - tiny-invariant: 1.3.3 - tinyglobby: 0.2.12 - vite: 6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vscode-uri: 3.1.0 - optionalDependencies: - eslint: 8.57.1 - optionator: 0.9.4 - typescript: 5.8.3 - vue-tsc: 2.2.8(typescript@5.8.3) - - vite-plugin-checker@0.9.3(eslint@8.57.1)(optionator@0.9.4)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)): + vite-plugin-checker@0.9.3(eslint@8.57.0)(optionator@0.9.4)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue-tsc@2.2.10(typescript@5.8.3)): dependencies: '@babel/code-frame': 7.27.1 chokidar: 4.0.3 @@ -20773,208 +17843,120 @@ snapshots: strip-ansi: 7.1.0 tiny-invariant: 1.3.3 tinyglobby: 0.2.13 - vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) vscode-uri: 3.1.0 optionalDependencies: - eslint: 8.57.1 + eslint: 8.57.0 optionator: 0.9.4 typescript: 5.8.3 + vue-tsc: 2.2.10(typescript@5.8.3) - vite-plugin-inspect@0.8.9(rollup@4.40.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)): - dependencies: - '@antfu/utils': 0.7.10 - '@rollup/pluginutils': 5.1.4(rollup@4.40.2) - debug: 4.4.0 - error-stack-parser-es: 0.1.5 - fs-extra: 11.3.0 - open: 10.1.0 - perfect-debounce: 1.0.0 - picocolors: 1.1.1 - sirv: 3.0.1 - vite: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - transitivePeerDependencies: - - rollup - - supports-color - - vite-plugin-inspect@11.0.0(@nuxt/kit@3.16.2(magicast@0.3.5))(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)): - dependencies: - ansis: 3.17.0 - debug: 4.4.0 - error-stack-parser-es: 1.0.5 - ohash: 2.0.11 - open: 10.1.0 - perfect-debounce: 1.0.0 - sirv: 3.0.1 - unplugin-utils: 0.2.4 - vite: 6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vite-dev-rpc: 1.0.7(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) - optionalDependencies: - '@nuxt/kit': 3.16.2(magicast@0.3.5) - transitivePeerDependencies: - - supports-color - - vite-plugin-inspect@11.0.0(@nuxt/kit@3.16.2(magicast@0.3.5))(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)): + vite-plugin-inspect@11.1.0(@nuxt/kit@3.17.4(magicast@0.3.5))(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0)): dependencies: ansis: 3.17.0 - debug: 4.4.0 + debug: 4.4.1 error-stack-parser-es: 1.0.5 ohash: 2.0.11 - open: 10.1.0 + open: 10.1.2 perfect-debounce: 1.0.0 sirv: 3.0.1 unplugin-utils: 0.2.4 - vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vite-dev-rpc: 1.0.7(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) + vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + vite-dev-rpc: 1.0.7(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0)) optionalDependencies: - '@nuxt/kit': 3.16.2(magicast@0.3.5) - transitivePeerDependencies: - - supports-color - - vite-plugin-node-polyfills@0.21.0(rollup@4.40.2)(vite@5.4.14(@types/node@22.15.18)(sass@1.85.1)(terser@5.39.0)): - dependencies: - '@rollup/plugin-inject': 5.0.5(rollup@4.40.2) - node-stdlib-browser: 1.3.1 - vite: 5.4.14(@types/node@22.15.18)(sass@1.85.1)(terser@5.39.0) - transitivePeerDependencies: - - rollup - - vite-plugin-vue-devtools@7.7.2(rollup@4.40.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.1.6)): - dependencies: - '@vue/devtools-core': 7.7.2(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.1.6)) - '@vue/devtools-kit': 7.7.2 - '@vue/devtools-shared': 7.7.2 - execa: 9.5.2 - sirv: 3.0.1 - vite: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vite-plugin-inspect: 0.8.9(rollup@4.40.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) - vite-plugin-vue-inspector: 5.3.1(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) - transitivePeerDependencies: - - '@nuxt/kit' - - rollup - - supports-color - - vue - - vite-plugin-vue-inspector@5.3.1(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)): - dependencies: - '@babel/core': 7.26.10 - '@babel/plugin-proposal-decorators': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.26.10) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.26.10) - '@babel/plugin-transform-typescript': 7.26.8(@babel/core@7.26.10) - '@vue/babel-plugin-jsx': 1.4.0(@babel/core@7.26.10) - '@vue/compiler-dom': 3.5.13 - kolorist: 1.8.0 - magic-string: 0.30.17 - vite: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + '@nuxt/kit': 3.17.4(magicast@0.3.5) transitivePeerDependencies: - supports-color - vite-plugin-vue-tracer@0.1.3(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)): - dependencies: - estree-walker: 3.0.3 - exsolve: 1.0.4 - magic-string: 0.30.17 - pathe: 2.0.3 - source-map-js: 1.2.1 - vite: 6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vue: 3.5.13(typescript@5.8.3) - - vite-plugin-vue-tracer@0.1.3(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)): + vite-plugin-vue-tracer@0.1.3(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3)): dependencies: estree-walker: 3.0.3 - exsolve: 1.0.4 + exsolve: 1.0.5 magic-string: 0.30.17 pathe: 2.0.3 source-map-js: 1.2.1 - vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vue: 3.5.13(typescript@5.8.3) + vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + vue: 3.5.14(typescript@5.8.3) - vite@5.4.14(@types/node@22.15.18)(sass@1.85.1)(terser@5.39.0): + vite@5.4.19(@types/node@22.15.29)(sass@1.89.0)(terser@5.39.2): dependencies: esbuild: 0.21.5 postcss: 8.5.3 - rollup: 4.35.0 - optionalDependencies: - '@types/node': 22.15.18 - fsevents: 2.3.3 - sass: 1.85.1 - terser: 5.39.0 - - vite@6.2.2(@types/node@20.17.24)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1): - dependencies: - esbuild: 0.25.1 - postcss: 8.5.3 - rollup: 4.35.0 + rollup: 4.40.2 optionalDependencies: - '@types/node': 20.17.24 + '@types/node': 22.15.29 fsevents: 2.3.3 - jiti: 2.4.2 - sass: 1.85.1 - terser: 5.39.0 - yaml: 2.7.1 + sass: 1.89.0 + terser: 5.39.2 - vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1): + vite@6.3.5(@types/node@20.17.50)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0): dependencies: - esbuild: 0.25.1 + esbuild: 0.25.4 + fdir: 6.4.4(picomatch@4.0.2) + picomatch: 4.0.2 postcss: 8.5.3 - rollup: 4.35.0 + rollup: 4.40.2 + tinyglobby: 0.2.13 optionalDependencies: - '@types/node': 22.13.10 + '@types/node': 20.17.50 fsevents: 2.3.3 jiti: 2.4.2 - sass: 1.85.1 - terser: 5.39.0 - yaml: 2.7.1 + sass: 1.89.0 + terser: 5.39.2 + yaml: 2.8.0 - vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1): + vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0): dependencies: - esbuild: 0.25.2 + esbuild: 0.25.4 + fdir: 6.4.4(picomatch@4.0.2) + picomatch: 4.0.2 postcss: 8.5.3 - rollup: 4.39.0 + rollup: 4.40.2 + tinyglobby: 0.2.13 optionalDependencies: - '@types/node': 22.14.1 + '@types/node': 22.15.18 fsevents: 2.3.3 jiti: 2.4.2 - sass: 1.85.1 - terser: 5.39.0 - yaml: 2.7.1 + sass: 1.89.0 + terser: 5.39.2 + yaml: 2.8.0 - vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1): + vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0): dependencies: esbuild: 0.25.4 fdir: 6.4.4(picomatch@4.0.2) picomatch: 4.0.2 postcss: 8.5.3 - rollup: 4.39.0 + rollup: 4.40.2 tinyglobby: 0.2.13 optionalDependencies: - '@types/node': 22.15.18 + '@types/node': 22.15.29 fsevents: 2.3.3 jiti: 2.4.2 - sass: 1.85.1 - terser: 5.39.0 - yaml: 2.7.1 + sass: 1.89.0 + terser: 5.39.2 + yaml: 2.8.0 - vitepress@1.6.3(@algolia/client-search@5.21.0)(@types/node@22.15.18)(@types/react@18.3.18)(axios@1.8.4)(fuse.js@7.1.0)(jwt-decode@4.0.0)(postcss@8.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1)(search-insights@2.17.3)(terser@5.39.0)(typescript@5.8.3): + vitepress@1.6.3(@algolia/client-search@5.25.0)(@types/node@22.15.29)(axios@1.9.0)(fuse.js@7.1.0)(jwt-decode@4.0.0)(postcss@8.5.3)(sass@1.89.0)(search-insights@2.17.3)(terser@5.39.2)(typescript@5.8.3): dependencies: '@docsearch/css': 3.8.2 - '@docsearch/js': 3.8.2(@algolia/client-search@5.21.0)(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3) - '@iconify-json/simple-icons': 1.2.28 + '@docsearch/js': 3.8.2(@algolia/client-search@5.25.0)(search-insights@2.17.3) + '@iconify-json/simple-icons': 1.2.35 '@shikijs/core': 2.5.0 '@shikijs/transformers': 2.5.0 '@shikijs/types': 2.5.0 '@types/markdown-it': 14.1.2 - '@vitejs/plugin-vue': 5.2.1(vite@5.4.14(@types/node@22.15.18)(sass@1.85.1)(terser@5.39.0))(vue@3.5.13(typescript@5.8.3)) - '@vue/devtools-api': 7.7.2 - '@vue/shared': 3.5.13 + '@vitejs/plugin-vue': 5.2.4(vite@5.4.19(@types/node@22.15.29)(sass@1.89.0)(terser@5.39.2))(vue@3.5.14(typescript@5.8.3)) + '@vue/devtools-api': 7.7.6 + '@vue/shared': 3.5.14 '@vueuse/core': 12.8.2(typescript@5.8.3) - '@vueuse/integrations': 12.8.2(axios@1.8.4)(focus-trap@7.6.4)(fuse.js@7.1.0)(jwt-decode@4.0.0)(typescript@5.8.3) + '@vueuse/integrations': 12.8.2(axios@1.9.0)(focus-trap@7.6.4)(fuse.js@7.1.0)(jwt-decode@4.0.0)(typescript@5.8.3) focus-trap: 7.6.4 mark.js: 8.11.1 minisearch: 7.1.2 shiki: 2.5.0 - vite: 5.4.14(@types/node@22.15.18)(sass@1.85.1)(terser@5.39.0) - vue: 3.5.13(typescript@5.8.3) + vite: 5.4.19(@types/node@22.15.29)(sass@1.89.0)(terser@5.39.2) + vue: 3.5.14(typescript@5.8.3) optionalDependencies: postcss: 8.5.3 transitivePeerDependencies: @@ -21004,9 +17986,19 @@ snapshots: - typescript - universal-cookie - vitest-environment-nuxt@1.0.1(@types/node@22.14.1)(@vue/test-utils@2.4.6)(jiti@2.4.2)(jsdom@26.0.0)(magicast@0.3.5)(sass@1.85.1)(terser@5.39.0)(typescript@5.8.3)(vitest@3.1.1(@types/node@22.14.1)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(yaml@2.7.1): + vitest-browser-react@0.1.1(@types/react-dom@19.1.5(@types/react@19.1.5))(@types/react@19.1.5)(@vitest/browser@3.1.3)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(vitest@3.1.3): + dependencies: + '@vitest/browser': 3.1.3(playwright@1.52.0)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vitest@3.1.3) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + vitest: 3.1.3(@types/node@22.15.18)(@vitest/browser@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + optionalDependencies: + '@types/react': 19.1.5 + '@types/react-dom': 19.1.5(@types/react@19.1.5) + + vitest-environment-nuxt@1.0.1(@types/node@22.15.29)(@vue/test-utils@2.4.6)(jiti@2.4.2)(jsdom@26.1.0)(magicast@0.3.5)(playwright-core@1.52.0)(sass@1.89.0)(terser@5.39.2)(typescript@5.8.3)(vitest@3.1.3)(yaml@2.8.0): dependencies: - '@nuxt/test-utils': 3.17.2(@types/node@22.14.1)(@vue/test-utils@2.4.6)(jiti@2.4.2)(jsdom@26.0.0)(magicast@0.3.5)(sass@1.85.1)(terser@5.39.0)(typescript@5.8.3)(vitest@3.1.1(@types/node@22.14.1)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1))(yaml@2.7.1) + '@nuxt/test-utils': 3.19.0(@types/node@22.15.29)(@vue/test-utils@2.4.6)(jiti@2.4.2)(jsdom@26.1.0)(magicast@0.3.5)(playwright-core@1.52.0)(sass@1.89.0)(terser@5.39.2)(typescript@5.8.3)(vitest@3.1.3)(yaml@2.8.0) transitivePeerDependencies: - '@cucumber/cucumber' - '@jest/globals' @@ -21032,31 +18024,32 @@ snapshots: - vitest - yaml - vitest@3.0.8(@types/node@20.17.24)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1): + vitest@3.1.3(@types/node@20.17.50)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0): dependencies: - '@vitest/expect': 3.0.8 - '@vitest/mocker': 3.0.8(vite@6.2.2(@types/node@20.17.24)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) - '@vitest/pretty-format': 3.0.8 - '@vitest/runner': 3.0.8 - '@vitest/snapshot': 3.0.8 - '@vitest/spy': 3.0.8 - '@vitest/utils': 3.0.8 + '@vitest/expect': 3.1.3 + '@vitest/mocker': 3.1.3(vite@6.3.5(@types/node@20.17.50)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0)) + '@vitest/pretty-format': 3.1.3 + '@vitest/runner': 3.1.3 + '@vitest/snapshot': 3.1.3 + '@vitest/spy': 3.1.3 + '@vitest/utils': 3.1.3 chai: 5.2.0 - debug: 4.4.0 - expect-type: 1.2.0 + debug: 4.4.1 + expect-type: 1.2.1 magic-string: 0.30.17 pathe: 2.0.3 - std-env: 3.8.1 + std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 + tinyglobby: 0.2.13 tinypool: 1.0.2 tinyrainbow: 2.0.0 - vite: 6.2.2(@types/node@20.17.24)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vite-node: 3.0.8(@types/node@20.17.24)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.5(@types/node@20.17.50)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + vite-node: 3.1.3(@types/node@20.17.50)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 20.17.24 - jsdom: 26.0.0 + '@types/node': 20.17.50 + jsdom: 26.1.0 transitivePeerDependencies: - jiti - less @@ -21071,31 +18064,33 @@ snapshots: - tsx - yaml - vitest@3.0.8(@types/node@22.13.10)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1): + vitest@3.1.3(@types/node@22.15.18)(@vitest/browser@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0): dependencies: - '@vitest/expect': 3.0.8 - '@vitest/mocker': 3.0.8(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) - '@vitest/pretty-format': 3.0.8 - '@vitest/runner': 3.0.8 - '@vitest/snapshot': 3.0.8 - '@vitest/spy': 3.0.8 - '@vitest/utils': 3.0.8 + '@vitest/expect': 3.1.3 + '@vitest/mocker': 3.1.3(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0)) + '@vitest/pretty-format': 3.1.3 + '@vitest/runner': 3.1.3 + '@vitest/snapshot': 3.1.3 + '@vitest/spy': 3.1.3 + '@vitest/utils': 3.1.3 chai: 5.2.0 - debug: 4.4.0 - expect-type: 1.2.0 + debug: 4.4.1 + expect-type: 1.2.1 magic-string: 0.30.17 pathe: 2.0.3 - std-env: 3.8.1 + std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 + tinyglobby: 0.2.13 tinypool: 1.0.2 tinyrainbow: 2.0.0 - vite: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vite-node: 3.0.8(@types/node@22.13.10)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + vite-node: 3.1.3(@types/node@22.15.18)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.13.10 - jsdom: 26.0.0 + '@types/node': 22.15.18 + '@vitest/browser': 3.1.3(playwright@1.52.0)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vitest@3.1.3) + jsdom: 26.1.0 transitivePeerDependencies: - jiti - less @@ -21110,31 +18105,33 @@ snapshots: - tsx - yaml - vitest@3.1.1(@types/node@22.14.1)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1): + vitest@3.1.3(@types/node@22.15.29)(@vitest/browser@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0): dependencies: - '@vitest/expect': 3.1.1 - '@vitest/mocker': 3.1.1(vite@6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1)) - '@vitest/pretty-format': 3.1.1 - '@vitest/runner': 3.1.1 - '@vitest/snapshot': 3.1.1 - '@vitest/spy': 3.1.1 - '@vitest/utils': 3.1.1 + '@vitest/expect': 3.1.3 + '@vitest/mocker': 3.1.3(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0)) + '@vitest/pretty-format': 3.1.3 + '@vitest/runner': 3.1.3 + '@vitest/snapshot': 3.1.3 + '@vitest/spy': 3.1.3 + '@vitest/utils': 3.1.3 chai: 5.2.0 - debug: 4.4.0 - expect-type: 1.2.0 + debug: 4.4.1 + expect-type: 1.2.1 magic-string: 0.30.17 pathe: 2.0.3 - std-env: 3.8.1 + std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 + tinyglobby: 0.2.13 tinypool: 1.0.2 tinyrainbow: 2.0.0 - vite: 6.2.5(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) - vite-node: 3.1.1(@types/node@22.14.1)(jiti@2.4.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + vite-node: 3.1.3(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.14.1 - jsdom: 26.0.0 + '@types/node': 22.15.29 + '@vitest/browser': 3.1.3(playwright@1.52.0)(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vitest@3.1.3) + jsdom: 26.1.0 transitivePeerDependencies: - jiti - less @@ -21149,100 +18146,90 @@ snapshots: - tsx - yaml - vm-browserify@1.1.2: {} - vscode-uri@3.1.0: {} vue-bundle-renderer@2.1.1: dependencies: - ufo: 1.5.4 + ufo: 1.6.1 - vue-component-type-helpers@2.2.8: {} + vue-component-type-helpers@2.2.10: {} vue-devtools-stub@0.1.0: {} - vue-eslint-parser@10.1.1(eslint@8.57.1): + vue-eslint-parser@10.1.3(eslint@8.57.0): dependencies: - debug: 4.4.0 - eslint: 8.57.1 + debug: 4.4.1 + eslint: 8.57.0 eslint-scope: 8.3.0 eslint-visitor-keys: 4.2.0 espree: 10.3.0 esquery: 1.6.0 lodash: 4.17.21 - semver: 7.7.1 + semver: 7.7.2 transitivePeerDependencies: - supports-color - vue-eslint-parser@9.4.3(eslint@8.57.1): + vue-eslint-parser@9.4.3(eslint@8.57.0): dependencies: - debug: 4.4.0 - eslint: 8.57.1 + debug: 4.4.1 + eslint: 8.57.0 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 esquery: 1.6.0 lodash: 4.17.21 - semver: 7.7.1 + semver: 7.7.2 transitivePeerDependencies: - supports-color - vue-router@4.5.0(vue@3.5.13(typescript@5.1.6)): + vue-router@4.5.1(vue@3.5.14(typescript@5.8.3)): dependencies: '@vue/devtools-api': 6.6.4 - vue: 3.5.13(typescript@5.1.6) + vue: 3.5.14(typescript@5.8.3) - vue-router@4.5.0(vue@3.5.13(typescript@5.8.3)): + vue-sfc-transformer@0.1.16(@vue/compiler-core@3.5.14)(esbuild@0.25.4)(vue@3.5.14(typescript@5.8.3)): dependencies: - '@vue/devtools-api': 6.6.4 - vue: 3.5.13(typescript@5.8.3) - - vue-router@4.5.1(vue@3.5.13(typescript@5.8.3)): - dependencies: - '@vue/devtools-api': 6.6.4 - vue: 3.5.13(typescript@5.8.3) - - vue-sfc-transformer@0.1.11(esbuild@0.25.4)(vue@3.5.13(typescript@5.8.3)): - dependencies: - '@babel/parser': 7.27.0 + '@babel/parser': 7.27.2 + '@vue/compiler-core': 3.5.14 esbuild: 0.25.4 - vue: 3.5.13(typescript@5.8.3) + vue: 3.5.14(typescript@5.8.3) - vue-tsc@2.2.8(typescript@5.1.6): + vue-tsc@2.2.10(typescript@5.1.6): dependencies: - '@volar/typescript': 2.4.12 - '@vue/language-core': 2.2.8(typescript@5.1.6) + '@volar/typescript': 2.4.14 + '@vue/language-core': 2.2.10(typescript@5.1.6) typescript: 5.1.6 - vue-tsc@2.2.8(typescript@5.8.3): + vue-tsc@2.2.10(typescript@5.8.3): dependencies: - '@volar/typescript': 2.4.12 - '@vue/language-core': 2.2.8(typescript@5.8.3) + '@volar/typescript': 2.4.14 + '@vue/language-core': 2.2.10(typescript@5.8.3) typescript: 5.8.3 - vue@3.5.13(typescript@5.1.6): + vue@3.5.14(typescript@5.1.6): dependencies: - '@vue/compiler-dom': 3.5.13 - '@vue/compiler-sfc': 3.5.13 - '@vue/runtime-dom': 3.5.13 - '@vue/server-renderer': 3.5.13(vue@3.5.13(typescript@5.1.6)) - '@vue/shared': 3.5.13 + '@vue/compiler-dom': 3.5.14 + '@vue/compiler-sfc': 3.5.14 + '@vue/runtime-dom': 3.5.14 + '@vue/server-renderer': 3.5.14(vue@3.5.14(typescript@5.1.6)) + '@vue/shared': 3.5.14 optionalDependencies: typescript: 5.1.6 - vue@3.5.13(typescript@5.8.3): + vue@3.5.14(typescript@5.8.3): dependencies: - '@vue/compiler-dom': 3.5.13 - '@vue/compiler-sfc': 3.5.13 - '@vue/runtime-dom': 3.5.13 - '@vue/server-renderer': 3.5.13(vue@3.5.13(typescript@5.8.3)) - '@vue/shared': 3.5.13 + '@vue/compiler-dom': 3.5.14 + '@vue/compiler-sfc': 3.5.14 + '@vue/runtime-dom': 3.5.14 + '@vue/server-renderer': 3.5.14(vue@3.5.14(typescript@5.8.3)) + '@vue/shared': 3.5.14 optionalDependencies: typescript: 5.8.3 w3c-xmlserializer@5.0.0: dependencies: xml-name-validator: 5.0.0 + optional: true wcwidth@1.0.1: dependencies: @@ -21252,20 +18239,24 @@ snapshots: webidl-conversions@3.0.1: {} - webidl-conversions@7.0.0: {} + webidl-conversions@7.0.0: + optional: true webpack-virtual-modules@0.6.2: {} whatwg-encoding@3.1.1: dependencies: iconv-lite: 0.6.3 + optional: true - whatwg-mimetype@4.0.0: {} + whatwg-mimetype@4.0.0: + optional: true whatwg-url@14.2.0: dependencies: - tr46: 5.1.0 + tr46: 5.1.1 webidl-conversions: 7.0.0 + optional: true whatwg-url@5.0.0: dependencies: @@ -21330,10 +18321,6 @@ snapshots: siginfo: 2.0.0 stackback: 0.0.2 - wide-align@1.1.5: - dependencies: - string-width: 4.2.3 - winston-transport@4.9.0: dependencies: logform: 2.7.0 @@ -21356,8 +18343,6 @@ snapshots: word-wrap@1.2.5: {} - world-countries@5.1.0: {} - wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -21382,15 +18367,15 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 4.1.0 - ws@8.18.1: {} + ws@8.18.2: {} xml-name-validator@4.0.0: {} - xml-name-validator@5.0.0: {} - - xmlchars@2.2.0: {} + xml-name-validator@5.0.0: + optional: true - xtend@4.0.2: {} + xmlchars@2.2.0: + optional: true y18n@5.0.8: {} @@ -21402,7 +18387,7 @@ snapshots: yaml@1.10.2: {} - yaml@2.7.1: {} + yaml@2.8.0: {} yargs-parser@20.2.9: {} @@ -21427,20 +18412,11 @@ snapshots: yocto-queue@1.2.1: {} - yoctocolors@2.1.1: {} - youch-core@0.3.2: dependencies: '@poppinss/exception': 1.2.1 error-stack-parser-es: 1.0.5 - youch@4.1.0-beta.6: - dependencies: - '@poppinss/dumper': 0.6.3 - '@speed-highlight/core': 1.2.7 - cookie: 1.0.2 - youch-core: 0.3.2 - youch@4.1.0-beta.7: dependencies: '@poppinss/dumper': 0.6.3 @@ -21448,18 +18424,12 @@ snapshots: cookie: 1.0.2 youch-core: 0.3.2 - zip-stream@4.1.1: - dependencies: - archiver-utils: 3.0.4 - compress-commons: 4.1.2 - readable-stream: 3.6.2 - zip-stream@6.0.1: dependencies: archiver-utils: 5.0.2 compress-commons: 6.0.2 readable-stream: 4.7.0 - zod@3.24.4: {} + zod@3.25.28: {} zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c517cb080..2d4ba3b4a 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,10 +1,13 @@ packages: - - "docs" - - "packages/*" - - "recipes/*" + - 'docs' + - 'packages/*' + - '!packages/__legacy__' + - 'recipes/*' + - '!recipes/__legacy__/*' + - '!recipes/vue-vite' + - '!recipes/nuxt-vite' catalog: - "@wso2/eslint-plugin": "https://gitpkg.now.sh/brionmario/wso2-ui-configs/packages/eslint-plugin?4ee6f6be232d7631999d709a86b91612f1d34ce7" - "@wso2/prettier-config": "https://gitpkg.now.sh/brionmario/wso2-ui-configs/packages/prettier-config?4ee6f6be232d7631999d709a86b91612f1d34ce7" - "@wso2/stylelint-config": "https://gitpkg.now.sh/brionmario/wso2-ui-configs/packages/stylelint-config?4ee6f6be232d7631999d709a86b91612f1d34ce7" - "eslint": "~8.57.0" \ No newline at end of file + '@wso2/eslint-plugin': 'https://gitpkg.now.sh/brionmario/wso2-ui-configs/packages/eslint-plugin?a1fc6eb570653c999828aea9f5027cba06af4391' + '@wso2/prettier-config': 'https://gitpkg.now.sh/brionmario/wso2-ui-configs/packages/prettier-config?a1fc6eb570653c999828aea9f5027cba06af4391' + '@wso2/stylelint-config': 'https://gitpkg.now.sh/brionmario/wso2-ui-configs/packages/stylelint-config?a1fc6eb570653c999828aea9f5027cba06af4391' diff --git a/prettier.config.cjs b/prettier.config.cjs index c07f730d2..929b9b15f 100644 --- a/prettier.config.cjs +++ b/prettier.config.cjs @@ -1,5 +1,5 @@ /** - * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/recipes/react-vite/.eslintrc.cjs b/recipes/__legacy__/react-vite/.eslintrc.cjs similarity index 100% rename from recipes/react-vite/.eslintrc.cjs rename to recipes/__legacy__/react-vite/.eslintrc.cjs diff --git a/recipes/react-vite/.gitignore b/recipes/__legacy__/react-vite/.gitignore similarity index 100% rename from recipes/react-vite/.gitignore rename to recipes/__legacy__/react-vite/.gitignore diff --git a/recipes/react-vite/CHANGELOG.md b/recipes/__legacy__/react-vite/CHANGELOG.md similarity index 100% rename from recipes/react-vite/CHANGELOG.md rename to recipes/__legacy__/react-vite/CHANGELOG.md diff --git a/recipes/react-vite/README.md b/recipes/__legacy__/react-vite/README.md similarity index 100% rename from recipes/react-vite/README.md rename to recipes/__legacy__/react-vite/README.md diff --git a/recipes/react-vite/index.html b/recipes/__legacy__/react-vite/index.html similarity index 100% rename from recipes/react-vite/index.html rename to recipes/__legacy__/react-vite/index.html diff --git a/recipes/react-vite/package.json b/recipes/__legacy__/react-vite/package.json similarity index 97% rename from recipes/react-vite/package.json rename to recipes/__legacy__/react-vite/package.json index e303d3558..c0c17c9c5 100644 --- a/recipes/react-vite/package.json +++ b/recipes/__legacy__/react-vite/package.json @@ -23,7 +23,7 @@ "@typescript-eslint/eslint-plugin": "^7.2.0", "@typescript-eslint/parser": "^7.2.0", "@vitejs/plugin-react": "^4.2.1", - "eslint": "catalog:", + "eslint": "8.57.0", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.6", "typescript": "5.1.6", diff --git a/recipes/react-vite/public/vite.svg b/recipes/__legacy__/react-vite/public/vite.svg similarity index 100% rename from recipes/react-vite/public/vite.svg rename to recipes/__legacy__/react-vite/public/vite.svg diff --git a/recipes/react-vite/src/App.css b/recipes/__legacy__/react-vite/src/App.css similarity index 100% rename from recipes/react-vite/src/App.css rename to recipes/__legacy__/react-vite/src/App.css diff --git a/recipes/react-vite/src/App.tsx b/recipes/__legacy__/react-vite/src/App.tsx similarity index 100% rename from recipes/react-vite/src/App.tsx rename to recipes/__legacy__/react-vite/src/App.tsx diff --git a/recipes/react-vite/src/main.tsx b/recipes/__legacy__/react-vite/src/main.tsx similarity index 100% rename from recipes/react-vite/src/main.tsx rename to recipes/__legacy__/react-vite/src/main.tsx diff --git a/recipes/react-vite/src/vite-env.d.ts b/recipes/__legacy__/react-vite/src/vite-env.d.ts similarity index 100% rename from recipes/react-vite/src/vite-env.d.ts rename to recipes/__legacy__/react-vite/src/vite-env.d.ts diff --git a/recipes/react-vite/tsconfig.json b/recipes/__legacy__/react-vite/tsconfig.json similarity index 100% rename from recipes/react-vite/tsconfig.json rename to recipes/__legacy__/react-vite/tsconfig.json diff --git a/recipes/react-vite/tsconfig.node.json b/recipes/__legacy__/react-vite/tsconfig.node.json similarity index 100% rename from recipes/react-vite/tsconfig.node.json rename to recipes/__legacy__/react-vite/tsconfig.node.json diff --git a/recipes/react-vite/vite.config.ts b/recipes/__legacy__/react-vite/vite.config.ts similarity index 100% rename from recipes/react-vite/vite.config.ts rename to recipes/__legacy__/react-vite/vite.config.ts diff --git a/recipes/create-next-app-ts-app-router/.gitignore b/recipes/create-next-app-ts-app-router/.gitignore new file mode 100644 index 000000000..af1db0d2d --- /dev/null +++ b/recipes/create-next-app-ts-app-router/.gitignore @@ -0,0 +1,43 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* +# allow .env.local.example to be committed with sample values. +!.env.local.example + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/recipes/create-next-app-ts-app-router/README.md b/recipes/create-next-app-ts-app-router/README.md new file mode 100644 index 000000000..e215bc4cc --- /dev/null +++ b/recipes/create-next-app-ts-app-router/README.md @@ -0,0 +1,36 @@ +This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. diff --git a/recipes/create-next-app-ts-app-router/app/favicon.ico b/recipes/create-next-app-ts-app-router/app/favicon.ico new file mode 100644 index 000000000..718d6fea4 Binary files /dev/null and b/recipes/create-next-app-ts-app-router/app/favicon.ico differ diff --git a/recipes/create-next-app-ts-app-router/app/globals.css b/recipes/create-next-app-ts-app-router/app/globals.css new file mode 100644 index 000000000..e3734be15 --- /dev/null +++ b/recipes/create-next-app-ts-app-router/app/globals.css @@ -0,0 +1,42 @@ +:root { + --background: #ffffff; + --foreground: #171717; +} + +@media (prefers-color-scheme: dark) { + :root { + --background: #0a0a0a; + --foreground: #ededed; + } +} + +html, +body { + max-width: 100vw; + overflow-x: hidden; +} + +body { + color: var(--foreground); + background: var(--background); + font-family: Arial, Helvetica, sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +* { + box-sizing: border-box; + padding: 0; + margin: 0; +} + +a { + color: inherit; + text-decoration: none; +} + +@media (prefers-color-scheme: dark) { + html { + color-scheme: dark; + } +} diff --git a/recipes/create-next-app-ts-app-router/app/layout.tsx b/recipes/create-next-app-ts-app-router/app/layout.tsx new file mode 100644 index 000000000..42fc323e4 --- /dev/null +++ b/recipes/create-next-app-ts-app-router/app/layout.tsx @@ -0,0 +1,32 @@ +import type { Metadata } from "next"; +import { Geist, Geist_Mono } from "next/font/google"; +import "./globals.css"; + +const geistSans = Geist({ + variable: "--font-geist-sans", + subsets: ["latin"], +}); + +const geistMono = Geist_Mono({ + variable: "--font-geist-mono", + subsets: ["latin"], +}); + +export const metadata: Metadata = { + title: "Create Next App", + description: "Generated by create next app", +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + {children} + + + ); +} diff --git a/recipes/create-next-app-ts-app-router/app/page.module.css b/recipes/create-next-app-ts-app-router/app/page.module.css new file mode 100644 index 000000000..8634d2c28 --- /dev/null +++ b/recipes/create-next-app-ts-app-router/app/page.module.css @@ -0,0 +1,169 @@ +.page { + --gray-rgb: 0, 0, 0; + --gray-alpha-200: rgba(var(--gray-rgb), 0.08); + --gray-alpha-100: rgba(var(--gray-rgb), 0.05); + + --button-primary-hover: #383838; + --button-secondary-hover: #f2f2f2; + + display: grid; + grid-template-rows: 20px 1fr 20px; + align-items: center; + justify-items: center; + min-height: 100svh; + padding: 80px; + gap: 64px; + font-family: var(--font-geist-sans); +} + +@media (prefers-color-scheme: dark) { + .page { + --gray-rgb: 255, 255, 255; + --gray-alpha-200: rgba(var(--gray-rgb), 0.145); + --gray-alpha-100: rgba(var(--gray-rgb), 0.06); + + --button-primary-hover: #ccc; + --button-secondary-hover: #1a1a1a; + } +} + +.main { + display: flex; + flex-direction: column; + gap: 32px; + grid-row-start: 2; +} + +.main ol { + font-family: var(--font-geist-mono); + padding-left: 0; + margin: 0; + font-size: 14px; + line-height: 24px; + letter-spacing: -0.01em; + list-style-position: inside; +} + +.main li:not(:last-of-type) { + margin-bottom: 8px; +} + +.main code { + font-family: inherit; + background: var(--gray-alpha-100); + padding: 2px 4px; + border-radius: 4px; + font-weight: 600; +} + +.ctas { + display: flex; + gap: 16px; +} + +.ctas a, +.ctas button { + appearance: none; + border-radius: 128px; + height: 48px; + padding: 0 20px; + border: none; + border: 1px solid transparent; + transition: + background 0.2s, + color 0.2s, + border-color 0.2s; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + font-size: 16px; + line-height: 20px; + font-weight: 500; +} + +.primary { + background: var(--foreground); + color: var(--background); + gap: 8px; +} + +.secondary { + border-color: var(--gray-alpha-200); + min-width: 158px; +} + +.footer { + grid-row-start: 3; + display: flex; + gap: 24px; +} + +.footer a { + display: flex; + align-items: center; + gap: 8px; +} + +.footer img { + flex-shrink: 0; +} + +/* Enable hover only on non-touch devices */ +@media (hover: hover) and (pointer: fine) { + .primary:hover { + background: var(--button-primary-hover); + border-color: transparent; + } + + .secondary:hover { + background: var(--button-secondary-hover); + border-color: transparent; + } + + .footer a:hover { + text-decoration: underline; + text-underline-offset: 4px; + } +} + +@media (max-width: 600px) { + .page { + padding: 32px; + padding-bottom: 80px; + } + + .main { + align-items: center; + } + + .main ol { + text-align: center; + } + + .ctas { + flex-direction: column; + } + + .ctas a { + font-size: 14px; + height: 40px; + padding: 0 16px; + } + + .secondary { + min-width: auto; + } + + .footer { + flex-wrap: wrap; + align-items: center; + justify-content: center; + } +} + +@media (prefers-color-scheme: dark) { + .logo { + filter: invert(); + } +} \ No newline at end of file diff --git a/recipes/create-next-app-ts-app-router/app/page.tsx b/recipes/create-next-app-ts-app-router/app/page.tsx new file mode 100644 index 000000000..419cc8ef7 --- /dev/null +++ b/recipes/create-next-app-ts-app-router/app/page.tsx @@ -0,0 +1,19 @@ +import styles from './page.module.css'; +import {SignInButton, SignedIn, SignOutButton, SignedOut} from '@asgardeo/nextjs'; + +export default function Home() { + return ( +
+
+
+ + Sign In + + + Sign Out + +
+
+
+ ); +} diff --git a/recipes/create-next-app-ts-app-router/env.local.example b/recipes/create-next-app-ts-app-router/env.local.example new file mode 100644 index 000000000..8b5f755d9 --- /dev/null +++ b/recipes/create-next-app-ts-app-router/env.local.example @@ -0,0 +1,6 @@ +# This file is an example of the .env.local file. +# DO NOT modify the sample values. + +NEXT_PUBLIC_ASGARDEO_BASE_URL='https://api.asgardeo.io/t/' +NEXT_PUBLIC_ASGARDEO_CLIENT_ID='' +ASGARDEO_CLIENT_SECRET='' diff --git a/recipes/create-next-app-ts-app-router/eslint.config.mjs b/recipes/create-next-app-ts-app-router/eslint.config.mjs new file mode 100644 index 000000000..c85fb67c4 --- /dev/null +++ b/recipes/create-next-app-ts-app-router/eslint.config.mjs @@ -0,0 +1,16 @@ +import { dirname } from "path"; +import { fileURLToPath } from "url"; +import { FlatCompat } from "@eslint/eslintrc"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const compat = new FlatCompat({ + baseDirectory: __dirname, +}); + +const eslintConfig = [ + ...compat.extends("next/core-web-vitals", "next/typescript"), +]; + +export default eslintConfig; diff --git a/recipes/create-next-app-ts-app-router/middleware.ts b/recipes/create-next-app-ts-app-router/middleware.ts new file mode 100644 index 000000000..ade3bfbc8 --- /dev/null +++ b/recipes/create-next-app-ts-app-router/middleware.ts @@ -0,0 +1,24 @@ +import {AsgardeoNext} from '@asgardeo/nextjs'; +import {NextRequest} from 'next/server'; + +const asgardeo = new AsgardeoNext(); + +asgardeo.initialize({ + baseUrl: process.env.NEXT_PUBLIC_ASGARDEO_BASE_URL, + clientId: process.env.NEXT_PUBLIC_ASGARDEO_CLIENT_ID, + clientSecret: process.env.NEXT_PUBLIC_ASGARDEO_CLIENT_SECRET, + afterSignInUrl: 'http://localhost:3000', +}); + +export async function middleware(request: NextRequest) { + return await asgardeo.middleware(request); +} + +export const config = { + matcher: [ + // Skip Next.js internals and all static files, unless found in search params + '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', + // Always run for API routes + '/(api|trpc)(.*)', + ], +}; diff --git a/recipes/create-next-app-ts-app-router/next.config.ts b/recipes/create-next-app-ts-app-router/next.config.ts new file mode 100644 index 000000000..e9ffa3083 --- /dev/null +++ b/recipes/create-next-app-ts-app-router/next.config.ts @@ -0,0 +1,7 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + /* config options here */ +}; + +export default nextConfig; diff --git a/recipes/create-next-app-ts-app-router/package.json b/recipes/create-next-app-ts-app-router/package.json new file mode 100644 index 000000000..e53529ded --- /dev/null +++ b/recipes/create-next-app-ts-app-router/package.json @@ -0,0 +1,26 @@ +{ + "private": true, + "name": "@asgardeo/create-next-app-ts-app-router", + "version": "0.0.0", + "scripts": { + "dev": "next dev --turbopack", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@asgardeo/nextjs": "workspace:^", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "next": "15.3.2" + }, + "devDependencies": { + "typescript": "^5", + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "eslint": "^9", + "eslint-config-next": "15.3.2", + "@eslint/eslintrc": "^3" + } +} \ No newline at end of file diff --git a/recipes/create-next-app-ts-app-router/public/file.svg b/recipes/create-next-app-ts-app-router/public/file.svg new file mode 100644 index 000000000..004145cdd --- /dev/null +++ b/recipes/create-next-app-ts-app-router/public/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/recipes/create-next-app-ts-app-router/public/globe.svg b/recipes/create-next-app-ts-app-router/public/globe.svg new file mode 100644 index 000000000..567f17b0d --- /dev/null +++ b/recipes/create-next-app-ts-app-router/public/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/recipes/create-next-app-ts-app-router/public/next.svg b/recipes/create-next-app-ts-app-router/public/next.svg new file mode 100644 index 000000000..5174b28c5 --- /dev/null +++ b/recipes/create-next-app-ts-app-router/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/recipes/create-next-app-ts-app-router/public/vercel.svg b/recipes/create-next-app-ts-app-router/public/vercel.svg new file mode 100644 index 000000000..770539603 --- /dev/null +++ b/recipes/create-next-app-ts-app-router/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/recipes/create-next-app-ts-app-router/public/window.svg b/recipes/create-next-app-ts-app-router/public/window.svg new file mode 100644 index 000000000..b2b2a44f6 --- /dev/null +++ b/recipes/create-next-app-ts-app-router/public/window.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/recipes/create-next-app-ts-app-router/tsconfig.json b/recipes/create-next-app-ts-app-router/tsconfig.json new file mode 100644 index 000000000..d8b93235f --- /dev/null +++ b/recipes/create-next-app-ts-app-router/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "ES2017", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/recipes/nuxt-vite/package.json b/recipes/nuxt-vite/package.json index 385d34355..1e7b389c7 100644 --- a/recipes/nuxt-vite/package.json +++ b/recipes/nuxt-vite/package.json @@ -1,7 +1,7 @@ { - "name": "nuxt-vite", "private": true, - "version": "0.0.1", + "name": "@asgardeo/nuxt-vite", + "version": "0.0.0", "type": "module", "scripts": { "build": "nuxt build", @@ -10,9 +10,9 @@ "preview": "nuxt preview" }, "dependencies": { + "@asgardeo/nuxt": "workspace:^", "nuxt": "^3.17.3", "vue": "^3.5.13", - "vue-router": "^4.5.1", - "@asgardeo/nuxt": "workspace:*" + "vue-router": "^4.5.1" } } diff --git a/recipes/vite-react-ts/.env.local.example b/recipes/vite-react-ts/.env.local.example new file mode 100644 index 000000000..020179b5e --- /dev/null +++ b/recipes/vite-react-ts/.env.local.example @@ -0,0 +1,5 @@ +# This file is an example of the .env.local file. +# DO NOT modify the sample values. + +VITE_ASGARDEO_BASE_URL='https://api.asgardeo.io/t/' +VITE_ASGARDEO_CLIENT_ID='' diff --git a/recipes/vite-react-ts/.gitignore b/recipes/vite-react-ts/.gitignore new file mode 100644 index 000000000..127fdb7a2 --- /dev/null +++ b/recipes/vite-react-ts/.gitignore @@ -0,0 +1,26 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local +# allow .env.local.example to be committed with sample values. +!.env.local.example + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/recipes/vite-react-ts/README.md b/recipes/vite-react-ts/README.md new file mode 100644 index 000000000..da9844432 --- /dev/null +++ b/recipes/vite-react-ts/README.md @@ -0,0 +1,54 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: + +```js +export default tseslint.config({ + extends: [ + // Remove ...tseslint.configs.recommended and replace with this + ...tseslint.configs.recommendedTypeChecked, + // Alternatively, use this for stricter rules + ...tseslint.configs.strictTypeChecked, + // Optionally, add this for stylistic rules + ...tseslint.configs.stylisticTypeChecked, + ], + languageOptions: { + // other options... + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + }, +}) +``` + +You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: + +```js +// eslint.config.js +import reactX from 'eslint-plugin-react-x' +import reactDom from 'eslint-plugin-react-dom' + +export default tseslint.config({ + plugins: { + // Add the react-x and react-dom plugins + 'react-x': reactX, + 'react-dom': reactDom, + }, + rules: { + // other rules... + // Enable its recommended typescript rules + ...reactX.configs['recommended-typescript'].rules, + ...reactDom.configs.recommended.rules, + }, +}) +``` diff --git a/recipes/vite-react-ts/eslint.config.js b/recipes/vite-react-ts/eslint.config.js new file mode 100644 index 000000000..092408a9f --- /dev/null +++ b/recipes/vite-react-ts/eslint.config.js @@ -0,0 +1,28 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' + +export default tseslint.config( + { ignores: ['dist'] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ['**/*.{ts,tsx}'], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, + }, +) diff --git a/recipes/vite-react-ts/index.html b/recipes/vite-react-ts/index.html new file mode 100644 index 000000000..e4b78eae1 --- /dev/null +++ b/recipes/vite-react-ts/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + React + TS + + +
+ + + diff --git a/recipes/vite-react-ts/package.json b/recipes/vite-react-ts/package.json new file mode 100644 index 000000000..31d814cff --- /dev/null +++ b/recipes/vite-react-ts/package.json @@ -0,0 +1,30 @@ +{ + "private": true, + "name": "@asgardep/vite-react-ts", + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "@asgardeo/react": "workspace:^", + "react": "^19.1.0", + "react-dom": "^19.1.0" + }, + "devDependencies": { + "@eslint/js": "^9.25.0", + "@types/react": "^19.1.2", + "@types/react-dom": "^19.1.2", + "@vitejs/plugin-react": "^4.4.1", + "eslint": "^9.25.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.19", + "globals": "^16.0.0", + "typescript": "~5.8.3", + "typescript-eslint": "^8.30.1", + "vite": "^6.3.5" + } +} diff --git a/recipes/vite-react-ts/public/vite.svg b/recipes/vite-react-ts/public/vite.svg new file mode 100644 index 000000000..e7b8dfb1b --- /dev/null +++ b/recipes/vite-react-ts/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/recipes/vite-react-ts/src/App.css b/recipes/vite-react-ts/src/App.css new file mode 100644 index 000000000..b9d355df2 --- /dev/null +++ b/recipes/vite-react-ts/src/App.css @@ -0,0 +1,42 @@ +#root { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; +} +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} +.logo.react:hover { + filter: drop-shadow(0 0 2em #61dafbaa); +} + +@keyframes logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: no-preference) { + a:nth-of-type(2) .logo { + animation: logo-spin infinite 20s linear; + } +} + +.card { + padding: 2em; +} + +.read-the-docs { + color: #888; +} diff --git a/recipes/vite-react-ts/src/App.tsx b/recipes/vite-react-ts/src/App.tsx new file mode 100644 index 000000000..ea14f7e37 --- /dev/null +++ b/recipes/vite-react-ts/src/App.tsx @@ -0,0 +1,43 @@ +import {UserDropdown, SignInButton, SignedOut, SignOutButton, SignedIn, User, UserProfile} from '@asgardeo/react'; +import './App.css'; + +function App() { + return ( + <> + + Sign In + + + + {user => ( +
+

+ Welcome, {user?.firstName} {user?.lastName}! +

+

Email: {user?.email}

+
+ )} +
+ null, + }, + { + label: 'Logout', + icon: null, + onClick: () => null, + }, + ]} + portalId="custom-dropdown" + /> + + Logout +
+ + ); +} + +export default App; diff --git a/recipes/vite-react-ts/src/assets/react.svg b/recipes/vite-react-ts/src/assets/react.svg new file mode 100644 index 000000000..6c87de9bb --- /dev/null +++ b/recipes/vite-react-ts/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/recipes/vite-react-ts/src/index.css b/recipes/vite-react-ts/src/index.css new file mode 100644 index 000000000..08a3ac9e1 --- /dev/null +++ b/recipes/vite-react-ts/src/index.css @@ -0,0 +1,68 @@ +:root { + font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/recipes/vite-react-ts/src/main.tsx b/recipes/vite-react-ts/src/main.tsx new file mode 100644 index 000000000..9a5a09d93 --- /dev/null +++ b/recipes/vite-react-ts/src/main.tsx @@ -0,0 +1,30 @@ +import {StrictMode} from 'react'; +import {createRoot} from 'react-dom/client'; +import './index.css'; +import App from './App.tsx'; +import {AsgardeoProvider} from '@asgardeo/react'; + +createRoot(document.getElementById('root')!).render( + + + + + , +); diff --git a/recipes/vite-react-ts/src/vite-env.d.ts b/recipes/vite-react-ts/src/vite-env.d.ts new file mode 100644 index 000000000..11f02fe2a --- /dev/null +++ b/recipes/vite-react-ts/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/recipes/vite-react-ts/tsconfig.app.json b/recipes/vite-react-ts/tsconfig.app.json new file mode 100644 index 000000000..c9ccbd4c5 --- /dev/null +++ b/recipes/vite-react-ts/tsconfig.app.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["src"] +} diff --git a/recipes/vite-react-ts/tsconfig.json b/recipes/vite-react-ts/tsconfig.json new file mode 100644 index 000000000..a1e6861d3 --- /dev/null +++ b/recipes/vite-react-ts/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/recipes/vite-react-ts/tsconfig.node.json b/recipes/vite-react-ts/tsconfig.node.json new file mode 100644 index 000000000..9728af2d8 --- /dev/null +++ b/recipes/vite-react-ts/tsconfig.node.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/recipes/vite-react-ts/vite.config.ts b/recipes/vite-react-ts/vite.config.ts new file mode 100644 index 000000000..8b0f57b91 --- /dev/null +++ b/recipes/vite-react-ts/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], +}) diff --git a/recipes/vue-vite/package.json b/recipes/vue-vite/package.json index 07a43a9d3..7856cb723 100644 --- a/recipes/vue-vite/package.json +++ b/recipes/vue-vite/package.json @@ -1,7 +1,7 @@ { - "name": "vue-vite", - "version": "0.0.1", "private": true, + "name": "@asgardeo/vue-vite", + "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", @@ -34,7 +34,7 @@ "@vue/eslint-config-typescript": "^14.4.0", "@vue/test-utils": "^2.4.6", "@vue/tsconfig": "^0.7.0", - "eslint": "catalog:", + "eslint": "8.57.0", "eslint-plugin-vue": "^9.33.0", "jiti": "^2.4.2", "jsdom": "^26.0.0", diff --git a/recipes/vue-vite/tsconfig.node.json b/recipes/vue-vite/tsconfig.node.json index c4575a8e1..117febe3d 100644 --- a/recipes/vue-vite/tsconfig.node.json +++ b/recipes/vue-vite/tsconfig.node.json @@ -10,7 +10,6 @@ ], "compilerOptions": { "noEmit": true, - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", "module": "ESNext", "moduleResolution": "Bundler", "types": ["node"] diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..dc121f199 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "root": true, + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@asgardeo/react": ["packages/react/src/index.ts"], + } + } +}