diff --git a/lib/grant-types/authorization-code-grant-type.js b/lib/grant-types/authorization-code-grant-type.js index 227a6867..fd2f5883 100644 --- a/lib/grant-types/authorization-code-grant-type.js +++ b/lib/grant-types/authorization-code-grant-type.js @@ -11,6 +11,9 @@ const InvalidRequestError = require('../errors/invalid-request-error'); const ServerError = require('../errors/server-error'); const isFormat = require('@node-oauth/formats'); const pkce = require('../pkce/pkce'); +const { isDefined, toString, isInTypes } = require('../utils/param-util'); +const isStringOrNumber = isInTypes('string', 'number'); +const isString = isInTypes('string'); /** * @class @@ -73,14 +76,22 @@ class AuthorizationCodeGrantType extends AbstractGrantType { */ async getAuthorizationCode(request, client) { - if (!request.body.code) { + if (!isDefined(request.body.code)) { throw new InvalidRequestError('Missing parameter: `code`'); } - if (!isFormat.vschar(request.body.code)) { + if (!isStringOrNumber(request.body.code)) { throw new InvalidRequestError('Invalid parameter: `code`'); } + // normalize string|number to string + const requestCode = toString(request.body.code); + + if (!isFormat.vschar(requestCode)) { + throw new InvalidRequestError('Invalid parameter: `code`'); + } + + // XXX: still passing the original value from request to model const code = await this.model.getAuthorizationCode(request.body.code); if (!code) { @@ -163,7 +174,7 @@ class AuthorizationCodeGrantType extends AbstractGrantType { const redirectUri = request.body.redirect_uri || request.query.redirect_uri; - if (!isFormat.uri(redirectUri)) { + if (!redirectUri || !isString(redirectUri) || !isFormat.uri(redirectUri)) { throw new InvalidRequestError('Invalid request: `redirect_uri` is not a valid URI'); } diff --git a/lib/grant-types/password-grant-type.js b/lib/grant-types/password-grant-type.js index bcb32c3a..8894519d 100644 --- a/lib/grant-types/password-grant-type.js +++ b/lib/grant-types/password-grant-type.js @@ -9,6 +9,8 @@ const InvalidArgumentError = require('../errors/invalid-argument-error'); const InvalidGrantError = require('../errors/invalid-grant-error'); const InvalidRequestError = require('../errors/invalid-request-error'); const isFormat = require('@node-oauth/formats'); +const { isDefined, isInTypes } = require('../utils/param-util'); +const isString = isInTypes('string'); /** * Constructor. @@ -58,19 +60,19 @@ class PasswordGrantType extends AbstractGrantType { */ async getUser(request, client) { - if (!request.body.username) { + if (!isDefined(request.body.username)) { throw new InvalidRequestError('Missing parameter: `username`'); } - if (!request.body.password) { + if (!isDefined(request.body.password)) { throw new InvalidRequestError('Missing parameter: `password`'); } - if (!isFormat.uchar(request.body.username)) { + if (!isString(request.body.username) || !isFormat.uchar(request.body.username)) { throw new InvalidRequestError('Invalid parameter: `username`'); } - if (!isFormat.uchar(request.body.password)) { + if (!isString(request.body.password) || !isFormat.uchar(request.body.password)) { throw new InvalidRequestError('Invalid parameter: `password`'); } diff --git a/lib/grant-types/refresh-token-grant-type.js b/lib/grant-types/refresh-token-grant-type.js index 1f62f7ec..b2355173 100644 --- a/lib/grant-types/refresh-token-grant-type.js +++ b/lib/grant-types/refresh-token-grant-type.js @@ -11,6 +11,8 @@ const InvalidRequestError = require('../errors/invalid-request-error'); const ServerError = require('../errors/server-error'); const isFormat = require('@node-oauth/formats'); const InvalidScopeError = require('../errors/invalid-scope-error'); +const { isInTypes, toString, isDefined } = require('../utils/param-util'); +const isStringOrNumber = isInTypes('string', 'number'); /** * Constructor. @@ -64,13 +66,18 @@ class RefreshTokenGrantType extends AbstractGrantType { /** * Get refresh token. */ - async getRefreshToken(request, client) { - if (!request.body.refresh_token) { + if (!isDefined(request.body.refresh_token)) { throw new InvalidRequestError('Missing parameter: `refresh_token`'); } - if (!isFormat.vschar(request.body.refresh_token)) { + if (!isStringOrNumber(request.body.refresh_token)) { + throw new InvalidRequestError('Invalid parameter: `refresh_token`'); + } + + const refreshToken = toString(request.body.refresh_token); + + if (!isFormat.vschar(refreshToken)) { throw new InvalidRequestError('Invalid parameter: `refresh_token`'); } diff --git a/lib/handlers/authorize-handler.js b/lib/handlers/authorize-handler.js index 17bb3341..6d2a97bf 100644 --- a/lib/handlers/authorize-handler.js +++ b/lib/handlers/authorize-handler.js @@ -21,6 +21,9 @@ const tokenUtil = require('../utils/token-util'); const url = require('url'); const pkce = require('../pkce/pkce'); const { parseScope } = require('../utils/scope-util'); +const { isDefined, isInTypes } = require('../utils/param-util'); +const isString = isInTypes('string'); +const isStringOrNumber = isInTypes('string', 'number'); /** * Response types. @@ -160,17 +163,18 @@ class AuthorizeHandler { const self = this; const clientId = request.body.client_id || request.query.client_id; - if (!clientId) { + if (!isDefined(clientId)) { throw new InvalidRequestError('Missing parameter: `client_id`'); } - if (!isFormat.vschar(clientId)) { + if (!isStringOrNumber(clientId) || !isFormat.vschar(clientId)) { throw new InvalidRequestError('Invalid parameter: `client_id`'); } const redirectUri = request.body.redirect_uri || request.query.redirect_uri; - if (redirectUri && !isFormat.uri(redirectUri)) { + // XXX: why is there no 'Missing parameter: `redirect_uri`' error? + if (isDefined(redirectUri) && (!isString(redirectUri) || !isFormat.uri(redirectUri))) { throw new InvalidRequestError('Invalid request: `redirect_uri` is not a valid URI'); } @@ -236,7 +240,7 @@ class AuthorizeHandler { getState (request) { const state = request.body.state || request.query.state; - const stateExists = state && state.length > 0; + const stateExists = isString(state) && state.length > 0; const stateIsValid = stateExists ? isFormat.vschar(state) : this.allowEmptyState; diff --git a/lib/handlers/token-handler.js b/lib/handlers/token-handler.js index 5bcd321c..a2204c36 100644 --- a/lib/handlers/token-handler.js +++ b/lib/handlers/token-handler.js @@ -18,6 +18,8 @@ const UnsupportedGrantTypeError = require('../errors/unsupported-grant-type-erro const auth = require('basic-auth'); const pkce = require('../pkce/pkce'); const isFormat = require('@node-oauth/formats'); +const { isInTypes, toString } = require('../utils/param-util'); +const isStringOrNumber = isInTypes('string', 'number'); /** * Grant types. @@ -123,7 +125,7 @@ class TokenHandler { throw new InvalidRequestError('Missing parameter: `client_secret`'); } - if (!isFormat.vschar(credentials.clientId)) { + if (!isStringOrNumber(credentials.clientId) || !isFormat.vschar(toString(credentials.clientId))) { throw new InvalidRequestError('Invalid parameter: `client_id`'); } diff --git a/lib/utils/param-util.js b/lib/utils/param-util.js new file mode 100644 index 00000000..37e04eb0 --- /dev/null +++ b/lib/utils/param-util.js @@ -0,0 +1,54 @@ +'use strict'; + +/** + * @module ParamUtil + */ + +/** + * Create a function to check, whether a value is one of the given types. + * @param types {...string[]} + * @return {function(*): boolean} + */ +function isInTypes (...types) { + return function (value) { + return types.includes(typeof value); + }; +} + +/** + * Check if a value is defined (not missing) + * @param value + * @return {boolean} + */ +function isDefined (value) { + // TODO: in future versions, consider changing this to `value !== undefined && value !== null && value !== ''`, + // which might be a breaking changes for some users + return !!value; +} + +/** + * Safely converts a value to a string in the following order: + * - If the value is already a string, return it. + * - If the value has a `toString` method, call it and return the result. + * - If the value is `null` or `undefined`, return an empty string. + * - Otherwise, use the global `String` function to convert the value. + * @param value {*} + * @return {string} + */ +function toString(value) { + if (typeof value === 'string') { + return value; + } + + if (Object.prototype.hasOwnProperty.call(value, 'toString')) { + return value.toString(); + } + + if (value === null || value === undefined) { + return ''; + } + + return String(value); +} + +module.exports = { isInTypes, isDefined, toString }; diff --git a/lib/utils/scope-util.js b/lib/utils/scope-util.js index 5ed4bbd3..982f6b27 100644 --- a/lib/utils/scope-util.js +++ b/lib/utils/scope-util.js @@ -1,6 +1,8 @@ const isFormat = require('@node-oauth/formats'); const InvalidScopeError = require('../errors/invalid-scope-error'); +const { isInTypes } = require('../utils/param-util'); const whiteSpace = /\s+/g; +const isString = isInTypes('string'); /** * @module ScopeUtil @@ -22,7 +24,7 @@ function parseScope (requestedScope) { return undefined; } - if (typeof requestedScope !== 'string') { + if (!isString(requestedScope)) { throw new InvalidScopeError('Invalid parameter: `scope`'); } diff --git a/package-lock.json b/package-lock.json index ac2ad4ed..e0a4b5af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "5.2.0", "license": "MIT", "dependencies": { - "@node-oauth/formats": "1.0.0", + "@node-oauth/formats": "^1.1.0", "basic-auth": "2.0.1", "type-is": "2.0.1" }, @@ -17,7 +17,7 @@ "chai": "6.2.2", "eslint": "8.57.1", "jsdoc-to-markdown": "^9.1.3", - "mocha": "11.7.5", + "mocha": "^11.7.5", "nyc": "17.1.0", "sinon": "21.0.1", "vitepress": "^2.0.0-alpha.15" @@ -26,324 +26,6 @@ "node": ">=16.0.0" } }, - "node_modules/@ai-sdk/gateway": { - "version": "2.0.23", - "resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-2.0.23.tgz", - "integrity": "sha512-qmX7afPRszUqG5hryHF3UN8ITPIRSGmDW6VYCmByzjoUkgm3MekzSx2hMV1wr0P+llDeuXb378SjqUfpvWJulg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@ai-sdk/provider": "2.0.0", - "@ai-sdk/provider-utils": "3.0.19", - "@vercel/oidc": "3.0.5" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "zod": "^3.25.76 || ^4.1.8" - } - }, - "node_modules/@ai-sdk/provider": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-2.0.0.tgz", - "integrity": "sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "json-schema": "^0.4.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@ai-sdk/provider-utils": { - "version": "3.0.19", - "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.19.tgz", - "integrity": "sha512-W41Wc9/jbUVXVwCN/7bWa4IKe8MtxO3EyA0Hfhx6grnmiYlCvpI8neSYWFE0zScXJkgA/YK3BRybzgyiXuu6JA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@ai-sdk/provider": "2.0.0", - "@standard-schema/spec": "^1.0.0", - "eventsource-parser": "^3.0.6" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "zod": "^3.25.76 || ^4.1.8" - } - }, - "node_modules/@ai-sdk/react": { - "version": "2.0.118", - "resolved": "https://registry.npmjs.org/@ai-sdk/react/-/react-2.0.118.tgz", - "integrity": "sha512-K/5VVEGTIu9SWrdQ0s/11OldFU8IjprDzeE6TaC2fOcQWhG7dGVGl9H8Z32QBHzdfJyMhFUxEyFKSOgA2j9+VQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@ai-sdk/provider-utils": "3.0.19", - "ai": "5.0.116", - "swr": "^2.2.5", - "throttleit": "2.1.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "react": "^18 || ~19.0.1 || ~19.1.2 || ^19.2.1", - "zod": "^3.25.76 || ^4.1.8" - }, - "peerDependenciesMeta": { - "zod": { - "optional": true - } - } - }, - "node_modules/@algolia/abtesting": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.12.2.tgz", - "integrity": "sha512-oWknd6wpfNrmRcH0vzed3UPX0i17o4kYLM5OMITyMVM2xLgaRbIafoxL0e8mcrNNb0iORCJA0evnNDKRYth5WQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/autocomplete-core": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.19.2.tgz", - "integrity": "sha512-mKv7RyuAzXvwmq+0XRK8HqZXt9iZ5Kkm2huLjgn5JoCPtDy+oh9yxUMfDDaVCw0oyzZ1isdJBc7l9nuCyyR7Nw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-plugin-algolia-insights": "1.19.2", - "@algolia/autocomplete-shared": "1.19.2" - } - }, - "node_modules/@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.19.2.tgz", - "integrity": "sha512-TjxbcC/r4vwmnZaPwrHtkXNeqvlpdyR+oR9Wi2XyfORkiGkLTVhX2j+O9SaCCINbKoDfc+c2PB8NjfOnz7+oKg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-shared": "1.19.2" - }, - "peerDependencies": { - "search-insights": ">= 1 < 3" - } - }, - "node_modules/@algolia/autocomplete-shared": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.19.2.tgz", - "integrity": "sha512-jEazxZTVD2nLrC+wYlVHQgpBoBB5KPStrJxLzsIFl6Kqd1AlG9sIAGl39V5tECLpIQzB3Qa2T6ZPJ1ChkwMK/w==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/client-abtesting": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.46.2.tgz", - "integrity": "sha512-oRSUHbylGIuxrlzdPA8FPJuwrLLRavOhAmFGgdAvMcX47XsyM+IOGa9tc7/K5SPvBqn4nhppOCEz7BrzOPWc4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-analytics": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.46.2.tgz", - "integrity": "sha512-EPBN2Oruw0maWOF4OgGPfioTvd+gmiNwx0HmD9IgmlS+l75DatcBkKOPNJN+0z3wBQWUO5oq602ATxIfmTQ8bA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-common": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.46.2.tgz", - "integrity": "sha512-Hj8gswSJNKZ0oyd0wWissqyasm+wTz1oIsv5ZmLarzOZAp3vFEda8bpDQ8PUhO+DfkbiLyVnAxsPe4cGzWtqkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-insights": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.46.2.tgz", - "integrity": "sha512-6dBZko2jt8FmQcHCbmNLB0kCV079Mx/DJcySTL3wirgDBUH7xhY1pOuUTLMiGkqM5D8moVZTvTdRKZUJRkrwBA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-personalization": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.46.2.tgz", - "integrity": "sha512-1waE2Uqh/PHNeDXGn/PM/WrmYOBiUGSVxAWqiJIj73jqPqvfzZgzdakHscIVaDl6Cp+j5dwjsZ5LCgaUr6DtmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-query-suggestions": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.46.2.tgz", - "integrity": "sha512-EgOzTZkyDcNL6DV0V/24+oBJ+hKo0wNgyrOX/mePBM9bc9huHxIY2352sXmoZ648JXXY2x//V1kropF/Spx83w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-search": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.46.2.tgz", - "integrity": "sha512-ZsOJqu4HOG5BlvIFnMU0YKjQ9ZI6r3C31dg2jk5kMWPSdhJpYL9xa5hEe7aieE+707dXeMI4ej3diy6mXdZpgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/ingestion": { - "version": "1.46.2", - "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.46.2.tgz", - "integrity": "sha512-1Uw2OslTWiOFDtt83y0bGiErJYy5MizadV0nHnOoHFWMoDqWW0kQoMFI65pXqRSkVvit5zjXSLik2xMiyQJDWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/monitoring": { - "version": "1.46.2", - "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.46.2.tgz", - "integrity": "sha512-xk9f+DPtNcddWN6E7n1hyNNsATBCHIqAvVGG2EAGHJc4AFYL18uM/kMTiOKXE/LKDPyy1JhIerrh9oYb7RBrgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/recommend": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.46.2.tgz", - "integrity": "sha512-NApbTPj9LxGzNw4dYnZmj2BoXiAc8NmbbH6qBNzQgXklGklt/xldTvu+FACN6ltFsTzoNU6j2mWNlHQTKGC5+Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-browser-xhr": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.46.2.tgz", - "integrity": "sha512-ekotpCwpSp033DIIrsTpYlGUCF6momkgupRV/FA3m62SreTSZUKjgK6VTNyG7TtYfq9YFm/pnh65bATP/ZWJEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-fetch": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.46.2.tgz", - "integrity": "sha512-gKE+ZFi/6y7saTr34wS0SqYFDcjHW4Wminv8PDZEi0/mE99+hSrbKgJWxo2ztb5eqGirQTgIh1AMVacGGWM1iw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-node-http": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.46.2.tgz", - "integrity": "sha512-ciPihkletp7ttweJ8Zt+GukSVLp2ANJHU+9ttiSxsJZThXc4Y2yJ8HGVWesW5jN1zrsZsezN71KrMx/iZsOYpg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -678,83 +360,19 @@ "node": ">=6.9.0" } }, - "node_modules/@docsearch/core": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@docsearch/core/-/core-4.4.0.tgz", - "integrity": "sha512-kiwNo5KEndOnrf5Kq/e5+D9NBMCFgNsDoRpKQJ9o/xnSlheh6b8AXppMuuUVVdAUIhIfQFk/07VLjjk/fYyKmw==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@types/react": ">= 16.8.0 < 20.0.0", - "react": ">= 16.8.0 < 20.0.0", - "react-dom": ">= 16.8.0 < 20.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, "node_modules/@docsearch/css": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-4.4.0.tgz", - "integrity": "sha512-e9vPgtih6fkawakmYo0Y6V4BKBmDV7Ykudn7ADWXUs5b6pmtBRwDbpSG/WiaUG63G28OkJDEnsMvgIAnZgGwYw==", + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-4.5.3.tgz", + "integrity": "sha512-kUpHaxn0AgI3LQfyzTYkNUuaFY4uEz/Ym9/N/FvyDE+PzSgZsCyDH9jE49B6N6f1eLCm9Yp64J9wENd6vypdxA==", "dev": true, "license": "MIT" }, "node_modules/@docsearch/js": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-4.4.0.tgz", - "integrity": "sha512-vCiKzjYD54bugUIMZA6YzuLDilkD3TNH/kfbvqsnzxiLTMu8F13psD+hdMSEOn7j+dFJOaf49fZ+gwr+rXctMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@docsearch/react": "4.4.0", - "htm": "3.1.1" - } - }, - "node_modules/@docsearch/react": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-4.4.0.tgz", - "integrity": "sha512-z12zeg1mV7WD4Ag4pKSuGukETJLaucVFwszDXL/qLaEgRqxEaVacO9SR1qqnCXvZztlvz2rt7cMqryi/7sKfjA==", + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-4.5.3.tgz", + "integrity": "sha512-rcBiUMCXbZLqrLIT6F6FDcrG/tyvM2WM0zum6NPbIiQNDQxbSgmNc+/bToS0rxBsXaxiU64esiWoS02WqrWLsg==", "dev": true, - "license": "MIT", - "dependencies": { - "@ai-sdk/react": "^2.0.30", - "@algolia/autocomplete-core": "1.19.2", - "@docsearch/core": "4.4.0", - "@docsearch/css": "4.4.0", - "ai": "^5.0.30", - "algoliasearch": "^5.28.0", - "marked": "^16.3.0", - "zod": "^4.1.8" - }, - "peerDependencies": { - "@types/react": ">= 16.8.0 < 20.0.0", - "react": ">= 16.8.0 < 20.0.0", - "react-dom": ">= 16.8.0 < 20.0.0", - "search-insights": ">= 1 < 3" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - }, - "search-insights": { - "optional": true - } - } + "license": "MIT" }, "node_modules/@esbuild/aix-ppc64": { "version": "0.27.2", @@ -1573,9 +1191,10 @@ } }, "node_modules/@node-oauth/formats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@node-oauth/formats/-/formats-1.0.0.tgz", - "integrity": "sha512-DwSbLtdC8zC5B5gTJkFzJj5s9vr9SGzOgQvV9nH7tUVuMSScg0EswAczhjIapOmH3Y8AyP7C4Jv7b8+QJObWZA==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@node-oauth/formats/-/formats-1.1.0.tgz", + "integrity": "sha512-Rgkxfg5k3wdI/BymwCK+wdudhyHl6hiqmY/uKuYqQmyKedg9RQCe+LaTHKtzrEthj33cr4bxYlA0onCkQ1AHng==", + "license": "MIT" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", @@ -1612,16 +1231,6 @@ "node": ">= 8" } }, - "node_modules/@opentelemetry/api": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", - "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -1640,9 +1249,9 @@ "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.54.0.tgz", - "integrity": "sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.56.0.tgz", + "integrity": "sha512-LNKIPA5k8PF1+jAFomGe3qN3bbIgJe/IlpDBwuVjrDKrJhVWywgnJvflMt/zkbVNLFtF1+94SljYQS6e99klnw==", "cpu": [ "arm" ], @@ -1654,9 +1263,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.54.0.tgz", - "integrity": "sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.56.0.tgz", + "integrity": "sha512-lfbVUbelYqXlYiU/HApNMJzT1E87UPGvzveGg2h0ktUNlOCxKlWuJ9jtfvs1sKHdwU4fzY7Pl8sAl49/XaEk6Q==", "cpu": [ "arm64" ], @@ -1668,9 +1277,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.54.0.tgz", - "integrity": "sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.56.0.tgz", + "integrity": "sha512-EgxD1ocWfhoD6xSOeEEwyE7tDvwTgZc8Bss7wCWe+uc7wO8G34HHCUH+Q6cHqJubxIAnQzAsyUsClt0yFLu06w==", "cpu": [ "arm64" ], @@ -1682,9 +1291,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.54.0.tgz", - "integrity": "sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.56.0.tgz", + "integrity": "sha512-1vXe1vcMOssb/hOF8iv52A7feWW2xnu+c8BV4t1F//m9QVLTfNVpEdja5ia762j/UEJe2Z1jAmEqZAK42tVW3g==", "cpu": [ "x64" ], @@ -1696,9 +1305,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.54.0.tgz", - "integrity": "sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.56.0.tgz", + "integrity": "sha512-bof7fbIlvqsyv/DtaXSck4VYQ9lPtoWNFCB/JY4snlFuJREXfZnm+Ej6yaCHfQvofJDXLDMTVxWscVSuQvVWUQ==", "cpu": [ "arm64" ], @@ -1710,9 +1319,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.54.0.tgz", - "integrity": "sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.56.0.tgz", + "integrity": "sha512-KNa6lYHloW+7lTEkYGa37fpvPq+NKG/EHKM8+G/g9WDU7ls4sMqbVRV78J6LdNuVaeeK5WB9/9VAFbKxcbXKYg==", "cpu": [ "x64" ], @@ -1724,9 +1333,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.54.0.tgz", - "integrity": "sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.56.0.tgz", + "integrity": "sha512-E8jKK87uOvLrrLN28jnAAAChNq5LeCd2mGgZF+fGF5D507WlG/Noct3lP/QzQ6MrqJ5BCKNwI9ipADB6jyiq2A==", "cpu": [ "arm" ], @@ -1738,9 +1347,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.54.0.tgz", - "integrity": "sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.56.0.tgz", + "integrity": "sha512-jQosa5FMYF5Z6prEpTCCmzCXz6eKr/tCBssSmQGEeozA9tkRUty/5Vx06ibaOP9RCrW1Pvb8yp3gvZhHwTDsJw==", "cpu": [ "arm" ], @@ -1752,9 +1361,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.54.0.tgz", - "integrity": "sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.56.0.tgz", + "integrity": "sha512-uQVoKkrC1KGEV6udrdVahASIsaF8h7iLG0U0W+Xn14ucFwi6uS539PsAr24IEF9/FoDtzMeeJXJIBo5RkbNWvQ==", "cpu": [ "arm64" ], @@ -1766,9 +1375,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.54.0.tgz", - "integrity": "sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.56.0.tgz", + "integrity": "sha512-vLZ1yJKLxhQLFKTs42RwTwa6zkGln+bnXc8ueFGMYmBTLfNu58sl5/eXyxRa2RarTkJbXl8TKPgfS6V5ijNqEA==", "cpu": [ "arm64" ], @@ -1780,9 +1389,23 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.54.0.tgz", - "integrity": "sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.56.0.tgz", + "integrity": "sha512-FWfHOCub564kSE3xJQLLIC/hbKqHSVxy8vY75/YHHzWvbJL7aYJkdgwD/xGfUlL5UV2SB7otapLrcCj2xnF1dg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.56.0.tgz", + "integrity": "sha512-z1EkujxIh7nbrKL1lmIpqFTc/sr0u8Uk0zK/qIEFldbt6EDKWFk/pxFq3gYj4Bjn3aa9eEhYRlL3H8ZbPT1xvA==", "cpu": [ "loong64" ], @@ -1794,9 +1417,23 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.54.0.tgz", - "integrity": "sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.56.0.tgz", + "integrity": "sha512-iNFTluqgdoQC7AIE8Q34R3AuPrJGJirj5wMUErxj22deOcY7XwZRaqYmB6ZKFHoVGqRcRd0mqO+845jAibKCkw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.56.0.tgz", + "integrity": "sha512-MtMeFVlD2LIKjp2sE2xM2slq3Zxf9zwVuw0jemsxvh1QOpHSsSzfNOTH9uYW9i1MXFxUSMmLpeVeUzoNOKBaWg==", "cpu": [ "ppc64" ], @@ -1808,9 +1445,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.54.0.tgz", - "integrity": "sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.56.0.tgz", + "integrity": "sha512-in+v6wiHdzzVhYKXIk5U74dEZHdKN9KH0Q4ANHOTvyXPG41bajYRsy7a8TPKbYPl34hU7PP7hMVHRvv/5aCSew==", "cpu": [ "riscv64" ], @@ -1822,9 +1459,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.54.0.tgz", - "integrity": "sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.56.0.tgz", + "integrity": "sha512-yni2raKHB8m9NQpI9fPVwN754mn6dHQSbDTwxdr9SE0ks38DTjLMMBjrwvB5+mXrX+C0npX0CVeCUcvvvD8CNQ==", "cpu": [ "riscv64" ], @@ -1836,9 +1473,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.54.0.tgz", - "integrity": "sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.56.0.tgz", + "integrity": "sha512-zhLLJx9nQPu7wezbxt2ut+CI4YlXi68ndEve16tPc/iwoylWS9B3FxpLS2PkmfYgDQtosah07Mj9E0khc3Y+vQ==", "cpu": [ "s390x" ], @@ -1850,9 +1487,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.54.0.tgz", - "integrity": "sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.56.0.tgz", + "integrity": "sha512-MVC6UDp16ZSH7x4rtuJPAEoE1RwS8N4oK9DLHy3FTEdFoUTCFVzMfJl/BVJ330C+hx8FfprA5Wqx4FhZXkj2Kw==", "cpu": [ "x64" ], @@ -1864,9 +1501,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.54.0.tgz", - "integrity": "sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.56.0.tgz", + "integrity": "sha512-ZhGH1eA4Qv0lxaV00azCIS1ChedK0V32952Md3FtnxSqZTBTd6tgil4nZT5cU8B+SIw3PFYkvyR4FKo2oyZIHA==", "cpu": [ "x64" ], @@ -1877,10 +1514,24 @@ "linux" ] }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.56.0.tgz", + "integrity": "sha512-O16XcmyDeFI9879pEcmtWvD/2nyxR9mF7Gs44lf1vGGx8Vg2DRNx11aVXBEqOQhWb92WN4z7fW/q4+2NYzCbBA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.54.0.tgz", - "integrity": "sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.56.0.tgz", + "integrity": "sha512-LhN/Reh+7F3RCgQIRbgw8ZMwUwyqJM+8pXNT6IIJAqm2IdKkzpCh/V9EdgOMBKuebIrzswqy4ATlrDgiOwbRcQ==", "cpu": [ "arm64" ], @@ -1892,9 +1543,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.54.0.tgz", - "integrity": "sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.56.0.tgz", + "integrity": "sha512-kbFsOObXp3LBULg1d3JIUQMa9Kv4UitDmpS+k0tinPBz3watcUiV2/LUDMMucA6pZO3WGE27P7DsfaN54l9ing==", "cpu": [ "arm64" ], @@ -1906,9 +1557,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.54.0.tgz", - "integrity": "sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.56.0.tgz", + "integrity": "sha512-vSSgny54D6P4vf2izbtFm/TcWYedw7f8eBrOiGGecyHyQB9q4Kqentjaj8hToe+995nob/Wv48pDqL5a62EWtg==", "cpu": [ "ia32" ], @@ -1920,9 +1571,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.54.0.tgz", - "integrity": "sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.56.0.tgz", + "integrity": "sha512-FeCnkPCTHQJFbiGG49KjV5YGW/8b9rrXAM2Mz2kiIoktq2qsJxRD5giEMEOD2lPdgs72upzefaUvS+nc8E3UzQ==", "cpu": [ "x64" ], @@ -1934,9 +1585,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.54.0.tgz", - "integrity": "sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.56.0.tgz", + "integrity": "sha512-H8AE9Ur/t0+1VXujj90w0HrSOuv0Nq9r1vSZF2t5km20NTfosQsGGUXDaKdQZzwuLts7IyL1fYT4hM95TI9c4g==", "cpu": [ "x64" ], @@ -1948,76 +1599,76 @@ ] }, "node_modules/@shikijs/core": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.20.0.tgz", - "integrity": "sha512-f2ED7HYV4JEk827mtMDwe/yQ25pRiXZmtHjWF8uzZKuKiEsJR7Ce1nuQ+HhV9FzDcbIo4ObBCD9GPTzNuy9S1g==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.21.0.tgz", + "integrity": "sha512-AXSQu/2n1UIQekY8euBJlvFYZIw0PHY63jUzGbrOma4wPxzznJXTXkri+QcHeBNaFxiiOljKxxJkVSoB3PjbyA==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/types": "3.20.0", + "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "node_modules/@shikijs/engine-javascript": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.20.0.tgz", - "integrity": "sha512-OFx8fHAZuk7I42Z9YAdZ95To6jDePQ9Rnfbw9uSRTSbBhYBp1kEOKv/3jOimcj3VRUKusDYM6DswLauwfhboLg==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.21.0.tgz", + "integrity": "sha512-ATwv86xlbmfD9n9gKRiwuPpWgPENAWCLwYCGz9ugTJlsO2kOzhOkvoyV/UD+tJ0uT7YRyD530x6ugNSffmvIiQ==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/types": "3.20.0", + "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "node_modules/@shikijs/engine-oniguruma": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.20.0.tgz", - "integrity": "sha512-Yx3gy7xLzM0ZOjqoxciHjA7dAt5tyzJE3L4uQoM83agahy+PlW244XJSrmJRSBvGYELDhYXPacD4R/cauV5bzQ==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.21.0.tgz", + "integrity": "sha512-OYknTCct6qiwpQDqDdf3iedRdzj6hFlOPv5hMvI+hkWfCKs5mlJ4TXziBG9nyabLwGulrUjHiCq3xCspSzErYQ==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/types": "3.20.0", + "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "node_modules/@shikijs/langs": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.20.0.tgz", - "integrity": "sha512-le+bssCxcSHrygCWuOrYJHvjus6zhQ2K7q/0mgjiffRbkhM4o1EWu2m+29l0yEsHDbWaWPNnDUTRVVBvBBeKaA==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.21.0.tgz", + "integrity": "sha512-g6mn5m+Y6GBJ4wxmBYqalK9Sp0CFkUqfNzUy2pJglUginz6ZpWbaWjDB4fbQ/8SHzFjYbtU6Ddlp1pc+PPNDVA==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/types": "3.20.0" + "@shikijs/types": "3.21.0" } }, "node_modules/@shikijs/themes": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.20.0.tgz", - "integrity": "sha512-U1NSU7Sl26Q7ErRvJUouArxfM2euWqq1xaSrbqMu2iqa+tSp0D1Yah8216sDYbdDHw4C8b75UpE65eWorm2erQ==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.21.0.tgz", + "integrity": "sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/types": "3.20.0" + "@shikijs/types": "3.21.0" } }, "node_modules/@shikijs/transformers": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-3.20.0.tgz", - "integrity": "sha512-PrHHMRr3Q5W1qB/42kJW6laqFyWdhrPF2hNR9qjOm1xcSiAO3hAHo7HaVyHE6pMyevmy3i51O8kuGGXC78uK3g==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-3.21.0.tgz", + "integrity": "sha512-CZwvCWWIiRRiFk9/JKzdEooakAP8mQDtBOQ1TKiCaS2E1bYtyBCOkUzS8akO34/7ufICQ29oeSfkb3tT5KtrhA==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/core": "3.20.0", - "@shikijs/types": "3.20.0" + "@shikijs/core": "3.21.0", + "@shikijs/types": "3.21.0" } }, "node_modules/@shikijs/types": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.20.0.tgz", - "integrity": "sha512-lhYAATn10nkZcBQ0BlzSbJA3wcmL5MXUUF8d2Zzon6saZDlToKaiRX60n2+ZaHJCmXEcZRWNzn+k9vplr8Jhsw==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.21.0.tgz", + "integrity": "sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA==", "dev": true, "license": "MIT", "dependencies": { @@ -2069,13 +1720,6 @@ "node": ">=4" } }, - "node_modules/@standard-schema/spec": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -2148,16 +1792,6 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, - "node_modules/@vercel/oidc": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.0.5.tgz", - "integrity": "sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">= 20" - } - }, "node_modules/@vitejs/plugin-vue": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.3.tgz", @@ -2176,42 +1810,42 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.26.tgz", - "integrity": "sha512-vXyI5GMfuoBCnv5ucIT7jhHKl55Y477yxP6fc4eUswjP8FG3FFVFd41eNDArR+Uk3QKn2Z85NavjaxLxOC19/w==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.27.tgz", + "integrity": "sha512-gnSBQjZA+//qDZen+6a2EdHqJ68Z7uybrMf3SPjEGgG4dicklwDVmMC1AeIHxtLVPT7sn6sH1KOO+tS6gwOUeQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.28.5", - "@vue/shared": "3.5.26", + "@vue/shared": "3.5.27", "entities": "^7.0.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-dom": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.26.tgz", - "integrity": "sha512-y1Tcd3eXs834QjswshSilCBnKGeQjQXB6PqFn/1nxcQw4pmG42G8lwz+FZPAZAby6gZeHSt/8LMPfZ4Rb+Bd/A==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.27.tgz", + "integrity": "sha512-oAFea8dZgCtVVVTEC7fv3T5CbZW9BxpFzGGxC79xakTr6ooeEqmRuvQydIiDAkglZEAd09LgVf1RoDnL54fu5w==", "dev": true, "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.5.26", - "@vue/shared": "3.5.26" + "@vue/compiler-core": "3.5.27", + "@vue/shared": "3.5.27" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.26.tgz", - "integrity": "sha512-egp69qDTSEZcf4bGOSsprUr4xI73wfrY5oRs6GSgXFTiHrWj4Y3X5Ydtip9QMqiCMCPVwLglB9GBxXtTadJ3mA==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.27.tgz", + "integrity": "sha512-sHZu9QyDPeDmN/MRoshhggVOWE5WlGFStKFwu8G52swATgSny27hJRWteKDSUUzUH+wp+bmeNbhJnEAel/auUQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.28.5", - "@vue/compiler-core": "3.5.26", - "@vue/compiler-dom": "3.5.26", - "@vue/compiler-ssr": "3.5.26", - "@vue/shared": "3.5.26", + "@vue/compiler-core": "3.5.27", + "@vue/compiler-dom": "3.5.27", + "@vue/compiler-ssr": "3.5.27", + "@vue/shared": "3.5.27", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.6", @@ -2219,14 +1853,14 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.26.tgz", - "integrity": "sha512-lZT9/Y0nSIRUPVvapFJEVDbEXruZh2IYHMk2zTtEgJSlP5gVOqeWXH54xDKAaFS4rTnDeDBQUYDtxKyoW9FwDw==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.27.tgz", + "integrity": "sha512-Sj7h+JHt512fV1cTxKlYhg7qxBvack+BGncSpH+8vnN+KN95iPIcqB5rsbblX40XorP+ilO7VIKlkuu3Xq2vjw==", "dev": true, "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.26", - "@vue/shared": "3.5.26" + "@vue/compiler-dom": "3.5.27", + "@vue/shared": "3.5.27" } }, "node_modules/@vue/devtools-api": { @@ -2266,57 +1900,57 @@ } }, "node_modules/@vue/reactivity": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.26.tgz", - "integrity": "sha512-9EnYB1/DIiUYYnzlnUBgwU32NNvLp/nhxLXeWRhHUEeWNTn1ECxX8aGO7RTXeX6PPcxe3LLuNBFoJbV4QZ+CFQ==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.27.tgz", + "integrity": "sha512-vvorxn2KXfJ0nBEnj4GYshSgsyMNFnIQah/wczXlsNXt+ijhugmW+PpJ2cNPe4V6jpnBcs0MhCODKllWG+nvoQ==", "dev": true, "license": "MIT", "dependencies": { - "@vue/shared": "3.5.26" + "@vue/shared": "3.5.27" } }, "node_modules/@vue/runtime-core": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.26.tgz", - "integrity": "sha512-xJWM9KH1kd201w5DvMDOwDHYhrdPTrAatn56oB/LRG4plEQeZRQLw0Bpwih9KYoqmzaxF0OKSn6swzYi84e1/Q==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.27.tgz", + "integrity": "sha512-fxVuX/fzgzeMPn/CLQecWeDIFNt3gQVhxM0rW02Tvp/YmZfXQgcTXlakq7IMutuZ/+Ogbn+K0oct9J3JZfyk3A==", "dev": true, "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.26", - "@vue/shared": "3.5.26" + "@vue/reactivity": "3.5.27", + "@vue/shared": "3.5.27" } }, "node_modules/@vue/runtime-dom": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.26.tgz", - "integrity": "sha512-XLLd/+4sPC2ZkN/6+V4O4gjJu6kSDbHAChvsyWgm1oGbdSO3efvGYnm25yCjtFm/K7rrSDvSfPDgN1pHgS4VNQ==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.27.tgz", + "integrity": "sha512-/QnLslQgYqSJ5aUmb5F0z0caZPGHRB8LEAQ1s81vHFM5CBfnun63rxhvE/scVb/j3TbBuoZwkJyiLCkBluMpeg==", "dev": true, "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.26", - "@vue/runtime-core": "3.5.26", - "@vue/shared": "3.5.26", + "@vue/reactivity": "3.5.27", + "@vue/runtime-core": "3.5.27", + "@vue/shared": "3.5.27", "csstype": "^3.2.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.26.tgz", - "integrity": "sha512-TYKLXmrwWKSodyVuO1WAubucd+1XlLg4set0YoV+Hu8Lo79mp/YMwWV5mC5FgtsDxX3qo1ONrxFaTP1OQgy1uA==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.27.tgz", + "integrity": "sha512-qOz/5thjeP1vAFc4+BY3Nr6wxyLhpeQgAE/8dDtKo6a6xdk+L4W46HDZgNmLOBUDEkFXV3G7pRiUqxjX0/2zWA==", "dev": true, "license": "MIT", "dependencies": { - "@vue/compiler-ssr": "3.5.26", - "@vue/shared": "3.5.26" + "@vue/compiler-ssr": "3.5.27", + "@vue/shared": "3.5.27" }, "peerDependencies": { - "vue": "3.5.26" + "vue": "3.5.27" } }, "node_modules/@vue/shared": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.26.tgz", - "integrity": "sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.27.tgz", + "integrity": "sha512-dXr/3CgqXsJkZ0n9F3I4elY8wM9jMJpP3pvRG52r6m0tu/MsAFIe6JpXVGeNMd/D9F4hQynWT8Rfuj0bdm9kFQ==", "dev": true, "license": "MIT" }, @@ -2462,25 +2096,6 @@ "node": ">=8" } }, - "node_modules/ai": { - "version": "5.0.116", - "resolved": "https://registry.npmjs.org/ai/-/ai-5.0.116.tgz", - "integrity": "sha512-+2hYJ80/NcDWuv9K2/MLP3cTCFgwWHmHlS1tOpFUKKcmLbErAAlE/S2knsKboc3PNAu8pQkDr2N3K/Vle7ENgQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@ai-sdk/gateway": "2.0.23", - "@ai-sdk/provider": "2.0.0", - "@ai-sdk/provider-utils": "3.0.19", - "@opentelemetry/api": "1.9.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "zod": "^3.25.76 || ^4.1.8" - } - }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -2497,32 +2112,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/algoliasearch": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.46.2.tgz", - "integrity": "sha512-qqAXW9QvKf2tTyhpDA4qXv1IfBwD2eduSW6tUEBFIfCeE9gn9HQ9I5+MaKoenRuHrzk5sQoNh1/iof8mY7uD6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/abtesting": "1.12.2", - "@algolia/client-abtesting": "5.46.2", - "@algolia/client-analytics": "5.46.2", - "@algolia/client-common": "5.46.2", - "@algolia/client-insights": "5.46.2", - "@algolia/client-personalization": "5.46.2", - "@algolia/client-query-suggestions": "5.46.2", - "@algolia/client-search": "5.46.2", - "@algolia/ingestion": "1.46.2", - "@algolia/monitoring": "1.46.2", - "@algolia/recommend": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -2616,10 +2205,11 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3203,9 +2793,9 @@ "dev": true }, "node_modules/entities": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.0.tgz", - "integrity": "sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -3446,16 +3036,6 @@ "node": ">=0.10.0" } }, - "node_modules/eventsource-parser": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", - "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3659,13 +3239,13 @@ "dev": true }, "node_modules/focus-trap": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.7.0.tgz", - "integrity": "sha512-DJJDHpEgoSbP8ZE1MNeU2IzCpfFyFdNZZRilqmfH2XiQsPK6PtD8AfJqWzEBudUQB2yHwZc5iq54rjTaGQ+ljw==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.8.0.tgz", + "integrity": "sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA==", "dev": true, "license": "MIT", "dependencies": { - "tabbable": "^6.3.0" + "tabbable": "^6.4.0" } }, "node_modules/foreground-child": { @@ -3782,10 +3362,11 @@ } }, "node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -3970,13 +3551,6 @@ "dev": true, "license": "MIT" }, - "node_modules/htm": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/htm/-/htm-3.1.1.tgz", - "integrity": "sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -4468,13 +4042,6 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true, - "license": "(AFL-2.1 OR BSD-3-Clause)" - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -4689,19 +4256,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/marked": { - "version": "16.4.2", - "resolved": "https://registry.npmjs.org/marked/-/marked-16.4.2.tgz", - "integrity": "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==", - "dev": true, - "license": "MIT", - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 20" - } - }, "node_modules/mdast-util-to-hast": { "version": "13.2.1", "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", @@ -4955,6 +4509,7 @@ "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz", "integrity": "sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==", "dev": true, + "license": "MIT", "dependencies": { "browser-stdout": "^1.3.1", "chokidar": "^4.0.1", @@ -5495,9 +5050,9 @@ "dev": true }, "node_modules/perfect-debounce": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.0.0.tgz", - "integrity": "sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.1.0.tgz", + "integrity": "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==", "dev": true, "license": "MIT" }, @@ -5694,17 +5249,6 @@ "safe-buffer": "^5.1.0" } }, - "node_modules/react": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", - "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -5847,9 +5391,9 @@ } }, "node_modules/rollup": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.54.0.tgz", - "integrity": "sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.56.0.tgz", + "integrity": "sha512-9FwVqlgUHzbXtDg9RCMgodF3Ua4Na6Gau+Sdt9vyCN4RhHfVKX2DCHy3BjMLTDd47ITDhYAnTwGulWTblJSDLg==", "dev": true, "license": "MIT", "dependencies": { @@ -5863,28 +5407,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.54.0", - "@rollup/rollup-android-arm64": "4.54.0", - "@rollup/rollup-darwin-arm64": "4.54.0", - "@rollup/rollup-darwin-x64": "4.54.0", - "@rollup/rollup-freebsd-arm64": "4.54.0", - "@rollup/rollup-freebsd-x64": "4.54.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.54.0", - "@rollup/rollup-linux-arm-musleabihf": "4.54.0", - "@rollup/rollup-linux-arm64-gnu": "4.54.0", - "@rollup/rollup-linux-arm64-musl": "4.54.0", - "@rollup/rollup-linux-loong64-gnu": "4.54.0", - "@rollup/rollup-linux-ppc64-gnu": "4.54.0", - "@rollup/rollup-linux-riscv64-gnu": "4.54.0", - "@rollup/rollup-linux-riscv64-musl": "4.54.0", - "@rollup/rollup-linux-s390x-gnu": "4.54.0", - "@rollup/rollup-linux-x64-gnu": "4.54.0", - "@rollup/rollup-linux-x64-musl": "4.54.0", - "@rollup/rollup-openharmony-arm64": "4.54.0", - "@rollup/rollup-win32-arm64-msvc": "4.54.0", - "@rollup/rollup-win32-ia32-msvc": "4.54.0", - "@rollup/rollup-win32-x64-gnu": "4.54.0", - "@rollup/rollup-win32-x64-msvc": "4.54.0", + "@rollup/rollup-android-arm-eabi": "4.56.0", + "@rollup/rollup-android-arm64": "4.56.0", + "@rollup/rollup-darwin-arm64": "4.56.0", + "@rollup/rollup-darwin-x64": "4.56.0", + "@rollup/rollup-freebsd-arm64": "4.56.0", + "@rollup/rollup-freebsd-x64": "4.56.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.56.0", + "@rollup/rollup-linux-arm-musleabihf": "4.56.0", + "@rollup/rollup-linux-arm64-gnu": "4.56.0", + "@rollup/rollup-linux-arm64-musl": "4.56.0", + "@rollup/rollup-linux-loong64-gnu": "4.56.0", + "@rollup/rollup-linux-loong64-musl": "4.56.0", + "@rollup/rollup-linux-ppc64-gnu": "4.56.0", + "@rollup/rollup-linux-ppc64-musl": "4.56.0", + "@rollup/rollup-linux-riscv64-gnu": "4.56.0", + "@rollup/rollup-linux-riscv64-musl": "4.56.0", + "@rollup/rollup-linux-s390x-gnu": "4.56.0", + "@rollup/rollup-linux-x64-gnu": "4.56.0", + "@rollup/rollup-linux-x64-musl": "4.56.0", + "@rollup/rollup-openbsd-x64": "4.56.0", + "@rollup/rollup-openharmony-arm64": "4.56.0", + "@rollup/rollup-win32-arm64-msvc": "4.56.0", + "@rollup/rollup-win32-ia32-msvc": "4.56.0", + "@rollup/rollup-win32-x64-gnu": "4.56.0", + "@rollup/rollup-win32-x64-msvc": "4.56.0", "fsevents": "~2.3.2" } }, @@ -5916,14 +5463,6 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, - "node_modules/search-insights": { - "version": "2.17.3", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz", - "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==", - "dev": true, - "license": "MIT", - "peer": true - }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -5973,18 +5512,18 @@ } }, "node_modules/shiki": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.20.0.tgz", - "integrity": "sha512-kgCOlsnyWb+p0WU+01RjkCH+eBVsjL1jOwUYWv0YDWkM2/A46+LDKVs5yZCUXjJG6bj4ndFoAg5iLIIue6dulg==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.21.0.tgz", + "integrity": "sha512-N65B/3bqL/TI2crrXr+4UivctrAGEjmsib5rPMMPpFp1xAx/w03v8WZ9RDDFYteXoEgY7qZ4HGgl5KBIu1153w==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/core": "3.20.0", - "@shikijs/engine-javascript": "3.20.0", - "@shikijs/engine-oniguruma": "3.20.0", - "@shikijs/langs": "3.20.0", - "@shikijs/themes": "3.20.0", - "@shikijs/types": "3.20.0", + "@shikijs/core": "3.21.0", + "@shikijs/engine-javascript": "3.21.0", + "@shikijs/engine-oniguruma": "3.21.0", + "@shikijs/langs": "3.21.0", + "@shikijs/themes": "3.21.0", + "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } @@ -6013,10 +5552,11 @@ } }, "node_modules/sinon/node_modules/diff": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.2.tgz", - "integrity": "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", + "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } @@ -6221,24 +5761,10 @@ "node": ">=8" } }, - "node_modules/swr": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/swr/-/swr-2.3.8.tgz", - "integrity": "sha512-gaCPRVoMq8WGDcWj9p4YWzCMPHzE0WNl6W8ADIx9c3JBEIdMkJGMzW+uzXvxHMltwcYACr9jP+32H8/hgwMR7w==", - "dev": true, - "license": "MIT", - "dependencies": { - "dequal": "^2.0.3", - "use-sync-external-store": "^1.6.0" - }, - "peerDependencies": { - "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, "node_modules/tabbable": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.3.0.tgz", - "integrity": "sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.4.0.tgz", + "integrity": "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==", "dev": true, "license": "MIT" }, @@ -6297,19 +5823,6 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "node_modules/throttleit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-2.1.0.tgz", - "integrity": "sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", @@ -6488,9 +6001,9 @@ } }, "node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", "dev": true, "license": "MIT", "dependencies": { @@ -6557,16 +6070,6 @@ "punycode": "^2.1.0" } }, - "node_modules/use-sync-external-store": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", - "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -6607,9 +6110,9 @@ } }, "node_modules/vite": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz", - "integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", "dependencies": { @@ -6728,17 +6231,17 @@ } }, "node_modules/vue": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.26.tgz", - "integrity": "sha512-SJ/NTccVyAoNUJmkM9KUqPcYlY+u8OVL1X5EW9RIs3ch5H2uERxyyIUI4MRxVCSOiEcupX9xNGde1tL9ZKpimA==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.27.tgz", + "integrity": "sha512-aJ/UtoEyFySPBGarREmN4z6qNKpbEguYHMmXSiOGk69czc+zhs0NF6tEFrY8TZKAl8N/LYAkd4JHVd5E/AsSmw==", "dev": true, "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.26", - "@vue/compiler-sfc": "3.5.26", - "@vue/runtime-dom": "3.5.26", - "@vue/server-renderer": "3.5.26", - "@vue/shared": "3.5.26" + "@vue/compiler-dom": "3.5.27", + "@vue/compiler-sfc": "3.5.27", + "@vue/runtime-dom": "3.5.27", + "@vue/server-renderer": "3.5.27", + "@vue/shared": "3.5.27" }, "peerDependencies": { "typescript": "*" @@ -6970,16 +6473,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/zod": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.2.1.tgz", - "integrity": "sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", @@ -6993,228 +6486,6 @@ } }, "dependencies": { - "@ai-sdk/gateway": { - "version": "2.0.23", - "resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-2.0.23.tgz", - "integrity": "sha512-qmX7afPRszUqG5hryHF3UN8ITPIRSGmDW6VYCmByzjoUkgm3MekzSx2hMV1wr0P+llDeuXb378SjqUfpvWJulg==", - "dev": true, - "requires": { - "@ai-sdk/provider": "2.0.0", - "@ai-sdk/provider-utils": "3.0.19", - "@vercel/oidc": "3.0.5" - } - }, - "@ai-sdk/provider": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-2.0.0.tgz", - "integrity": "sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA==", - "dev": true, - "requires": { - "json-schema": "^0.4.0" - } - }, - "@ai-sdk/provider-utils": { - "version": "3.0.19", - "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.19.tgz", - "integrity": "sha512-W41Wc9/jbUVXVwCN/7bWa4IKe8MtxO3EyA0Hfhx6grnmiYlCvpI8neSYWFE0zScXJkgA/YK3BRybzgyiXuu6JA==", - "dev": true, - "requires": { - "@ai-sdk/provider": "2.0.0", - "@standard-schema/spec": "^1.0.0", - "eventsource-parser": "^3.0.6" - } - }, - "@ai-sdk/react": { - "version": "2.0.118", - "resolved": "https://registry.npmjs.org/@ai-sdk/react/-/react-2.0.118.tgz", - "integrity": "sha512-K/5VVEGTIu9SWrdQ0s/11OldFU8IjprDzeE6TaC2fOcQWhG7dGVGl9H8Z32QBHzdfJyMhFUxEyFKSOgA2j9+VQ==", - "dev": true, - "requires": { - "@ai-sdk/provider-utils": "3.0.19", - "ai": "5.0.116", - "swr": "^2.2.5", - "throttleit": "2.1.0" - } - }, - "@algolia/abtesting": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.12.2.tgz", - "integrity": "sha512-oWknd6wpfNrmRcH0vzed3UPX0i17o4kYLM5OMITyMVM2xLgaRbIafoxL0e8mcrNNb0iORCJA0evnNDKRYth5WQ==", - "dev": true, - "requires": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - } - }, - "@algolia/autocomplete-core": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.19.2.tgz", - "integrity": "sha512-mKv7RyuAzXvwmq+0XRK8HqZXt9iZ5Kkm2huLjgn5JoCPtDy+oh9yxUMfDDaVCw0oyzZ1isdJBc7l9nuCyyR7Nw==", - "dev": true, - "requires": { - "@algolia/autocomplete-plugin-algolia-insights": "1.19.2", - "@algolia/autocomplete-shared": "1.19.2" - } - }, - "@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.19.2.tgz", - "integrity": "sha512-TjxbcC/r4vwmnZaPwrHtkXNeqvlpdyR+oR9Wi2XyfORkiGkLTVhX2j+O9SaCCINbKoDfc+c2PB8NjfOnz7+oKg==", - "dev": true, - "requires": { - "@algolia/autocomplete-shared": "1.19.2" - } - }, - "@algolia/autocomplete-shared": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.19.2.tgz", - "integrity": "sha512-jEazxZTVD2nLrC+wYlVHQgpBoBB5KPStrJxLzsIFl6Kqd1AlG9sIAGl39V5tECLpIQzB3Qa2T6ZPJ1ChkwMK/w==", - "dev": true, - "requires": {} - }, - "@algolia/client-abtesting": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.46.2.tgz", - "integrity": "sha512-oRSUHbylGIuxrlzdPA8FPJuwrLLRavOhAmFGgdAvMcX47XsyM+IOGa9tc7/K5SPvBqn4nhppOCEz7BrzOPWc4A==", - "dev": true, - "requires": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - } - }, - "@algolia/client-analytics": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.46.2.tgz", - "integrity": "sha512-EPBN2Oruw0maWOF4OgGPfioTvd+gmiNwx0HmD9IgmlS+l75DatcBkKOPNJN+0z3wBQWUO5oq602ATxIfmTQ8bA==", - "dev": true, - "requires": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - } - }, - "@algolia/client-common": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.46.2.tgz", - "integrity": "sha512-Hj8gswSJNKZ0oyd0wWissqyasm+wTz1oIsv5ZmLarzOZAp3vFEda8bpDQ8PUhO+DfkbiLyVnAxsPe4cGzWtqkg==", - "dev": true - }, - "@algolia/client-insights": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.46.2.tgz", - "integrity": "sha512-6dBZko2jt8FmQcHCbmNLB0kCV079Mx/DJcySTL3wirgDBUH7xhY1pOuUTLMiGkqM5D8moVZTvTdRKZUJRkrwBA==", - "dev": true, - "requires": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - } - }, - "@algolia/client-personalization": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.46.2.tgz", - "integrity": "sha512-1waE2Uqh/PHNeDXGn/PM/WrmYOBiUGSVxAWqiJIj73jqPqvfzZgzdakHscIVaDl6Cp+j5dwjsZ5LCgaUr6DtmA==", - "dev": true, - "requires": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - } - }, - "@algolia/client-query-suggestions": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.46.2.tgz", - "integrity": "sha512-EgOzTZkyDcNL6DV0V/24+oBJ+hKo0wNgyrOX/mePBM9bc9huHxIY2352sXmoZ648JXXY2x//V1kropF/Spx83w==", - "dev": true, - "requires": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - } - }, - "@algolia/client-search": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.46.2.tgz", - "integrity": "sha512-ZsOJqu4HOG5BlvIFnMU0YKjQ9ZI6r3C31dg2jk5kMWPSdhJpYL9xa5hEe7aieE+707dXeMI4ej3diy6mXdZpgA==", - "dev": true, - "requires": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - } - }, - "@algolia/ingestion": { - "version": "1.46.2", - "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.46.2.tgz", - "integrity": "sha512-1Uw2OslTWiOFDtt83y0bGiErJYy5MizadV0nHnOoHFWMoDqWW0kQoMFI65pXqRSkVvit5zjXSLik2xMiyQJDWQ==", - "dev": true, - "requires": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - } - }, - "@algolia/monitoring": { - "version": "1.46.2", - "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.46.2.tgz", - "integrity": "sha512-xk9f+DPtNcddWN6E7n1hyNNsATBCHIqAvVGG2EAGHJc4AFYL18uM/kMTiOKXE/LKDPyy1JhIerrh9oYb7RBrgw==", - "dev": true, - "requires": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - } - }, - "@algolia/recommend": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.46.2.tgz", - "integrity": "sha512-NApbTPj9LxGzNw4dYnZmj2BoXiAc8NmbbH6qBNzQgXklGklt/xldTvu+FACN6ltFsTzoNU6j2mWNlHQTKGC5+Q==", - "dev": true, - "requires": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - } - }, - "@algolia/requester-browser-xhr": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.46.2.tgz", - "integrity": "sha512-ekotpCwpSp033DIIrsTpYlGUCF6momkgupRV/FA3m62SreTSZUKjgK6VTNyG7TtYfq9YFm/pnh65bATP/ZWJEg==", - "dev": true, - "requires": { - "@algolia/client-common": "5.46.2" - } - }, - "@algolia/requester-fetch": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.46.2.tgz", - "integrity": "sha512-gKE+ZFi/6y7saTr34wS0SqYFDcjHW4Wminv8PDZEi0/mE99+hSrbKgJWxo2ztb5eqGirQTgIh1AMVacGGWM1iw==", - "dev": true, - "requires": { - "@algolia/client-common": "5.46.2" - } - }, - "@algolia/requester-node-http": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.46.2.tgz", - "integrity": "sha512-ciPihkletp7ttweJ8Zt+GukSVLp2ANJHU+9ttiSxsJZThXc4Y2yJ8HGVWesW5jN1zrsZsezN71KrMx/iZsOYpg==", - "dev": true, - "requires": { - "@algolia/client-common": "5.46.2" - } - }, "@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -7466,44 +6737,17 @@ "@babel/helper-validator-identifier": "^7.28.5" } }, - "@docsearch/core": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@docsearch/core/-/core-4.4.0.tgz", - "integrity": "sha512-kiwNo5KEndOnrf5Kq/e5+D9NBMCFgNsDoRpKQJ9o/xnSlheh6b8AXppMuuUVVdAUIhIfQFk/07VLjjk/fYyKmw==", - "dev": true, - "requires": {} - }, "@docsearch/css": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-4.4.0.tgz", - "integrity": "sha512-e9vPgtih6fkawakmYo0Y6V4BKBmDV7Ykudn7ADWXUs5b6pmtBRwDbpSG/WiaUG63G28OkJDEnsMvgIAnZgGwYw==", + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-4.5.3.tgz", + "integrity": "sha512-kUpHaxn0AgI3LQfyzTYkNUuaFY4uEz/Ym9/N/FvyDE+PzSgZsCyDH9jE49B6N6f1eLCm9Yp64J9wENd6vypdxA==", "dev": true }, "@docsearch/js": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-4.4.0.tgz", - "integrity": "sha512-vCiKzjYD54bugUIMZA6YzuLDilkD3TNH/kfbvqsnzxiLTMu8F13psD+hdMSEOn7j+dFJOaf49fZ+gwr+rXctMw==", - "dev": true, - "requires": { - "@docsearch/react": "4.4.0", - "htm": "3.1.1" - } - }, - "@docsearch/react": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-4.4.0.tgz", - "integrity": "sha512-z12zeg1mV7WD4Ag4pKSuGukETJLaucVFwszDXL/qLaEgRqxEaVacO9SR1qqnCXvZztlvz2rt7cMqryi/7sKfjA==", - "dev": true, - "requires": { - "@ai-sdk/react": "^2.0.30", - "@algolia/autocomplete-core": "1.19.2", - "@docsearch/core": "4.4.0", - "@docsearch/css": "4.4.0", - "ai": "^5.0.30", - "algoliasearch": "^5.28.0", - "marked": "^16.3.0", - "zod": "^4.1.8" - } + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-4.5.3.tgz", + "integrity": "sha512-rcBiUMCXbZLqrLIT6F6FDcrG/tyvM2WM0zum6NPbIiQNDQxbSgmNc+/bToS0rxBsXaxiU64esiWoS02WqrWLsg==", + "dev": true }, "@esbuild/aix-ppc64": { "version": "0.27.2", @@ -7960,9 +7204,9 @@ } }, "@node-oauth/formats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@node-oauth/formats/-/formats-1.0.0.tgz", - "integrity": "sha512-DwSbLtdC8zC5B5gTJkFzJj5s9vr9SGzOgQvV9nH7tUVuMSScg0EswAczhjIapOmH3Y8AyP7C4Jv7b8+QJObWZA==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@node-oauth/formats/-/formats-1.1.0.tgz", + "integrity": "sha512-Rgkxfg5k3wdI/BymwCK+wdudhyHl6hiqmY/uKuYqQmyKedg9RQCe+LaTHKtzrEthj33cr4bxYlA0onCkQ1AHng==" }, "@nodelib/fs.scandir": { "version": "2.1.5", @@ -7990,12 +7234,6 @@ "fastq": "^1.6.0" } }, - "@opentelemetry/api": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", - "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", - "dev": true - }, "@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -8010,224 +7248,245 @@ "dev": true }, "@rollup/rollup-android-arm-eabi": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.54.0.tgz", - "integrity": "sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.56.0.tgz", + "integrity": "sha512-LNKIPA5k8PF1+jAFomGe3qN3bbIgJe/IlpDBwuVjrDKrJhVWywgnJvflMt/zkbVNLFtF1+94SljYQS6e99klnw==", "dev": true, "optional": true }, "@rollup/rollup-android-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.54.0.tgz", - "integrity": "sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.56.0.tgz", + "integrity": "sha512-lfbVUbelYqXlYiU/HApNMJzT1E87UPGvzveGg2h0ktUNlOCxKlWuJ9jtfvs1sKHdwU4fzY7Pl8sAl49/XaEk6Q==", "dev": true, "optional": true }, "@rollup/rollup-darwin-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.54.0.tgz", - "integrity": "sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.56.0.tgz", + "integrity": "sha512-EgxD1ocWfhoD6xSOeEEwyE7tDvwTgZc8Bss7wCWe+uc7wO8G34HHCUH+Q6cHqJubxIAnQzAsyUsClt0yFLu06w==", "dev": true, "optional": true }, "@rollup/rollup-darwin-x64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.54.0.tgz", - "integrity": "sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.56.0.tgz", + "integrity": "sha512-1vXe1vcMOssb/hOF8iv52A7feWW2xnu+c8BV4t1F//m9QVLTfNVpEdja5ia762j/UEJe2Z1jAmEqZAK42tVW3g==", "dev": true, "optional": true }, "@rollup/rollup-freebsd-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.54.0.tgz", - "integrity": "sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.56.0.tgz", + "integrity": "sha512-bof7fbIlvqsyv/DtaXSck4VYQ9lPtoWNFCB/JY4snlFuJREXfZnm+Ej6yaCHfQvofJDXLDMTVxWscVSuQvVWUQ==", "dev": true, "optional": true }, "@rollup/rollup-freebsd-x64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.54.0.tgz", - "integrity": "sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.56.0.tgz", + "integrity": "sha512-KNa6lYHloW+7lTEkYGa37fpvPq+NKG/EHKM8+G/g9WDU7ls4sMqbVRV78J6LdNuVaeeK5WB9/9VAFbKxcbXKYg==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.54.0.tgz", - "integrity": "sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.56.0.tgz", + "integrity": "sha512-E8jKK87uOvLrrLN28jnAAAChNq5LeCd2mGgZF+fGF5D507WlG/Noct3lP/QzQ6MrqJ5BCKNwI9ipADB6jyiq2A==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm-musleabihf": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.54.0.tgz", - "integrity": "sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.56.0.tgz", + "integrity": "sha512-jQosa5FMYF5Z6prEpTCCmzCXz6eKr/tCBssSmQGEeozA9tkRUty/5Vx06ibaOP9RCrW1Pvb8yp3gvZhHwTDsJw==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.54.0.tgz", - "integrity": "sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.56.0.tgz", + "integrity": "sha512-uQVoKkrC1KGEV6udrdVahASIsaF8h7iLG0U0W+Xn14ucFwi6uS539PsAr24IEF9/FoDtzMeeJXJIBo5RkbNWvQ==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm64-musl": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.54.0.tgz", - "integrity": "sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.56.0.tgz", + "integrity": "sha512-vLZ1yJKLxhQLFKTs42RwTwa6zkGln+bnXc8ueFGMYmBTLfNu58sl5/eXyxRa2RarTkJbXl8TKPgfS6V5ijNqEA==", "dev": true, "optional": true }, "@rollup/rollup-linux-loong64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.54.0.tgz", - "integrity": "sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.56.0.tgz", + "integrity": "sha512-FWfHOCub564kSE3xJQLLIC/hbKqHSVxy8vY75/YHHzWvbJL7aYJkdgwD/xGfUlL5UV2SB7otapLrcCj2xnF1dg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-loong64-musl": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.56.0.tgz", + "integrity": "sha512-z1EkujxIh7nbrKL1lmIpqFTc/sr0u8Uk0zK/qIEFldbt6EDKWFk/pxFq3gYj4Bjn3aa9eEhYRlL3H8ZbPT1xvA==", "dev": true, "optional": true }, "@rollup/rollup-linux-ppc64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.54.0.tgz", - "integrity": "sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.56.0.tgz", + "integrity": "sha512-iNFTluqgdoQC7AIE8Q34R3AuPrJGJirj5wMUErxj22deOcY7XwZRaqYmB6ZKFHoVGqRcRd0mqO+845jAibKCkw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-ppc64-musl": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.56.0.tgz", + "integrity": "sha512-MtMeFVlD2LIKjp2sE2xM2slq3Zxf9zwVuw0jemsxvh1QOpHSsSzfNOTH9uYW9i1MXFxUSMmLpeVeUzoNOKBaWg==", "dev": true, "optional": true }, "@rollup/rollup-linux-riscv64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.54.0.tgz", - "integrity": "sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.56.0.tgz", + "integrity": "sha512-in+v6wiHdzzVhYKXIk5U74dEZHdKN9KH0Q4ANHOTvyXPG41bajYRsy7a8TPKbYPl34hU7PP7hMVHRvv/5aCSew==", "dev": true, "optional": true }, "@rollup/rollup-linux-riscv64-musl": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.54.0.tgz", - "integrity": "sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.56.0.tgz", + "integrity": "sha512-yni2raKHB8m9NQpI9fPVwN754mn6dHQSbDTwxdr9SE0ks38DTjLMMBjrwvB5+mXrX+C0npX0CVeCUcvvvD8CNQ==", "dev": true, "optional": true }, "@rollup/rollup-linux-s390x-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.54.0.tgz", - "integrity": "sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.56.0.tgz", + "integrity": "sha512-zhLLJx9nQPu7wezbxt2ut+CI4YlXi68ndEve16tPc/iwoylWS9B3FxpLS2PkmfYgDQtosah07Mj9E0khc3Y+vQ==", "dev": true, "optional": true }, "@rollup/rollup-linux-x64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.54.0.tgz", - "integrity": "sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.56.0.tgz", + "integrity": "sha512-MVC6UDp16ZSH7x4rtuJPAEoE1RwS8N4oK9DLHy3FTEdFoUTCFVzMfJl/BVJ330C+hx8FfprA5Wqx4FhZXkj2Kw==", "dev": true, "optional": true }, "@rollup/rollup-linux-x64-musl": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.54.0.tgz", - "integrity": "sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.56.0.tgz", + "integrity": "sha512-ZhGH1eA4Qv0lxaV00azCIS1ChedK0V32952Md3FtnxSqZTBTd6tgil4nZT5cU8B+SIw3PFYkvyR4FKo2oyZIHA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-openbsd-x64": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.56.0.tgz", + "integrity": "sha512-O16XcmyDeFI9879pEcmtWvD/2nyxR9mF7Gs44lf1vGGx8Vg2DRNx11aVXBEqOQhWb92WN4z7fW/q4+2NYzCbBA==", "dev": true, "optional": true }, "@rollup/rollup-openharmony-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.54.0.tgz", - "integrity": "sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.56.0.tgz", + "integrity": "sha512-LhN/Reh+7F3RCgQIRbgw8ZMwUwyqJM+8pXNT6IIJAqm2IdKkzpCh/V9EdgOMBKuebIrzswqy4ATlrDgiOwbRcQ==", "dev": true, "optional": true }, "@rollup/rollup-win32-arm64-msvc": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.54.0.tgz", - "integrity": "sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.56.0.tgz", + "integrity": "sha512-kbFsOObXp3LBULg1d3JIUQMa9Kv4UitDmpS+k0tinPBz3watcUiV2/LUDMMucA6pZO3WGE27P7DsfaN54l9ing==", "dev": true, "optional": true }, "@rollup/rollup-win32-ia32-msvc": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.54.0.tgz", - "integrity": "sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.56.0.tgz", + "integrity": "sha512-vSSgny54D6P4vf2izbtFm/TcWYedw7f8eBrOiGGecyHyQB9q4Kqentjaj8hToe+995nob/Wv48pDqL5a62EWtg==", "dev": true, "optional": true }, "@rollup/rollup-win32-x64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.54.0.tgz", - "integrity": "sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.56.0.tgz", + "integrity": "sha512-FeCnkPCTHQJFbiGG49KjV5YGW/8b9rrXAM2Mz2kiIoktq2qsJxRD5giEMEOD2lPdgs72upzefaUvS+nc8E3UzQ==", "dev": true, "optional": true }, "@rollup/rollup-win32-x64-msvc": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.54.0.tgz", - "integrity": "sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.56.0.tgz", + "integrity": "sha512-H8AE9Ur/t0+1VXujj90w0HrSOuv0Nq9r1vSZF2t5km20NTfosQsGGUXDaKdQZzwuLts7IyL1fYT4hM95TI9c4g==", "dev": true, "optional": true }, "@shikijs/core": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.20.0.tgz", - "integrity": "sha512-f2ED7HYV4JEk827mtMDwe/yQ25pRiXZmtHjWF8uzZKuKiEsJR7Ce1nuQ+HhV9FzDcbIo4ObBCD9GPTzNuy9S1g==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.21.0.tgz", + "integrity": "sha512-AXSQu/2n1UIQekY8euBJlvFYZIw0PHY63jUzGbrOma4wPxzznJXTXkri+QcHeBNaFxiiOljKxxJkVSoB3PjbyA==", "dev": true, "requires": { - "@shikijs/types": "3.20.0", + "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "@shikijs/engine-javascript": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.20.0.tgz", - "integrity": "sha512-OFx8fHAZuk7I42Z9YAdZ95To6jDePQ9Rnfbw9uSRTSbBhYBp1kEOKv/3jOimcj3VRUKusDYM6DswLauwfhboLg==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.21.0.tgz", + "integrity": "sha512-ATwv86xlbmfD9n9gKRiwuPpWgPENAWCLwYCGz9ugTJlsO2kOzhOkvoyV/UD+tJ0uT7YRyD530x6ugNSffmvIiQ==", "dev": true, "requires": { - "@shikijs/types": "3.20.0", + "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "@shikijs/engine-oniguruma": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.20.0.tgz", - "integrity": "sha512-Yx3gy7xLzM0ZOjqoxciHjA7dAt5tyzJE3L4uQoM83agahy+PlW244XJSrmJRSBvGYELDhYXPacD4R/cauV5bzQ==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.21.0.tgz", + "integrity": "sha512-OYknTCct6qiwpQDqDdf3iedRdzj6hFlOPv5hMvI+hkWfCKs5mlJ4TXziBG9nyabLwGulrUjHiCq3xCspSzErYQ==", "dev": true, "requires": { - "@shikijs/types": "3.20.0", + "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "@shikijs/langs": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.20.0.tgz", - "integrity": "sha512-le+bssCxcSHrygCWuOrYJHvjus6zhQ2K7q/0mgjiffRbkhM4o1EWu2m+29l0yEsHDbWaWPNnDUTRVVBvBBeKaA==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.21.0.tgz", + "integrity": "sha512-g6mn5m+Y6GBJ4wxmBYqalK9Sp0CFkUqfNzUy2pJglUginz6ZpWbaWjDB4fbQ/8SHzFjYbtU6Ddlp1pc+PPNDVA==", "dev": true, "requires": { - "@shikijs/types": "3.20.0" + "@shikijs/types": "3.21.0" } }, "@shikijs/themes": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.20.0.tgz", - "integrity": "sha512-U1NSU7Sl26Q7ErRvJUouArxfM2euWqq1xaSrbqMu2iqa+tSp0D1Yah8216sDYbdDHw4C8b75UpE65eWorm2erQ==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.21.0.tgz", + "integrity": "sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw==", "dev": true, "requires": { - "@shikijs/types": "3.20.0" + "@shikijs/types": "3.21.0" } }, "@shikijs/transformers": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-3.20.0.tgz", - "integrity": "sha512-PrHHMRr3Q5W1qB/42kJW6laqFyWdhrPF2hNR9qjOm1xcSiAO3hAHo7HaVyHE6pMyevmy3i51O8kuGGXC78uK3g==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-3.21.0.tgz", + "integrity": "sha512-CZwvCWWIiRRiFk9/JKzdEooakAP8mQDtBOQ1TKiCaS2E1bYtyBCOkUzS8akO34/7ufICQ29oeSfkb3tT5KtrhA==", "dev": true, "requires": { - "@shikijs/core": "3.20.0", - "@shikijs/types": "3.20.0" + "@shikijs/core": "3.21.0", + "@shikijs/types": "3.21.0" } }, "@shikijs/types": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.20.0.tgz", - "integrity": "sha512-lhYAATn10nkZcBQ0BlzSbJA3wcmL5MXUUF8d2Zzon6saZDlToKaiRX60n2+ZaHJCmXEcZRWNzn+k9vplr8Jhsw==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.21.0.tgz", + "integrity": "sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA==", "dev": true, "requires": { "@shikijs/vscode-textmate": "^10.0.2", @@ -8276,12 +7535,6 @@ } } }, - "@standard-schema/spec": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", - "dev": true - }, "@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -8346,12 +7599,6 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, - "@vercel/oidc": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.0.5.tgz", - "integrity": "sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw==", - "dev": true - }, "@vitejs/plugin-vue": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.3.tgz", @@ -8362,39 +7609,39 @@ } }, "@vue/compiler-core": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.26.tgz", - "integrity": "sha512-vXyI5GMfuoBCnv5ucIT7jhHKl55Y477yxP6fc4eUswjP8FG3FFVFd41eNDArR+Uk3QKn2Z85NavjaxLxOC19/w==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.27.tgz", + "integrity": "sha512-gnSBQjZA+//qDZen+6a2EdHqJ68Z7uybrMf3SPjEGgG4dicklwDVmMC1AeIHxtLVPT7sn6sH1KOO+tS6gwOUeQ==", "dev": true, "requires": { "@babel/parser": "^7.28.5", - "@vue/shared": "3.5.26", + "@vue/shared": "3.5.27", "entities": "^7.0.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "@vue/compiler-dom": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.26.tgz", - "integrity": "sha512-y1Tcd3eXs834QjswshSilCBnKGeQjQXB6PqFn/1nxcQw4pmG42G8lwz+FZPAZAby6gZeHSt/8LMPfZ4Rb+Bd/A==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.27.tgz", + "integrity": "sha512-oAFea8dZgCtVVVTEC7fv3T5CbZW9BxpFzGGxC79xakTr6ooeEqmRuvQydIiDAkglZEAd09LgVf1RoDnL54fu5w==", "dev": true, "requires": { - "@vue/compiler-core": "3.5.26", - "@vue/shared": "3.5.26" + "@vue/compiler-core": "3.5.27", + "@vue/shared": "3.5.27" } }, "@vue/compiler-sfc": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.26.tgz", - "integrity": "sha512-egp69qDTSEZcf4bGOSsprUr4xI73wfrY5oRs6GSgXFTiHrWj4Y3X5Ydtip9QMqiCMCPVwLglB9GBxXtTadJ3mA==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.27.tgz", + "integrity": "sha512-sHZu9QyDPeDmN/MRoshhggVOWE5WlGFStKFwu8G52swATgSny27hJRWteKDSUUzUH+wp+bmeNbhJnEAel/auUQ==", "dev": true, "requires": { "@babel/parser": "^7.28.5", - "@vue/compiler-core": "3.5.26", - "@vue/compiler-dom": "3.5.26", - "@vue/compiler-ssr": "3.5.26", - "@vue/shared": "3.5.26", + "@vue/compiler-core": "3.5.27", + "@vue/compiler-dom": "3.5.27", + "@vue/compiler-ssr": "3.5.27", + "@vue/shared": "3.5.27", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.6", @@ -8402,13 +7649,13 @@ } }, "@vue/compiler-ssr": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.26.tgz", - "integrity": "sha512-lZT9/Y0nSIRUPVvapFJEVDbEXruZh2IYHMk2zTtEgJSlP5gVOqeWXH54xDKAaFS4rTnDeDBQUYDtxKyoW9FwDw==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.27.tgz", + "integrity": "sha512-Sj7h+JHt512fV1cTxKlYhg7qxBvack+BGncSpH+8vnN+KN95iPIcqB5rsbblX40XorP+ilO7VIKlkuu3Xq2vjw==", "dev": true, "requires": { - "@vue/compiler-dom": "3.5.26", - "@vue/shared": "3.5.26" + "@vue/compiler-dom": "3.5.27", + "@vue/shared": "3.5.27" } }, "@vue/devtools-api": { @@ -8445,50 +7692,50 @@ } }, "@vue/reactivity": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.26.tgz", - "integrity": "sha512-9EnYB1/DIiUYYnzlnUBgwU32NNvLp/nhxLXeWRhHUEeWNTn1ECxX8aGO7RTXeX6PPcxe3LLuNBFoJbV4QZ+CFQ==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.27.tgz", + "integrity": "sha512-vvorxn2KXfJ0nBEnj4GYshSgsyMNFnIQah/wczXlsNXt+ijhugmW+PpJ2cNPe4V6jpnBcs0MhCODKllWG+nvoQ==", "dev": true, "requires": { - "@vue/shared": "3.5.26" + "@vue/shared": "3.5.27" } }, "@vue/runtime-core": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.26.tgz", - "integrity": "sha512-xJWM9KH1kd201w5DvMDOwDHYhrdPTrAatn56oB/LRG4plEQeZRQLw0Bpwih9KYoqmzaxF0OKSn6swzYi84e1/Q==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.27.tgz", + "integrity": "sha512-fxVuX/fzgzeMPn/CLQecWeDIFNt3gQVhxM0rW02Tvp/YmZfXQgcTXlakq7IMutuZ/+Ogbn+K0oct9J3JZfyk3A==", "dev": true, "requires": { - "@vue/reactivity": "3.5.26", - "@vue/shared": "3.5.26" + "@vue/reactivity": "3.5.27", + "@vue/shared": "3.5.27" } }, "@vue/runtime-dom": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.26.tgz", - "integrity": "sha512-XLLd/+4sPC2ZkN/6+V4O4gjJu6kSDbHAChvsyWgm1oGbdSO3efvGYnm25yCjtFm/K7rrSDvSfPDgN1pHgS4VNQ==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.27.tgz", + "integrity": "sha512-/QnLslQgYqSJ5aUmb5F0z0caZPGHRB8LEAQ1s81vHFM5CBfnun63rxhvE/scVb/j3TbBuoZwkJyiLCkBluMpeg==", "dev": true, "requires": { - "@vue/reactivity": "3.5.26", - "@vue/runtime-core": "3.5.26", - "@vue/shared": "3.5.26", + "@vue/reactivity": "3.5.27", + "@vue/runtime-core": "3.5.27", + "@vue/shared": "3.5.27", "csstype": "^3.2.3" } }, "@vue/server-renderer": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.26.tgz", - "integrity": "sha512-TYKLXmrwWKSodyVuO1WAubucd+1XlLg4set0YoV+Hu8Lo79mp/YMwWV5mC5FgtsDxX3qo1ONrxFaTP1OQgy1uA==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.27.tgz", + "integrity": "sha512-qOz/5thjeP1vAFc4+BY3Nr6wxyLhpeQgAE/8dDtKo6a6xdk+L4W46HDZgNmLOBUDEkFXV3G7pRiUqxjX0/2zWA==", "dev": true, "requires": { - "@vue/compiler-ssr": "3.5.26", - "@vue/shared": "3.5.26" + "@vue/compiler-ssr": "3.5.27", + "@vue/shared": "3.5.27" } }, "@vue/shared": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.26.tgz", - "integrity": "sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.27.tgz", + "integrity": "sha512-dXr/3CgqXsJkZ0n9F3I4elY8wM9jMJpP3pvRG52r6m0tu/MsAFIe6JpXVGeNMd/D9F4hQynWT8Rfuj0bdm9kFQ==", "dev": true }, "@vueuse/core": { @@ -8548,18 +7795,6 @@ "indent-string": "^4.0.0" } }, - "ai": { - "version": "5.0.116", - "resolved": "https://registry.npmjs.org/ai/-/ai-5.0.116.tgz", - "integrity": "sha512-+2hYJ80/NcDWuv9K2/MLP3cTCFgwWHmHlS1tOpFUKKcmLbErAAlE/S2knsKboc3PNAu8pQkDr2N3K/Vle7ENgQ==", - "dev": true, - "requires": { - "@ai-sdk/gateway": "2.0.23", - "@ai-sdk/provider": "2.0.0", - "@ai-sdk/provider-utils": "3.0.19", - "@opentelemetry/api": "1.9.0" - } - }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -8572,28 +7807,6 @@ "uri-js": "^4.2.2" } }, - "algoliasearch": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.46.2.tgz", - "integrity": "sha512-qqAXW9QvKf2tTyhpDA4qXv1IfBwD2eduSW6tUEBFIfCeE9gn9HQ9I5+MaKoenRuHrzk5sQoNh1/iof8mY7uD6Q==", - "dev": true, - "requires": { - "@algolia/abtesting": "1.12.2", - "@algolia/client-abtesting": "5.46.2", - "@algolia/client-analytics": "5.46.2", - "@algolia/client-common": "5.46.2", - "@algolia/client-insights": "5.46.2", - "@algolia/client-personalization": "5.46.2", - "@algolia/client-query-suggestions": "5.46.2", - "@algolia/client-search": "5.46.2", - "@algolia/ingestion": "1.46.2", - "@algolia/monitoring": "1.46.2", - "@algolia/recommend": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" - } - }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -8663,9 +7876,9 @@ "dev": true }, "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "requires": { "balanced-match": "^1.0.0", @@ -9041,9 +8254,9 @@ "dev": true }, "entities": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.0.tgz", - "integrity": "sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", "dev": true }, "es6-error": { @@ -9213,12 +8426,6 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, - "eventsource-parser": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", - "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", - "dev": true - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -9357,12 +8564,12 @@ "dev": true }, "focus-trap": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.7.0.tgz", - "integrity": "sha512-DJJDHpEgoSbP8ZE1MNeU2IzCpfFyFdNZZRilqmfH2XiQsPK6PtD8AfJqWzEBudUQB2yHwZc5iq54rjTaGQ+ljw==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.8.0.tgz", + "integrity": "sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA==", "dev": true, "requires": { - "tabbable": "^6.3.0" + "tabbable": "^6.4.0" } }, "foreground-child": { @@ -9427,9 +8634,9 @@ }, "dependencies": { "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "requires": { "balanced-match": "^1.0.0" @@ -9569,12 +8776,6 @@ "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", "dev": true }, - "htm": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/htm/-/htm-3.1.1.tgz", - "integrity": "sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==", - "dev": true - }, "html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -9916,12 +9117,6 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -10090,12 +9285,6 @@ "dev": true, "requires": {} }, - "marked": { - "version": "16.4.2", - "resolved": "https://registry.npmjs.org/marked/-/marked-16.4.2.tgz", - "integrity": "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==", - "dev": true - }, "mdast-util-to-hast": { "version": "13.2.1", "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", @@ -10654,9 +9843,9 @@ } }, "perfect-debounce": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.0.0.tgz", - "integrity": "sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.1.0.tgz", + "integrity": "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==", "dev": true }, "picocolors": { @@ -10778,13 +9967,6 @@ "safe-buffer": "^5.1.0" } }, - "react": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", - "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", - "dev": true, - "peer": true - }, "readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -10889,33 +10071,36 @@ } }, "rollup": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.54.0.tgz", - "integrity": "sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==", - "dev": true, - "requires": { - "@rollup/rollup-android-arm-eabi": "4.54.0", - "@rollup/rollup-android-arm64": "4.54.0", - "@rollup/rollup-darwin-arm64": "4.54.0", - "@rollup/rollup-darwin-x64": "4.54.0", - "@rollup/rollup-freebsd-arm64": "4.54.0", - "@rollup/rollup-freebsd-x64": "4.54.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.54.0", - "@rollup/rollup-linux-arm-musleabihf": "4.54.0", - "@rollup/rollup-linux-arm64-gnu": "4.54.0", - "@rollup/rollup-linux-arm64-musl": "4.54.0", - "@rollup/rollup-linux-loong64-gnu": "4.54.0", - "@rollup/rollup-linux-ppc64-gnu": "4.54.0", - "@rollup/rollup-linux-riscv64-gnu": "4.54.0", - "@rollup/rollup-linux-riscv64-musl": "4.54.0", - "@rollup/rollup-linux-s390x-gnu": "4.54.0", - "@rollup/rollup-linux-x64-gnu": "4.54.0", - "@rollup/rollup-linux-x64-musl": "4.54.0", - "@rollup/rollup-openharmony-arm64": "4.54.0", - "@rollup/rollup-win32-arm64-msvc": "4.54.0", - "@rollup/rollup-win32-ia32-msvc": "4.54.0", - "@rollup/rollup-win32-x64-gnu": "4.54.0", - "@rollup/rollup-win32-x64-msvc": "4.54.0", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.56.0.tgz", + "integrity": "sha512-9FwVqlgUHzbXtDg9RCMgodF3Ua4Na6Gau+Sdt9vyCN4RhHfVKX2DCHy3BjMLTDd47ITDhYAnTwGulWTblJSDLg==", + "dev": true, + "requires": { + "@rollup/rollup-android-arm-eabi": "4.56.0", + "@rollup/rollup-android-arm64": "4.56.0", + "@rollup/rollup-darwin-arm64": "4.56.0", + "@rollup/rollup-darwin-x64": "4.56.0", + "@rollup/rollup-freebsd-arm64": "4.56.0", + "@rollup/rollup-freebsd-x64": "4.56.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.56.0", + "@rollup/rollup-linux-arm-musleabihf": "4.56.0", + "@rollup/rollup-linux-arm64-gnu": "4.56.0", + "@rollup/rollup-linux-arm64-musl": "4.56.0", + "@rollup/rollup-linux-loong64-gnu": "4.56.0", + "@rollup/rollup-linux-loong64-musl": "4.56.0", + "@rollup/rollup-linux-ppc64-gnu": "4.56.0", + "@rollup/rollup-linux-ppc64-musl": "4.56.0", + "@rollup/rollup-linux-riscv64-gnu": "4.56.0", + "@rollup/rollup-linux-riscv64-musl": "4.56.0", + "@rollup/rollup-linux-s390x-gnu": "4.56.0", + "@rollup/rollup-linux-x64-gnu": "4.56.0", + "@rollup/rollup-linux-x64-musl": "4.56.0", + "@rollup/rollup-openbsd-x64": "4.56.0", + "@rollup/rollup-openharmony-arm64": "4.56.0", + "@rollup/rollup-win32-arm64-msvc": "4.56.0", + "@rollup/rollup-win32-ia32-msvc": "4.56.0", + "@rollup/rollup-win32-x64-gnu": "4.56.0", + "@rollup/rollup-win32-x64-msvc": "4.56.0", "@types/estree": "1.0.8", "fsevents": "~2.3.2" } @@ -10934,13 +10119,6 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, - "search-insights": { - "version": "2.17.3", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz", - "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==", - "dev": true, - "peer": true - }, "semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -10978,17 +10156,17 @@ "dev": true }, "shiki": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.20.0.tgz", - "integrity": "sha512-kgCOlsnyWb+p0WU+01RjkCH+eBVsjL1jOwUYWv0YDWkM2/A46+LDKVs5yZCUXjJG6bj4ndFoAg5iLIIue6dulg==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.21.0.tgz", + "integrity": "sha512-N65B/3bqL/TI2crrXr+4UivctrAGEjmsib5rPMMPpFp1xAx/w03v8WZ9RDDFYteXoEgY7qZ4HGgl5KBIu1153w==", "dev": true, "requires": { - "@shikijs/core": "3.20.0", - "@shikijs/engine-javascript": "3.20.0", - "@shikijs/engine-oniguruma": "3.20.0", - "@shikijs/langs": "3.20.0", - "@shikijs/themes": "3.20.0", - "@shikijs/types": "3.20.0", + "@shikijs/core": "3.21.0", + "@shikijs/engine-javascript": "3.21.0", + "@shikijs/engine-oniguruma": "3.21.0", + "@shikijs/langs": "3.21.0", + "@shikijs/themes": "3.21.0", + "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } @@ -11013,9 +10191,9 @@ }, "dependencies": { "diff": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.2.tgz", - "integrity": "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", + "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", "dev": true } } @@ -11154,20 +10332,10 @@ "has-flag": "^4.0.0" } }, - "swr": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/swr/-/swr-2.3.8.tgz", - "integrity": "sha512-gaCPRVoMq8WGDcWj9p4YWzCMPHzE0WNl6W8ADIx9c3JBEIdMkJGMzW+uzXvxHMltwcYACr9jP+32H8/hgwMR7w==", - "dev": true, - "requires": { - "dequal": "^2.0.3", - "use-sync-external-store": "^1.6.0" - } - }, "tabbable": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.3.0.tgz", - "integrity": "sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.4.0.tgz", + "integrity": "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==", "dev": true }, "table-layout": { @@ -11213,12 +10381,6 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "throttleit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-2.1.0.tgz", - "integrity": "sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==", - "dev": true - }, "tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", @@ -11337,9 +10499,9 @@ } }, "unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", "dev": true, "requires": { "@types/unist": "^3.0.0", @@ -11376,13 +10538,6 @@ "punycode": "^2.1.0" } }, - "use-sync-external-store": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", - "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", - "dev": true, - "requires": {} - }, "uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -11410,9 +10565,9 @@ } }, "vite": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz", - "integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "requires": { "esbuild": "^0.27.0", @@ -11451,16 +10606,16 @@ } }, "vue": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.26.tgz", - "integrity": "sha512-SJ/NTccVyAoNUJmkM9KUqPcYlY+u8OVL1X5EW9RIs3ch5H2uERxyyIUI4MRxVCSOiEcupX9xNGde1tL9ZKpimA==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.27.tgz", + "integrity": "sha512-aJ/UtoEyFySPBGarREmN4z6qNKpbEguYHMmXSiOGk69czc+zhs0NF6tEFrY8TZKAl8N/LYAkd4JHVd5E/AsSmw==", "dev": true, "requires": { - "@vue/compiler-dom": "3.5.26", - "@vue/compiler-sfc": "3.5.26", - "@vue/runtime-dom": "3.5.26", - "@vue/server-renderer": "3.5.26", - "@vue/shared": "3.5.26" + "@vue/compiler-dom": "3.5.27", + "@vue/compiler-sfc": "3.5.27", + "@vue/runtime-dom": "3.5.27", + "@vue/server-renderer": "3.5.27", + "@vue/shared": "3.5.27" } }, "walk-back": { @@ -11619,12 +10774,6 @@ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true }, - "zod": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.2.1.tgz", - "integrity": "sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw==", - "dev": true - }, "zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", diff --git a/package.json b/package.json index ea25a5b4..6053de0d 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "CHANGELOG.md" ], "dependencies": { - "@node-oauth/formats": "1.0.0", + "@node-oauth/formats": "^1.1.0", "basic-auth": "2.0.1", "type-is": "2.0.1" }, @@ -34,7 +34,7 @@ "chai": "6.2.2", "eslint": "8.57.1", "jsdoc-to-markdown": "^9.1.3", - "mocha": "11.7.5", + "mocha": "^11.7.5", "nyc": "17.1.0", "sinon": "21.0.1", "vitepress": "^2.0.0-alpha.15" diff --git a/test/compliance/client-authentication_test.js b/test/compliance/client-authentication_test.js index 72624ec5..00c4a92a 100644 --- a/test/compliance/client-authentication_test.js +++ b/test/compliance/client-authentication_test.js @@ -33,7 +33,7 @@ const auth = new OAuth2Server({ }); const user = db.saveUser({ id: 1, username: 'test', password: 'test'}); -const client = db.saveClient({ id: 'a', secret: 'b', grants: ['password'] }); +const client = db.saveClient({ id: 1, secret: 'b', grants: ['password'] }); const scope = 'read write'; function createDefaultRequest () { diff --git a/test/compliance/password-grant-type_test.js b/test/compliance/password-grant-type_test.js index d82193af..318086bb 100644 --- a/test/compliance/password-grant-type_test.js +++ b/test/compliance/password-grant-type_test.js @@ -71,7 +71,7 @@ const auth = new OAuth2Server({ }); const user = db.saveUser({ id: 1, username: 'test', password: 'test'}); -const client = db.saveClient({ id: 'a', secret: 'b', grants: ['password'] }); +const client = db.saveClient({ id: 1, secret: 'b', grants: ['password'] }); const scope = 'read write'; function createDefaultRequest () { diff --git a/test/compliance/refresh-token-grant-type_test.js b/test/compliance/refresh-token-grant-type_test.js index fd3d40da..0d132cb2 100644 --- a/test/compliance/refresh-token-grant-type_test.js +++ b/test/compliance/refresh-token-grant-type_test.js @@ -73,7 +73,7 @@ const auth = new OAuth2Server({ }); const user = db.saveUser({ id: 1, username: 'test', password: 'test'}); -const client = db.saveClient({ id: 'a', secret: 'b', grants: ['password', 'refresh_token'] }); +const client = db.saveClient({ id: '1', secret: 'b', grants: ['password', 'refresh_token'] }); const scope = 'read write'; function createLoginRequest () { diff --git a/test/helpers/db.js b/test/helpers/db.js index 147d1741..a0359887 100644 --- a/test/helpers/db.js +++ b/test/helpers/db.js @@ -31,9 +31,9 @@ class DB { findClient (clientId, clientSecret) { return this.clients.find(client => { if (clientSecret) { - return client.id === clientId && client.secret === clientSecret; + return client.id == clientId && client.secret === clientSecret; } else { - return client.id === clientId; + return client.id == clientId; } }); } diff --git a/test/integration/grant-types/authorization-code-grant-type_test.js b/test/integration/grant-types/authorization-code-grant-type_test.js index c3ec4c09..5d6f3311 100644 --- a/test/integration/grant-types/authorization-code-grant-type_test.js +++ b/test/integration/grant-types/authorization-code-grant-type_test.js @@ -91,17 +91,17 @@ describe('AuthorizationCodeGrantType integration', function() { }); it('should throw an error if `client` is invalid (not in code)', async function() { - const client = { id: 1234 }; + const client = { id: '1234' }; const model = Model.from({ getAuthorizationCode: function(code) { - code.should.equal(123456789); - return { authorizationCode: 12345, expiresAt: new Date(new Date() * 2), user: {} }; + code.should.equal('123456789'); + return { authorizationCode: '12345', expiresAt: new Date(new Date() * 2), user: {} }; }, revokeAuthorizationCode: () => should.fail(), saveToken: () => should.fail() }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 123456789 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '123456789' }, headers: {}, method: {}, query: {} }); try { await grantType.handle(request, client); @@ -112,21 +112,63 @@ describe('AuthorizationCodeGrantType integration', function() { } }); - it('should throw an error if `client` is missing', function() { + it('should throw an error if `client` is missing', async function () { const model = Model.from({ getAuthorizationCode: () => should.fail(), revokeAuthorizationCode: () => should.fail(), saveToken: () => should.fail() }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345' }, headers: {}, method: {}, query: {} }); + const values = [null, undefined, '', 0, false]; + for (const client of values) { + try { + await grantType.handle(request, client); + should.fail(); + } catch (e) { + e.should.be.an.instanceOf(InvalidArgumentError); + e.message.should.equal('Missing parameter: `client`'); + } + } + }); - try { - grantType.handle(request, null); + it('should throw an error if `code` is missing', async function() { + const model = Model.from({ + getAuthorizationCode: () => should.fail(), + revokeAuthorizationCode: () => should.fail(), + saveToken: () => should.fail() + }); + const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); + const values = [null, undefined, '', 0, false]; + for (const code of values) { + const request = new Request({ body: { code }, headers: {}, method: {}, query: {} }); + try { + await grantType.handle(request, { id: 'foobar' }); + should.fail(); + } catch (e) { + e.should.be.an.instanceOf(InvalidRequestError); + e.message.should.equal('Missing parameter: `code`'); + } } - catch (e) { - e.should.be.an.instanceOf(InvalidArgumentError); - e.message.should.equal('Missing parameter: `client`'); + }); + + it('should throw an error if `code` is of invalid format', async function() { + const model = Model.from({ + getAuthorizationCode: () => should.fail(), + revokeAuthorizationCode: () => should.fail(), + saveToken: () => should.fail() + }); + const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); + const values = ['øå€£‰', {}, () => {}, [], Symbol('foo')]; + for (const code of values) { + const request = new Request({ body: { code }, headers: {}, method: {}, query: {} }); + try { + await grantType.handle(request, { id: 'foobar' }); + should.fail(); + } catch (e) { + e.should.be.an.instanceOf(InvalidRequestError); + e.message.should.equal('Invalid parameter: `code`'); + } } }); @@ -135,72 +177,77 @@ describe('AuthorizationCodeGrantType integration', function() { const scope = ['fooscope']; const user = { name: 'foouser' }; const codeDoc = { - authorizationCode: 12345, + authorizationCode: '12345', expiresAt: new Date(new Date() * 2), client, user, scope }; - const model = Model.from({ - getAuthorizationCode: async function (code) { - code.should.equal('code-1234'); - return codeDoc; - }, - revokeAuthorizationCode: async function (_codeDoc) { - _codeDoc.should.deep.equal(codeDoc); - return true; - }, - validateScope: async function (_user, _client, _scope) { - _user.should.deep.equal(user); - _client.should.deep.equal(client); - _scope.should.eql(scope); - return scope; - }, - generateAccessToken: async function (_client, _user, _scope) { - _user.should.deep.equal(user); - _client.should.deep.equal(client); - _scope.should.eql(scope); - return 'long-access-token-hash'; - }, - generateRefreshToken: async function (_client, _user, _scope) { - _user.should.deep.equal(user); - _client.should.deep.equal(client); - _scope.should.eql(scope); - return 'long-refresh-token-hash'; - }, - saveToken: async function (_token, _client, _user) { - _user.should.deep.equal(user); - _client.should.deep.equal(client); - _token.accessToken.should.equal('long-access-token-hash'); - _token.refreshToken.should.equal('long-refresh-token-hash'); - _token.authorizationCode.should.equal(codeDoc.authorizationCode); - _token.accessTokenExpiresAt.should.be.instanceOf(Date); - _token.refreshTokenExpiresAt.should.be.instanceOf(Date); - return _token; - }, - }); + const values = ['1234', 1234]; + for (const code of values) { - const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 'code-1234' }, headers: {}, method: {}, query: {} }); + const model = Model.from({ + getAuthorizationCode: async function (_code) { + _code.should.equal(code); - const token = await grantType.handle(request, client); - token.accessToken.should.equal('long-access-token-hash'); - token.refreshToken.should.equal('long-refresh-token-hash'); - token.authorizationCode.should.equal(codeDoc.authorizationCode); - token.accessTokenExpiresAt.should.be.instanceOf(Date); - token.refreshTokenExpiresAt.should.be.instanceOf(Date); + return codeDoc; + }, + revokeAuthorizationCode: async function (_codeDoc) { + _codeDoc.should.deep.equal(codeDoc); + return true; + }, + validateScope: async function (_user, _client, _scope) { + _user.should.deep.equal(user); + _client.should.deep.equal(client); + _scope.should.eql(scope); + return scope; + }, + generateAccessToken: async function (_client, _user, _scope) { + _user.should.deep.equal(user); + _client.should.deep.equal(client); + _scope.should.eql(scope); + return 'long-access-token-hash'; + }, + generateRefreshToken: async function (_client, _user, _scope) { + _user.should.deep.equal(user); + _client.should.deep.equal(client); + _scope.should.eql(scope); + return 'long-refresh-token-hash'; + }, + saveToken: async function (_token, _client, _user) { + _user.should.deep.equal(user); + _client.should.deep.equal(client); + _token.accessToken.should.equal('long-access-token-hash'); + _token.refreshToken.should.equal('long-refresh-token-hash'); + _token.authorizationCode.should.equal(codeDoc.authorizationCode); + _token.accessTokenExpiresAt.should.be.instanceOf(Date); + _token.refreshTokenExpiresAt.should.be.instanceOf(Date); + return _token; + }, + }); + + const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); + const request = new Request({ body: { code }, headers: {}, method: {}, query: {} }); + + const token = await grantType.handle(request, client); + token.accessToken.should.equal('long-access-token-hash'); + token.refreshToken.should.equal('long-refresh-token-hash'); + token.authorizationCode.should.equal(codeDoc.authorizationCode); + token.accessTokenExpiresAt.should.be.instanceOf(Date); + token.refreshTokenExpiresAt.should.be.instanceOf(Date); + } }); it('should support promises', function() { const client = { id: 'foobar' }; const model = Model.from({ - getAuthorizationCode: function() { return { authorizationCode: 12345, client: { id: 'foobar' }, expiresAt: new Date(new Date() * 2), user: {} }; }, + getAuthorizationCode: function() { return { authorizationCode: '12345', client: { id: 'foobar' }, expiresAt: new Date(new Date() * 2), user: {} }; }, revokeAuthorizationCode: function() { return true; }, saveToken: function() {} }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345' }, headers: {}, method: {}, query: {} }); grantType.handle(request, client).should.be.an.instanceOf(Promise); }); @@ -208,12 +255,12 @@ describe('AuthorizationCodeGrantType integration', function() { it('should support non-promises', function() { const client = { id: 'foobar' }; const model = Model.from({ - getAuthorizationCode: function() { return { authorizationCode: 12345, client: { id: 'foobar' }, expiresAt: new Date(new Date() * 2), user: {} }; }, + getAuthorizationCode: function() { return { authorizationCode: '12345', client: { id: 'foobar' }, expiresAt: new Date(new Date() * 2), user: {} }; }, revokeAuthorizationCode: function() { return true; }, saveToken: function() {} }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345' }, headers: {}, method: {}, query: {} }); grantType.handle(request, client).should.be.an.instanceOf(Promise); }); @@ -265,7 +312,7 @@ describe('AuthorizationCodeGrantType integration', function() { saveToken: () => should.fail() }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345' }, headers: {}, method: {}, query: {} }); try { await grantType.getAuthorizationCode(request, client); @@ -279,12 +326,12 @@ describe('AuthorizationCodeGrantType integration', function() { it('should throw an error if `authorizationCode.client` is missing', async function() { const client = {}; const model = Model.from({ - getAuthorizationCode: async function() { return { authorizationCode: 12345 }; }, + getAuthorizationCode: async function() { return { authorizationcode: '12345' }; }, revokeAuthorizationCode: () => should.fail(), saveToken: () => should.fail() }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345' }, headers: {}, method: {}, query: {} }); try { await grantType.getAuthorizationCode(request, client); @@ -299,13 +346,13 @@ describe('AuthorizationCodeGrantType integration', function() { const client = {}; const model = Model.from({ getAuthorizationCode: async function() { - return { authorizationCode: 12345, client: {}, user: {} }; + return { authorizationCode: '12345', client: {}, user: {} }; }, revokeAuthorizationCode: () => should.fail(), saveToken: () => should.fail() }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345' }, headers: {}, method: {}, query: {} }); try { await grantType.getAuthorizationCode(request, client); @@ -320,13 +367,13 @@ describe('AuthorizationCodeGrantType integration', function() { const client = {}; const model = Model.from({ getAuthorizationCode: async function() { - return { authorizationCode: 12345, client: {}, expiresAt: new Date() }; + return { authorizationCode: '12345', client: {}, expiresAt: new Date() }; }, revokeAuthorizationCode: () => should.fail(), saveToken: () => should.fail() }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345' }, headers: {}, method: {}, query: {} }); try { await grantType.getAuthorizationCode(request, client); @@ -338,16 +385,16 @@ describe('AuthorizationCodeGrantType integration', function() { }); it('should throw an error if the client id does not match', async function() { - const client = { id: 123 }; + const client = { id: '123' }; const model = Model.from({ getAuthorizationCode: async function() { - return { authorizationCode: 12345, expiresAt: new Date(), client: { id: 456 }, user: {} }; + return { authorizationCode: '12345', expiresAt: new Date(), client: { id: 456 }, user: {} }; }, revokeAuthorizationCode: () => should.fail(), saveToken: () => should.fail() }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345' }, headers: {}, method: {}, query: {} }); try { await grantType.getAuthorizationCode(request, client); @@ -359,17 +406,17 @@ describe('AuthorizationCodeGrantType integration', function() { }); it('should throw an error if the auth code is expired', async function() { - const client = { id: 123 }; + const client = { id: '123' }; const date = new Date(new Date() / 2); const model = Model.from({ getAuthorizationCode: async function() { - return { authorizationCode: 12345, client: { id: 123 }, expiresAt: date, user: {} }; + return { authorizationCode: '12345', client: { id: '123' }, expiresAt: date, user: {} }; }, revokeAuthorizationCode: () => should.fail(), saveToken: () => should.fail() }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345' }, headers: {}, method: {}, query: {} }); try { await grantType.getAuthorizationCode(request, client); @@ -381,7 +428,7 @@ describe('AuthorizationCodeGrantType integration', function() { }); it('should throw an error if the `redirectUri` is invalid (format)', async function() { - const authorizationCode = { authorizationCode: 12345, client: { id: 'foobar' }, expiresAt: new Date(new Date() * 2), redirectUri: 'foobar', user: {} }; + const authorizationCode = { authorizationCode: '12345', client: { id: 'foobar' }, expiresAt: new Date(new Date() * 2), redirectUri: 'foobar', user: {} }; const client = { id: 'foobar' }; const model = Model.from({ getAuthorizationCode: async function() { return authorizationCode; }, @@ -389,7 +436,7 @@ describe('AuthorizationCodeGrantType integration', function() { saveToken: () => should.fail() }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345' }, headers: {}, method: {}, query: {} }); try { await grantType.getAuthorizationCode(request, client); @@ -402,28 +449,28 @@ describe('AuthorizationCodeGrantType integration', function() { it('should return an auth code', async function() { const authorizationCode = { - authorizationCode: 1234567, + authorizationCode: '1234567', client: { id: 'foobar' }, expiresAt: new Date(new Date() * 2), user: {} }; const client = { id: 'foobar' }; const model = Model.from({ getAuthorizationCode: async function(_code) { - _code.should.equal(12345); + _code.should.equal('12345'); return authorizationCode; }, revokeAuthorizationCode: () => should.fail(), saveToken: () => should.fail() }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345' }, headers: {}, method: {}, query: {} }); const code = await grantType.getAuthorizationCode(request, client); code.should.deep.equal(authorizationCode); }); it('should support promises', function() { - const authorizationCode = { authorizationCode: 12345, client: { id: 'foobar' }, expiresAt: new Date(new Date() * 2), user: {} }; + const authorizationCode = { authorizationCode: '12345', client: { id: 'foobar' }, expiresAt: new Date(new Date() * 2), user: {} }; const client = { id: 'foobar' }; const model = Model.from({ getAuthorizationCode: async function() { return authorizationCode; }, @@ -431,13 +478,13 @@ describe('AuthorizationCodeGrantType integration', function() { saveToken: function() {} }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345' }, headers: {}, method: {}, query: {} }); grantType.getAuthorizationCode(request, client).should.be.an.instanceOf(Promise); }); it('should support non-promises', function() { - const authorizationCode = { authorizationCode: 12345, client: { id: 'foobar' }, expiresAt: new Date(new Date() * 2), user: {} }; + const authorizationCode = { authorizationCode: '12345', client: { id: 'foobar' }, expiresAt: new Date(new Date() * 2), user: {} }; const client = { id: 'foobar' }; const model = Model.from({ getAuthorizationCode: function() { return authorizationCode; }, @@ -445,7 +492,7 @@ describe('AuthorizationCodeGrantType integration', function() { saveToken: function() {} }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345' }, headers: {}, method: {}, query: {} }); grantType.getAuthorizationCode(request, client).should.be.an.instanceOf(Promise); }); @@ -453,14 +500,14 @@ describe('AuthorizationCodeGrantType integration', function() { describe('validateRedirectUri()', function() { it('should throw an error if `redirectUri` is missing', function() { - const authorizationCode = { authorizationCode: 12345, client: {}, expiresAt: new Date(new Date() / 2), redirectUri: 'http://foo.bar', user: {} }; + const authorizationCode = { authorizationCode: '12345', client: { id: '123' }, expiresAt: new Date(new Date() / 2), redirectUri: 'http://foo.bar', user: {} }; const model = Model.from({ getAuthorizationCode: function() {}, revokeAuthorizationCode: function() { return authorizationCode; }, saveToken: function() {} }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345' }, headers: {}, method: {}, query: {} }); try { grantType.validateRedirectUri(request, authorizationCode); @@ -473,14 +520,14 @@ describe('AuthorizationCodeGrantType integration', function() { }); it('should throw an error if `redirectUri` is invalid', function() { - const authorizationCode = { authorizationCode: 12345, client: {}, expiresAt: new Date(new Date() / 2), redirectUri: 'http://foo.bar', user: {} }; + const authorizationCode = { authorizationcode: '12345', client: {}, expiresAt: new Date(new Date() / 2), redirectUri: 'http://foo.bar', user: {} }; const model = Model.from({ getAuthorizationCode: function() {}, revokeAuthorizationCode: function() { return true; }, saveToken: function() {} }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345, redirect_uri: 'http://bar.foo' }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345', redirect_uri: 'http://bar.foo' }, headers: {}, method: {}, query: {} }); try { grantType.validateRedirectUri(request, authorizationCode); @@ -492,14 +539,14 @@ describe('AuthorizationCodeGrantType integration', function() { } }); it('returns undefined and does not throw if `redirectUri` is valid', async function () { - const authorizationCode = { authorizationCode: 12345, client: {}, expiresAt: new Date(new Date() / 2), redirectUri: 'http://foo.bar', user: {} }; + const authorizationCode = { authorizationcode: '12345', client: {}, expiresAt: new Date(new Date() / 2), redirectUri: 'http://foo.bar', user: {} }; const model = Model.from({ getAuthorizationCode: function() {}, revokeAuthorizationCode: function() { return true; }, saveToken: function() {} }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345, redirect_uri: 'http://foo.bar' }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345', redirect_uri: 'http://foo.bar' }, headers: {}, method: {}, query: {} }); const value = grantType.validateRedirectUri(request, authorizationCode); const isUndefined = value === undefined; isUndefined.should.equal(true); @@ -508,7 +555,7 @@ describe('AuthorizationCodeGrantType integration', function() { describe('revokeAuthorizationCode()', function() { it('should revoke the auth code', async function() { - const authorizationCode = { authorizationCode: 12345, client: {}, expiresAt: new Date(new Date() / 2), user: {} }; + const authorizationCode = { authorizationcode: '12345', client: {}, expiresAt: new Date(new Date() / 2), user: {} }; const model = Model.from({ getAuthorizationCode: () => should.fail(), revokeAuthorizationCode: async function(_code) { @@ -524,7 +571,7 @@ describe('AuthorizationCodeGrantType integration', function() { }); it('should throw an error when the auth code is invalid', async function() { - const authorizationCode = { authorizationCode: 12345, client: {}, expiresAt: new Date(new Date() / 2), user: {} }; + const authorizationCode = { authorizationcode: '12345', client: {}, expiresAt: new Date(new Date() / 2), user: {} }; const returnTypes = [false, null, undefined, 0, '']; for (const type of returnTypes) { @@ -549,7 +596,7 @@ describe('AuthorizationCodeGrantType integration', function() { }); it('should support promises', function() { - const authorizationCode = { authorizationCode: 12345, client: {}, expiresAt: new Date(new Date() / 2), user: {} }; + const authorizationCode = { authorizationcode: '12345', client: {}, expiresAt: new Date(new Date() / 2), user: {} }; const model = Model.from({ getAuthorizationCode: () => should.fail(), revokeAuthorizationCode: async function() { return true; }, @@ -560,7 +607,7 @@ describe('AuthorizationCodeGrantType integration', function() { }); it('should support non-promises', function() { - const authorizationCode = { authorizationCode: 12345, client: {}, expiresAt: new Date(new Date() / 2), user: {} }; + const authorizationCode = { authorizationcode: '12345', client: {}, expiresAt: new Date(new Date() / 2), user: {} }; const model = Model.from({ getAuthorizationCode: () => should.fail(), revokeAuthorizationCode: function() { return authorizationCode; }, diff --git a/test/integration/grant-types/refresh-token-grant-type_test.js b/test/integration/grant-types/refresh-token-grant-type_test.js index 658983aa..9c06d9bb 100644 --- a/test/integration/grant-types/refresh-token-grant-type_test.js +++ b/test/integration/grant-types/refresh-token-grant-type_test.js @@ -112,10 +112,10 @@ describe('RefreshTokenGrantType integration', function() { }); it('should return a token', async function() { - const client = { id: 123 }; + const client = { id: '123' }; const token = { accessToken: 'foo', - client: { id: 123 }, + client: { id: '123' }, user: { name: 'foo' }, scope: ['read', 'write'], refreshTokenExpiresAt: new Date( new Date() * 2) @@ -131,19 +131,19 @@ describe('RefreshTokenGrantType integration', function() { }, generateAccessToken: async function (_client, _user, _scope) { _user.should.deep.equal({ name: 'foo' }); - _client.should.deep.equal({ id: 123 }); + _client.should.deep.equal({ id: '123' }); _scope.should.eql(['read', 'write']); return 'new-access-token'; }, generateRefreshToken: async function (_client, _user, _scope) { _user.should.deep.equal({ name: 'foo' }); - _client.should.deep.equal({ id: 123 }); + _client.should.deep.equal({ id: '123' }); _scope.should.eql(['read', 'write']); return 'new-refresh-token'; }, saveToken: async function(_token, _client, _user) { _user.should.deep.equal({ name: 'foo' }); - _client.should.deep.equal({ id: 123 }); + _client.should.deep.equal({ id: '123' }); _token.accessToken.should.equal('new-access-token'); _token.refreshToken.should.equal('new-refresh-token'); _token.accessTokenExpiresAt.should.be.instanceOf(Date); @@ -159,9 +159,9 @@ describe('RefreshTokenGrantType integration', function() { }); it('should support promises', function() { - const client = { id: 123 }; + const client = { id: '123' }; const model = Model.from({ - getRefreshToken: async function() { return { accessToken: 'foo', client: { id: 123 }, user: {} }; }, + getRefreshToken: async function() { return { accessToken: 'foo', client: { id: '123' }, user: {} }; }, revokeToken: async function() { return { accessToken: 'foo', client: {}, refreshTokenExpiresAt: new Date(new Date() / 2), user: {} }; }, saveToken: async function() { return { accessToken: 'foo', client: {}, user: {} }; } }); @@ -172,9 +172,9 @@ describe('RefreshTokenGrantType integration', function() { }); it('should support non-promises', function() { - const client = { id: 123 }; + const client = { id: '123' }; const model = Model.from({ - getRefreshToken: async function() { return { accessToken: 'foo', client: { id: 123 }, user: {} }; }, + getRefreshToken: async function() { return { accessToken: 'foo', client: { id: '123' }, user: {} }; }, revokeToken: async function() { return { accessToken: 'foo', client: {}, refreshTokenExpiresAt: new Date(new Date() / 2), user: {} }; }, saveToken: async function() { return { accessToken: 'foo', client: {}, user: {} }; } }); @@ -187,6 +187,30 @@ describe('RefreshTokenGrantType integration', function() { describe('getRefreshToken()', function() { it('should throw an error if the `refreshToken` parameter is missing from the request body', async function() { + const client = {}; + const model = Model.from({ + getRefreshToken: () => should.fail(), + revokeToken: () => should.fail(), + saveToken: () => should.fail() + }); + const values = [null, undefined]; + + for (const value of values) { + const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 120, model }); + const request = new Request({ body: { refresh_token: value }, headers: {}, method: {}, query: {} }); + + try { + await grantType.getRefreshToken(request, client); + + should.fail(); + } catch (e) { + e.should.be.an.instanceOf(InvalidRequestError); + e.message.should.equal('Missing parameter: `refresh_token`'); + } + } + }); + + it('should throw an error if `refreshToken` is not a valid format', async () => { const client = {}; const model = Model.from({ getRefreshToken: () => should.fail(), @@ -194,20 +218,23 @@ describe('RefreshTokenGrantType integration', function() { saveToken: () => should.fail() }); const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 120, model }); - const request = new Request({ body: {}, headers: {}, method: {}, query: {} }); + const values = ['toke😇n', () => {}, [], Symbol('test')]; - try { - await grantType.getRefreshToken(request, client); + for (const value of values) { + const request = new Request({ body: { refresh_token: value }, headers: {}, method: {}, query: {} }); + try { + await grantType.getRefreshToken(request, client); - should.fail(); - } catch (e) { - e.should.be.an.instanceOf(InvalidRequestError); - e.message.should.equal('Missing parameter: `refresh_token`'); + should.fail(); + } catch (e) { + e.should.be.an.instanceOf(InvalidRequestError); + e.message.should.equal('Invalid parameter: `refresh_token`'); + } } }); it('should throw an error if `refreshToken` is not found', async function() { - const client = { id: 123 }; + const client = { id: '123' }; const model = Model.from({ getRefreshToken: async function() {} , revokeToken: () => should.fail(), @@ -233,8 +260,9 @@ describe('RefreshTokenGrantType integration', function() { revokeToken: () => should.fail(), saveToken: () => should.fail() }); + const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 120, model }); - const request = new Request({ body: { refresh_token: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { refresh_token: '12345' }, headers: {}, method: {}, query: {} }); try { await grantType.getRefreshToken(request, client); @@ -255,30 +283,34 @@ describe('RefreshTokenGrantType integration', function() { revokeToken: () => should.fail(), saveToken: () => should.fail() }); - const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 120, model }); - const request = new Request({ body: { refresh_token: 12345 }, headers: {}, method: {}, query: {} }); - try { - await grantType.getRefreshToken(request, client); + const values = [12345, '12345']; + for (const value of values) { + const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 120, model }); + const request = new Request({ body: { refresh_token: value }, headers: {}, method: {}, query: {} }); - should.fail(); - } catch (e) { - e.should.be.an.instanceOf(ServerError); - e.message.should.equal('Server error: `getRefreshToken()` did not return a `user` object'); + try { + await grantType.getRefreshToken(request, client); + + should.fail(); + } catch (e) { + e.should.be.an.instanceOf(ServerError); + e.message.should.equal('Server error: `getRefreshToken()` did not return a `user` object'); + } } }); it('should throw an error if the client id does not match', async function() { - const client = { id: 123 }; + const client = { id: '123' }; const model = Model.from({ getRefreshToken: async function() { - return { accessToken: 'foo', client: { id: 456 }, user: {} }; + return { accessToken: 'foo', client: { id: '456' }, user: {} }; }, revokeToken: () => should.fail(), saveToken: () => should.fail() }); const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 120, model }); - const request = new Request({ body: { refresh_token: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { refresh_token: '12345' }, headers: {}, method: {}, query: {} }); try { await grantType.getRefreshToken(request, client); @@ -294,7 +326,7 @@ describe('RefreshTokenGrantType integration', function() { const client = {}; const model = Model.from({ getRefreshToken: async function() { - return { client: { id: 456 }, user: {} }; + return { client: { id: '456' }, user: {} }; }, revokeToken: () => should.fail(), saveToken: () => should.fail() @@ -316,13 +348,13 @@ describe('RefreshTokenGrantType integration', function() { const client = {}; const model = Model.from({ getRefreshToken: async function() { - return { accessToken: 'foo', client: { id: 456 }, user: {} }; + return { accessToken: 'foo', client: { id: '456' }, user: {} }; }, revokeToken: () => should.fail(), saveToken: () => should.fail() }); const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 120, model }); - const request = new Request({ body: { refresh_token: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { refresh_token: '12345' }, headers: {}, method: {}, query: {} }); try { await grantType.getRefreshToken(request, client); @@ -335,17 +367,17 @@ describe('RefreshTokenGrantType integration', function() { }); it('should throw an error if `refresh_token` is expired', async function() { - const client = { id: 123 }; + const client = { id: '123' }; const date = new Date(new Date() / 2); const model = Model.from({ getRefreshToken: async function() { - return { accessToken: 'foo', client: { id: 123 }, refreshTokenExpiresAt: date, user: {} }; + return { accessToken: 'foo', client: { id: '123' }, refreshTokenExpiresAt: date, user: {} }; }, revokeToken: () => should.fail(), saveToken: () => should.fail() }); const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 120, model }); - const request = new Request({ body: { refresh_token: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { refresh_token: '12345' }, headers: {}, method: {}, query: {} }); try { await grantType.getRefreshToken(request, client); @@ -358,16 +390,16 @@ describe('RefreshTokenGrantType integration', function() { }); it('should throw an error if `refreshTokenExpiresAt` is not a date value', async function() { - const client = { id: 123 }; + const client = { id: '123' }; const model = Model.from({ getRefreshToken: async function() { - return { accessToken: 'foo', client: { id: 123 }, refreshTokenExpiresAt: 'stringvalue', user: {} }; + return { accessToken: 'foo', client: { id: '123' }, refreshTokenExpiresAt: 'stringvalue', user: {} }; }, revokeToken: () => should.fail(), saveToken: () => should.fail() }); const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 120, model }); - const request = new Request({ body: { refresh_token: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { refresh_token: '12345' }, headers: {}, method: {}, query: {} }); try { await grantType.getRefreshToken(request, client); @@ -380,8 +412,8 @@ describe('RefreshTokenGrantType integration', function() { }); it('should return a token', async function() { - const client = { id: 123 }; - const token = { accessToken: 'foo', client: { id: 123 }, user: { name: 'foobar' } }; + const client = { id: '123' }; + const token = { accessToken: 'foo', client: { id: '123' }, user: { name: 'foobar' } }; const model = Model.from({ getRefreshToken: async function(_refreshToken) { _refreshToken.should.equal('foobar_refresh'); @@ -409,8 +441,8 @@ describe('RefreshTokenGrantType integration', function() { }); it('should support promises', function() { - const client = { id: 123 }; - const token = { accessToken: 'foo', client: { id: 123 }, user: {} }; + const client = { id: '123' }; + const token = { accessToken: 'foo', client: { id: '123' }, user: {} }; const model = Model.from({ getRefreshToken: async function() { return token; }, revokeToken: async function() {}, @@ -423,8 +455,8 @@ describe('RefreshTokenGrantType integration', function() { }); it('should support non-promises', function() { - const client = { id: 123 }; - const token = { accessToken: 'foo', client: { id: 123 }, user: {} }; + const client = { id: '123' }; + const token = { accessToken: 'foo', client: { id: '123' }, user: {} }; const model = Model.from({ getRefreshToken: async function() { return token; }, revokeToken: async function() {}, @@ -499,7 +531,7 @@ describe('RefreshTokenGrantType integration', function() { describe('saveToken()', function() { it('should save the token', async function() { const user = { name: 'foo' }; - const client = { id: 123465 }; + const client = { id: '123465' }; const scope = ['foo', 'bar']; const model = Model.from({ getRefreshToken: () => should.fail(), diff --git a/test/integration/handlers/authorize-handler_test.js b/test/integration/handlers/authorize-handler_test.js index fb6904d4..ddf08e6b 100644 --- a/test/integration/handlers/authorize-handler_test.js +++ b/test/integration/handlers/authorize-handler_test.js @@ -238,7 +238,7 @@ describe('AuthorizeHandler integration', function() { const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model }); const request = new Request({ body: { - client_id: 12345, + client_id: '12345', response_type: 'code' }, headers: { @@ -282,7 +282,7 @@ describe('AuthorizeHandler integration', function() { const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model }); const request = new Request({ body: { - client_id: 12345, + client_id: '12345', response_type: 'code' }, headers: { @@ -378,7 +378,7 @@ describe('AuthorizeHandler integration', function() { const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model }); const request = new Request({ body: { - client_id: 12345, + client_id: '12345', response_type: 'code' }, headers: { @@ -423,7 +423,7 @@ describe('AuthorizeHandler integration', function() { const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model }); const request = new Request({ body: { - client_id: 12345, + client_id: '12345', response_type: 'code' }, headers: { @@ -449,7 +449,7 @@ describe('AuthorizeHandler integration', function() { }); it('should redirect to an error response if `scope` is insufficient (validateScope)', async function() { - const client = { id: 12345, grants: ['authorization_code'], redirectUris: ['http://example.com/cb'] }; + const client = { id: '12345', grants: ['authorization_code'], redirectUris: ['http://example.com/cb'] }; const model = Model.from({ getAccessToken: async function() { return { @@ -462,7 +462,7 @@ describe('AuthorizeHandler integration', function() { return client; }, saveAuthorizationCode: async function() { - return { authorizationCode: 12345, client }; + return { authorizationCode: '12345', client }; }, validateScope: async function(_user, _client, _scope) { _scope.should.eql(['read']); @@ -472,7 +472,7 @@ describe('AuthorizeHandler integration', function() { const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model }); const request = new Request({ body: { - client_id: 12345, + client_id: '12345', response_type: 'code' }, headers: { @@ -518,7 +518,7 @@ describe('AuthorizeHandler integration', function() { const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model }); const request = new Request({ body: { - client_id: 12345, + client_id: '12345', response_type: 'code' }, headers: { @@ -559,7 +559,7 @@ describe('AuthorizeHandler integration', function() { const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model }); const request = new Request({ body: { - client_id: 12345, + client_id: '12345', response_type: 'test' }, headers: { @@ -607,7 +607,7 @@ describe('AuthorizeHandler integration', function() { const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model }); const request = new Request({ body: { - client_id: 12345, + client_id: '12345', response_type: 'code' }, headers: { @@ -735,7 +735,7 @@ describe('AuthorizeHandler integration', function() { const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model, authenticateHandler }); const request = new Request({ body: { - client_id: 12345, + client_id: '12345', response_type: 'code' }, headers: { @@ -904,7 +904,7 @@ describe('AuthorizeHandler integration', function() { saveAuthorizationCode: function() {} }); const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model }); - const request = new Request({ body: { client_id: 12345, response_type: 'code', redirect_uri: 'foobar' }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { client_id: '12345', response_type: 'code', redirect_uri: 'foobar' }, headers: {}, method: {}, query: {} }); try { await handler.getClient(request); @@ -923,7 +923,7 @@ describe('AuthorizeHandler integration', function() { saveAuthorizationCode: function() {} }); const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model }); - const request = new Request({ body: { client_id: 12345, response_type: 'code' }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { client_id: '12345', response_type: 'code' }, headers: {}, method: {}, query: {} }); return handler.getClient(request) .then(should.fail) @@ -942,7 +942,7 @@ describe('AuthorizeHandler integration', function() { saveAuthorizationCode: function() {} }); const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model }); - const request = new Request({ body: { client_id: 12345, response_type: 'code' }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { client_id: '12345', response_type: 'code' }, headers: {}, method: {}, query: {} }); return handler.getClient(request) .then(should.fail) @@ -961,7 +961,7 @@ describe('AuthorizeHandler integration', function() { saveAuthorizationCode: function() {} }); const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model }); - const request = new Request({ body: { client_id: 12345, response_type: 'code' }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { client_id: '12345', response_type: 'code' }, headers: {}, method: {}, query: {} }); return handler.getClient(request) .then(should.fail) @@ -978,7 +978,7 @@ describe('AuthorizeHandler integration', function() { saveAuthorizationCode: function() {} }); const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model }); - const request = new Request({ body: { client_id: 12345, response_type: 'code' }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { client_id: '12345', response_type: 'code' }, headers: {}, method: {}, query: {} }); return handler.getClient(request) .then(should.fail) @@ -997,7 +997,7 @@ describe('AuthorizeHandler integration', function() { saveAuthorizationCode: function() {} }); const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model }); - const request = new Request({ body: { client_id: 12345, response_type: 'code', redirect_uri: 'https://foobar.com' }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { client_id: '12345', response_type: 'code', redirect_uri: 'https://foobar.com' }, headers: {}, method: {}, query: {} }); return handler.getClient(request) .then(should.fail) @@ -1017,7 +1017,7 @@ describe('AuthorizeHandler integration', function() { }); const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model }); const request = new Request({ - body: { client_id: 12345 }, + body: { client_id: '12345' }, headers: {}, method: {}, query: {} @@ -1036,7 +1036,7 @@ describe('AuthorizeHandler integration', function() { }); const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model }); const request = new Request({ - body: { client_id: 12345 }, + body: { client_id: '12345' }, headers: {}, method: {}, query: {} @@ -1056,7 +1056,7 @@ describe('AuthorizeHandler integration', function() { saveAuthorizationCode: function() {} }); const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model }); - const request = new Request({ body: { response_type: 'code' }, headers: {}, method: {}, query: { client_id: 12345 } }); + const request = new Request({ body: { response_type: 'code' }, headers: {}, method: {}, query: { client_id: '12345' } }); return handler.getClient(request) .then(function(data) { diff --git a/test/integration/handlers/token-handler_test.js b/test/integration/handlers/token-handler_test.js index 46f3ab19..9ae206ad 100644 --- a/test/integration/handlers/token-handler_test.js +++ b/test/integration/handlers/token-handler_test.js @@ -246,7 +246,7 @@ describe('TokenHandler integration', function() { const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 }); const request = new Request({ body: { - client_id: 12345, + client_id: '12345', client_secret: 'secret', grant_type: 'password', password: 'bar', @@ -278,7 +278,7 @@ describe('TokenHandler integration', function() { const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 }); const request = new Request({ body: { - client_id: 12345, + client_id: '12345', client_secret: 'secret', grant_type: 'password', password: 'bar', @@ -309,7 +309,7 @@ describe('TokenHandler integration', function() { const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 }); const request = new Request({ body: { - client_id: 12345, + client_id: '12345', client_secret: 'secret', username: 'foo', password: 'bar', @@ -340,7 +340,7 @@ describe('TokenHandler integration', function() { const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 }); const request = new Request({ body: { - client_id: 12345, + client_id: '12345', client_secret: 'secret', username: 'foo', password: 'bar', @@ -375,7 +375,7 @@ describe('TokenHandler integration', function() { const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120, allowExtendedTokenAttributes: true }); const request = new Request({ body: { - client_id: 12345, + client_id: '12345', client_secret: 'secret', username: 'foo', password: 'bar', @@ -444,7 +444,7 @@ describe('TokenHandler integration', function() { saveToken: function() {} }); const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 }); - const request = new Request({ body: { client_id: 12345, client_secret: 'secret' }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { client_id: '12345', client_secret: 'secret' }, headers: {}, method: {}, query: {} }); return handler.getClient(request) .then(should.fail) @@ -460,7 +460,7 @@ describe('TokenHandler integration', function() { saveToken: function() {} }); const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 }); - const request = new Request({ body: { client_id: 12345, client_secret: 'secret' }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { client_id: '12345', client_secret: 'secret' }, headers: {}, method: {}, query: {} }); return handler.getClient(request) .then(should.fail) @@ -476,7 +476,7 @@ describe('TokenHandler integration', function() { saveToken: function() {} }); const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 }); - const request = new Request({ body: { client_id: 12345, client_secret: 'secret' }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { client_id: '12345', client_secret: 'secret' }, headers: {}, method: {}, query: {} }); return handler.getClient(request) .then(should.fail) @@ -512,13 +512,13 @@ describe('TokenHandler integration', function() { }); it('should return a client', function() { - const client = { id: 12345, grants: [] }; + const client = { id: '12345', grants: [] }; const model = Model.from({ getClient: function() { return client; }, saveToken: function() {} }); const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 }); - const request = new Request({ body: { client_id: 12345, client_secret: 'secret' }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { client_id: '12345', client_secret: 'secret' }, headers: {}, method: {}, query: {} }); return handler.getClient(request) .then(function(data) { @@ -530,7 +530,7 @@ describe('TokenHandler integration', function() { describe('with `password` grant type and `requireClientAuthentication` is false', function() { it('should return a client ', function() { - const client = { id: 12345, grants: [] }; + const client = { id: '12345', grants: [] }; const model = Model.from({ getClient: function() { return client; }, saveToken: function() {} @@ -557,7 +557,7 @@ describe('TokenHandler integration', function() { describe('with `password` grant type and `requireClientAuthentication` is false and Authorization header', function() { it('should return a client ', function() { - const client = { id: 12345, grants: [] }; + const client = { id: '12345', grants: [] }; const model = Model.from({ getClient: function() { return client; }, saveToken: function() {} @@ -592,7 +592,7 @@ describe('TokenHandler integration', function() { saveToken: function() {} }); const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 }); - const request = new Request({ body: { client_id: 12345, client_secret: 'secret' }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { client_id: '12345', client_secret: 'secret' }, headers: {}, method: {}, query: {} }); handler.getClient(request).should.be.an.instanceOf(Promise); }); @@ -603,7 +603,7 @@ describe('TokenHandler integration', function() { saveToken: function() {} }); const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 }); - const request = new Request({ body: { client_id: 12345, client_secret: 'secret' }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { client_id: '12345', client_secret: 'secret' }, headers: {}, method: {}, query: {} }); handler.getClient(request).should.be.an.instanceOf(Promise); }); @@ -793,16 +793,16 @@ describe('TokenHandler integration', function() { const client = { id: 'foobar', grants: ['authorization_code'] }; const token = {}; const model = Model.from({ - getAuthorizationCode: function() { return { authorizationCode: 12345, client: { id: 'foobar' }, expiresAt: new Date(new Date() * 2), user: {} }; }, + getAuthorizationCode: function() { return { authorizationCode: '12345', client: { id: 'foobar' }, expiresAt: new Date(new Date() * 2), user: {} }; }, getClient: function() {}, saveToken: function() { return token; }, validateScope: function() { return ['foo']; }, - revokeAuthorizationCode: function() { return { authorizationCode: 12345, client: { id: 'foobar' }, expiresAt: new Date(new Date() / 2), user: {} }; } + revokeAuthorizationCode: function() { return { authorizationCode: '12345', client: { id: 'foobar' }, expiresAt: new Date(new Date() / 2), user: {} }; } }); const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 }); const request = new Request({ body: { - code: 12345, + code: '12345', grant_type: 'authorization_code' }, headers: {}, @@ -822,7 +822,7 @@ describe('TokenHandler integration', function() { it('should return a token when code verifier is valid using S256 code challenge method', function() { const codeVerifier = stringUtil.base64URLEncode(crypto.randomBytes(32)); const authorizationCode = { - authorizationCode: 12345, + authorizationCode: '12345', client: { id: 'foobar' }, expiresAt: new Date(new Date().getTime() * 2), user: {}, @@ -841,7 +841,7 @@ describe('TokenHandler integration', function() { const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 }); const request = new Request({ body: { - code: 12345, + code: '12345', grant_type: 'authorization_code', code_verifier: codeVerifier }, @@ -860,7 +860,7 @@ describe('TokenHandler integration', function() { it('should return a token when code verifier is valid using plain code challenge method', function() { const codeVerifier = stringUtil.base64URLEncode(crypto.randomBytes(32)); const authorizationCode = { - authorizationCode: 12345, + authorizationCode: '12345', client: { id: 'foobar' }, expiresAt: new Date(new Date().getTime() * 2), user: {}, @@ -879,7 +879,7 @@ describe('TokenHandler integration', function() { const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 }); const request = new Request({ body: { - code: 12345, + code: '12345', grant_type: 'authorization_code', code_verifier: codeVerifier }, @@ -898,7 +898,7 @@ describe('TokenHandler integration', function() { it('should throw an invalid grant error when code verifier is invalid', function() { const codeVerifier = stringUtil.base64URLEncode(crypto.randomBytes(32)); const authorizationCode = { - authorizationCode: 12345, + authorizationCode: '12345', client: { id: 'foobar' }, expiresAt: new Date(new Date().getTime() * 2), user: {}, @@ -917,7 +917,7 @@ describe('TokenHandler integration', function() { const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 }); const request = new Request({ body: { - code: 12345, + code: '12345', grant_type: 'authorization_code', code_verifier: '123123123123123123123123123123123123123123123' }, @@ -937,7 +937,7 @@ describe('TokenHandler integration', function() { it('should throw an invalid grant error when code verifier is missing', function() { const codeVerifier = stringUtil.base64URLEncode(crypto.randomBytes(32)); const authorizationCode = { - authorizationCode: 12345, + authorizationCode: '12345', client: { id: 'foobar' }, expiresAt: new Date(new Date().getTime() * 2), user: {}, @@ -956,7 +956,7 @@ describe('TokenHandler integration', function() { const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 }); const request = new Request({ body: { - code: 12345, + code: '12345', grant_type: 'authorization_code' }, headers: {}, @@ -974,7 +974,7 @@ describe('TokenHandler integration', function() { it('should throw an invalid grant error when code verifier is present but code challenge is missing', function() { const authorizationCode = { - authorizationCode: 12345, + authorizationCode: '12345', client: { id: 'foobar' }, expiresAt: new Date(new Date().getTime() * 2), user: {} @@ -991,7 +991,7 @@ describe('TokenHandler integration', function() { const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 }); const request = new Request({ body: { - code: 12345, + code: '12345', grant_type: 'authorization_code', code_verifier: '123123123123123123123123123123123123123123123' }, @@ -1051,7 +1051,7 @@ describe('TokenHandler integration', function() { const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 }); const request = new Request({ body: { - client_id: 12345, + client_id: '12345', client_secret: 'secret', grant_type: 'password', password: 'bar', @@ -1085,7 +1085,7 @@ describe('TokenHandler integration', function() { const request = new Request({ body: { grant_type: 'refresh_token', - refresh_token: 12345 + refresh_token: '12345' }, headers: {}, method: {}, diff --git a/test/integration/server_test.js b/test/integration/server_test.js index f16aecce..88e51006 100644 --- a/test/integration/server_test.js +++ b/test/integration/server_test.js @@ -93,11 +93,11 @@ describe('Server integration', function() { return { grants: ['authorization_code'], redirectUris: ['http://example.com/cb'] }; }, saveAuthorizationCode: function() { - return { authorizationCode: 123 }; + return { authorizationCode: '123' }; } }); const server = new Server({ model: model }); - const request = new Request({ body: { client_id: 1234, client_secret: 'secret', response_type: 'code' }, headers: { 'Authorization': 'Bearer foo' }, method: {}, query: { state: 'foobar' } }); + const request = new Request({ body: { client_id: '1234', client_secret: 'secret', response_type: 'code' }, headers: { 'Authorization': 'Bearer foo' }, method: {}, query: { state: 'foobar' } }); const response = new Response({ body: {}, headers: {} }); try { @@ -121,11 +121,11 @@ describe('Server integration', function() { return { grants: ['authorization_code'], redirectUris: ['http://example.com/cb'] }; }, saveAuthorizationCode: function() { - return { authorizationCode: 123 }; + return { authorizationCode: '123' }; } }); const server = new Server({ model: model }); - const request = new Request({ body: { client_id: 1234, client_secret: 'secret', response_type: 'code' }, headers: { 'Authorization': 'Bearer foo' }, method: {}, query: { state: 'foobar' } }); + const request = new Request({ body: { client_id: '1234', client_secret: 'secret', response_type: 'code' }, headers: { 'Authorization': 'Bearer foo' }, method: {}, query: { state: 'foobar' } }); const response = new Response({ body: {}, headers: {} }); const handler = server.authorize(request, response); @@ -143,12 +143,12 @@ describe('Server integration', function() { return {}; }, saveToken: function() { - return { accessToken: 1234, client: {}, user: {} }; + return { accessToken: '1234', client: {}, user: {} }; }, validateScope: function() { return ['foo']; } }); const server = new Server({ model: model }); - const request = new Request({ body: { client_id: 1234, client_secret: 'secret', grant_type: 'password', username: 'foo', password: 'pass', scope: 'foo' }, headers: { 'content-type': 'application/x-www-form-urlencoded', 'transfer-encoding': 'chunked' }, method: 'POST', query: {} }); + const request = new Request({ body: { client_id: '1234', client_secret: 'secret', grant_type: 'password', username: 'foo', password: 'pass', scope: 'foo' }, headers: { 'content-type': 'application/x-www-form-urlencoded', 'transfer-encoding': 'chunked' }, method: 'POST', query: {} }); const response = new Response({ body: {}, headers: {} }); try { @@ -169,11 +169,11 @@ describe('Server integration', function() { return {}; }, saveToken: function() { - return { accessToken: 1234, client: {}, user: {} }; + return { accessToken: '1234', client: {}, user: {} }; } }); const server = new Server({ model: model }); - const request = new Request({ body: { client_id: 1234, client_secret: 'secret', grant_type: 'password', username: 'foo', password: 'pass' }, headers: { 'content-type': 'application/x-www-form-urlencoded', 'transfer-encoding': 'chunked' }, method: 'POST', query: {} }); + const request = new Request({ body: { client_id: '1234', client_secret: 'secret', grant_type: 'password', username: 'foo', password: 'pass' }, headers: { 'content-type': 'application/x-www-form-urlencoded', 'transfer-encoding': 'chunked' }, method: 'POST', query: {} }); const response = new Response({ body: {}, headers: {} }); const handler = server.token(request, response); diff --git a/test/unit/grant-types/authorization-code-grant-type_test.js b/test/unit/grant-types/authorization-code-grant-type_test.js index dd22b0f5..720f1d77 100644 --- a/test/unit/grant-types/authorization-code-grant-type_test.js +++ b/test/unit/grant-types/authorization-code-grant-type_test.js @@ -22,19 +22,19 @@ describe('AuthorizationCodeGrantType', function() { describe('getAuthorizationCode()', function() { it('should call `model.getAuthorizationCode()`', function() { const model = Model.from({ - getAuthorizationCode: sinon.stub().returns({ authorizationCode: 12345, client: {}, expiresAt: new Date(new Date() * 2), user: {} }), + getAuthorizationCode: sinon.stub().returns({ authorizationCode: '12345', client: {}, expiresAt: new Date(new Date() * 2), user: {} }), revokeAuthorizationCode: function() {}, saveToken: function() {} }); const handler = new AuthorizationCodeGrantType({ accessTokenLifetime: 120, model: model }); - const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345' }, headers: {}, method: {}, query: {} }); const client = {}; return handler.getAuthorizationCode(request, client) .then(function() { model.getAuthorizationCode.callCount.should.equal(1); model.getAuthorizationCode.firstCall.args.should.have.length(1); - model.getAuthorizationCode.firstCall.args[0].should.equal(12345); + model.getAuthorizationCode.firstCall.args[0].should.equal('12345'); model.getAuthorizationCode.firstCall.thisValue.should.equal(model); }) .catch(should.fail); @@ -96,7 +96,7 @@ describe('AuthorizationCodeGrantType', function() { it('should throw an error if the `code_verifier` is invalid with S256 code challenge method', function() { const codeVerifier = stringUtil.base64URLEncode(crypto.randomBytes(32)); const authorizationCode = { - authorizationCode: 12345, + authorizationCode: '12345', client: { id: 'foobar' }, expiresAt: new Date(new Date().getTime() * 2), user: {}, @@ -110,7 +110,7 @@ describe('AuthorizationCodeGrantType', function() { saveToken: function() {} }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345, code_verifier: 'foo' }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345', code_verifier: 'foo' }, headers: {}, method: {}, query: {} }); return grantType.getAuthorizationCode(request, client) .then(should.fail) @@ -123,7 +123,7 @@ describe('AuthorizationCodeGrantType', function() { it('should throw an error in getAuthorizationCode if an invalid code challenge method has been saved', function () { const codeVerifier = stringUtil.base64URLEncode(crypto.randomBytes(32)); const authorizationCode = { - authorizationCode: 12345, + authorizationCode: '12345', client: { id: 'foobar', isPublic: true }, expiresAt: new Date(new Date().getTime() * 2), user: {}, @@ -137,7 +137,7 @@ describe('AuthorizationCodeGrantType', function() { saveToken: function() {} }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345, code_verifier: codeVerifier }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345', code_verifier: codeVerifier }, headers: {}, method: {}, query: {} }); return grantType.getAuthorizationCode(request, client) .then(should.fail) @@ -150,7 +150,7 @@ describe('AuthorizationCodeGrantType', function() { it('should throw an error if the `code_verifier` is invalid with plain code challenge method', function() { const codeVerifier = stringUtil.base64URLEncode(crypto.randomBytes(32)); const authorizationCode = { - authorizationCode: 12345, + authorizationCode: '12345', client: { id: 'foobar' }, expiresAt: new Date(new Date().getTime() * 2), user: {}, @@ -165,7 +165,7 @@ describe('AuthorizationCodeGrantType', function() { saveToken: function() {} }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345, code_verifier: 'foo' }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345', code_verifier: 'foo' }, headers: {}, method: {}, query: {} }); return grantType.getAuthorizationCode(request, client) .then(should.fail) @@ -178,7 +178,7 @@ describe('AuthorizationCodeGrantType', function() { it('should return an auth code when `code_verifier` is valid with S256 code challenge method', function() { const codeVerifier = stringUtil.base64URLEncode(crypto.randomBytes(32)); const authorizationCode = { - authorizationCode: 12345, + authorizationCode: '12345', client: { id: 'foobar', isPublic: true }, expiresAt: new Date(new Date().getTime() * 2), user: {}, @@ -192,7 +192,7 @@ describe('AuthorizationCodeGrantType', function() { saveToken: function() {} }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345, code_verifier: codeVerifier }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345', code_verifier: codeVerifier }, headers: {}, method: {}, query: {} }); return grantType.getAuthorizationCode(request, client) .then(function(data) { @@ -204,7 +204,7 @@ describe('AuthorizationCodeGrantType', function() { it('should return an auth code when `code_verifier` is valid with plain code challenge method', function() { const codeVerifier = stringUtil.base64URLEncode(crypto.randomBytes(32)); const authorizationCode = { - authorizationCode: 12345, + authorizationCode: '12345', client: { id: 'foobar' }, expiresAt: new Date(new Date().getTime() * 2), user: {}, @@ -218,7 +218,7 @@ describe('AuthorizationCodeGrantType', function() { saveToken: function() {} }); const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model }); - const request = new Request({ body: { code: 12345, code_verifier: codeVerifier }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { code: '12345', code_verifier: codeVerifier }, headers: {}, method: {}, query: {} }); return grantType.getAuthorizationCode(request, client) .then(function(data) { diff --git a/test/unit/handlers/authorize-handler_test.js b/test/unit/handlers/authorize-handler_test.js index b539e480..95798aa1 100644 --- a/test/unit/handlers/authorize-handler_test.js +++ b/test/unit/handlers/authorize-handler_test.js @@ -43,13 +43,13 @@ describe('AuthorizeHandler', function() { saveAuthorizationCode: function() {} }); const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model }); - const request = new Request({ body: { client_id: 12345, client_secret: 'secret' }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { client_id: '12345', client_secret: 'secret' }, headers: {}, method: {}, query: {} }); return handler.getClient(request) .then(function() { model.getClient.callCount.should.equal(1); model.getClient.firstCall.args.should.have.length(2); - model.getClient.firstCall.args[0].should.equal(12345); + model.getClient.firstCall.args[0].should.equal('12345'); model.getClient.firstCall.thisValue.should.equal(model); }) .catch(should.fail); @@ -131,13 +131,13 @@ describe('AuthorizeHandler', function() { validateRedirectUri: sinon.stub().returns(true) }); const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model }); - const request = new Request({ body: { client_id: 12345, client_secret: 'secret', redirect_uri }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { client_id: '12345', client_secret: 'secret', redirect_uri }, headers: {}, method: {}, query: {} }); return handler.getClient(request) .then(function() { model.getClient.callCount.should.equal(1); model.getClient.firstCall.args.should.have.length(2); - model.getClient.firstCall.args[0].should.equal(12345); + model.getClient.firstCall.args[0].should.equal('12345'); model.getClient.firstCall.thisValue.should.equal(model); model.validateRedirectUri.callCount.should.equal(1); @@ -162,7 +162,7 @@ describe('AuthorizeHandler', function() { }); const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model }); - const request = new Request({ body: { client_id: 12345, client_secret: 'secret', redirect_uri }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { client_id: '12345', client_secret: 'secret', redirect_uri }, headers: {}, method: {}, query: {} }); return handler.getClient(request) .then((client) => { @@ -183,7 +183,7 @@ describe('AuthorizeHandler', function() { }); const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model }); - const request = new Request({ body: { client_id: 12345, client_secret: 'secret', redirect_uri }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { client_id: '12345', client_secret: 'secret', redirect_uri }, headers: {}, method: {}, query: {} }); return handler.getClient(request) .then(() => { diff --git a/test/unit/handlers/token-handler_test.js b/test/unit/handlers/token-handler_test.js index a16be32d..80d3b97f 100644 --- a/test/unit/handlers/token-handler_test.js +++ b/test/unit/handlers/token-handler_test.js @@ -22,13 +22,13 @@ describe('TokenHandler', function() { saveToken: function() {} }); const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 }); - const request = new Request({ body: { client_id: 12345, client_secret: 'secret' }, headers: {}, method: {}, query: {} }); + const request = new Request({ body: { client_id: '12345', client_secret: 'secret' }, headers: {}, method: {}, query: {} }); return handler.getClient(request) .then(function() { model.getClient.callCount.should.equal(1); model.getClient.firstCall.args.should.have.length(2); - model.getClient.firstCall.args[0].should.equal(12345); + model.getClient.firstCall.args[0].should.equal('12345'); model.getClient.firstCall.args[1].should.equal('secret'); model.getClient.firstCall.thisValue.should.equal(model); })