Opey II integration WIP: Add test

This commit is contained in:
nemo 2025-01-30 11:01:55 +00:00
parent 0feb271e23
commit 7893183585
8 changed files with 601 additions and 16 deletions

View File

@ -0,0 +1,133 @@
import { streamText } from 'ai'
import axios from 'axios'
import { Controller, Session, Req, Res, Post } from 'routing-controllers'
import { Request, Response } from 'express'
import { Service } from 'typedi'
import OBPClientService from '../services/OBPClientService'
import OpeyClientService from '../services/OpeyClientService'
import { v6 as uuid6 } from 'uuid';
import { UserInput } from '../schema/OpeySchema'
@Service()
@Controller('/opey')
export class OpeyController {
constructor(
private obpClientService: OBPClientService,
private opeyClientService: OpeyClientService,
) {}
@Post('/consent')
/**
* Retrieves a consent from OBP for the current user
*/
async getConsent(
@Session() session: any,
@Req() request: Request,
@Res() response: Response
): Response {
try {
console.log("Getting consent from OBP")
// Check if consent is already in session
if (session['obpConsent']) {
console.log("Consent found in session, returning cached consent ID")
const obpConsent = session['obpConsent']
// NOTE: Arguably we should not return the consent to the frontend as it could be hijacked,
// we can keep everything in the backend and only return the JWT token
return response.status(200).json({consent_id: obpConsent.consent_id});
}
const oauthConfig = session['clientConfig']
const version = this.obpClientService.getOBPVersion()
// Obbiously this should not be hard-coded, especially the consumer_id, but for now it is
const consentRequestBody = {
"everything": false,
"views": [],
"entitlements": [],
"consumer_id": "33e0a1bd-9f1d-4128-911b-8936110f802f"
}
// Get current user, only proceed if user is logged in
const currentUser = await this.obpClientService.get(`/obp/${version}/users/current`, oauthConfig)
const currentResponseKeys = Object.keys(currentUser)
if (!currentResponseKeys.includes('user_id')) {
return response.status(400).json({ message: 'User not logged in, Authentication required' });
}
// url needs to be changed once we get the 'bankless' consent endpoint
// this creates a consent for the current logged in user, and starts SCA flow i.e. sends SMS or email OTP to user
const consent = await this.obpClientService.create(`/obp/${version}/banks/gh.29.uk/my/consents/IMPLICIT`, consentRequestBody, oauthConfig)
console.log("Consent: ", consent)
// store consent in session, return consent 200 OK
session['obpConsent'] = consent
return response.status(200).json({consent_id: consent.consent_id});
} catch (error) {
console.error("Error in consent endpoint: ", error);
return response.status(500).json({ error: 'Internal Server Error '});
}
}
@Post('/consent/answer-challenge')
/**
* Endpoint to answer the consent challenge with code i.e. SMS or email OTP for SCA
* If successful, returns a Consent-JWT for use by Opey to access endpoints/ roles that the consenting user has
* This completes (i.e. is the final step in) the consent flow
*/
async answerConsentChallenge(
@Session() session: any,
@Req() request: Request,
@Res() response: Response
): Response {
try {
const oauthConfig = session['clientConfig']
const version = this.obpClientService.getOBPVersion()
const obpConsent = session['obpConsent']
if (!obpConsent) {
return response.status(400).json({ message: 'Consent not found in session' });
} else if (obpConsent.status === 'ACCEPTED') {
return response.status(400).json({ message: 'Consent already accepted' });
}
const answerBody = request.body
const consentJWT = await this.obpClientService.create(`/obp/${version}/banks/gh.29.uk/consents/${obpConsent.consent_id}/challenge`, answerBody, oauthConfig)
console.log("Consent JWT: ", consentJWT)
// store consent JWT in session, return consent JWT 200 OK
session['obpConsentJWT'] = consentJWT
return response.status(200).json(true);
} catch (error) {
console.error("Error in consent/answer-challenge endpoint: ", error);
return response.status(500).json({ error: 'Internal Server Error' });
}
}
@Post('/stream')
async streamOpey(
@Session() session: any,
@Req() request: Request,
@Res() response: Response
) {
const messages = await request.json()
console.log(messages)
const user_input: UserInput = {
"message": messages[-1],
"thread_id": uuid6(),
"is_tool_call_approval": false
}
const stream = await this.opeyClientService.stream(user_input)
stream.on('data', (chunk)=>{
console.log(chunk)
})
}
}

View File

@ -0,0 +1,6 @@
export class UserInput {
message: string;
thread_id?: string | null;
is_tool_call_approval: boolean;
}

View File

@ -0,0 +1,54 @@
import { Service } from 'typedi'
import axios from 'axios'
import { UserInput } from '../schema/OpeySchema'
@Service()
export default class OpeyClientService {
private AuthConfig: {
consentId: string,
opeyJWT: string,
}
private opeyConfig: {
baseUri: string,
authConfig: any,
paths: {
stream: string,
invoke: string,
approve_tool: string,
feedback: string,
}
}
constuctor() {
this.AuthConfig = {
consentId: '',
opeyJWT: ''
}
this.opeyConfig = {
baseUri: process.env.VITE_CHATBOT_URL,
authConfig: this.AuthConfig,
paths: {
stream: '/stream',
invoke: '/invoke',
approve_tool: '/approve_tool/{thead_id}',
feedback: '/feedback',
}
}
}
async stream(user_input: UserInput) {
await axios.post(this.opeyConfig.paths.stream, user_input, {
headers: {
"Authorization": `Bearer ${this.opeyConfig.authConfig.opeyJWT}`
},
responseType: 'stream'
}).catch((error) => {
console.error(error)
}).then((response) => {
const stream = response.data
return stream
})
}
}

View File

@ -73,13 +73,14 @@
const { isConnected } = storeToRefs(connectionStore);
return {isStreaming, chatMessages, lastError, currentMessageSnapshot, chatStore, connectionStore, isConnected}
return {isStreaming, chatMessages, lastError, currentMessageSnapshot, chatStore, connectionStore}
},
data() {
return {
isOpen: false,
userInput: '',
sessionId: uuidv4(),
isConnected: false,
awaitingConnection: !this.isConnected,
awaitingConsentChallengeAnswer: false,
consentChallengeAnswer: '',
@ -121,6 +122,9 @@
async establishWebSocketConnection() {
// Get the Opey JWT token
// try to get a consent token
// Check if the user already has a token in the cookies
try {
const consentResponse = await getOpeyConsent()
console.log('Consent response: ', consentResponse)
@ -175,6 +179,12 @@
if (response.status === 200) {
console.log('Consent challenge answered successfully, Consent approved')
this.awaitingConsentChallengeAnswer = false
if (response.data.success) {
console.log('Consent approved')
this.isConnected = true
} else {
console.log('Consent denied')
}
}
} catch (error) {

View File

@ -1,3 +1,13 @@
<!--
placeholder for Opey II Chat widget
-->
-->
<script setup>
import { useChat } from '@ai-sdk/vue'
const { messages, input, handleInputChange, handleSubmit, addToolResult } = useChat
</script>
<template>
</template>

View File

@ -86,14 +86,16 @@ export async function getOpeyJWT() {
}
export async function getOpeyConsent() {
const response = await axios.post('/api/opey/consent').catch((error) => {
await axios.post('/api/opey/consent').catch((error) => {
if (error.response) {
throw new Error(`getOpeyConsent returned an error: ${error.toJSON()}`);
} else {
throw new Error(`getOpeyConsent returned an error: ${error.message}`);
}
}).then((response) => {
console.log(response)
return response
});
return response
}
export async function answerOpeyConsentChallenge(answerBody: any) {

41
test/opey.test.ts Normal file
View File

@ -0,0 +1,41 @@
import { beforeAll, describe, afterAll, it, expect, expectTypeOf, test } from 'vitest';
import { OpeyController } from "../server/controllers/OpeyController";
import app from '../server/app';
import { UserInput } from '../server/schema/OpeySchema';
import { v6 as uuid6 } from 'uuid';
const BEFORE_ALL_TIMEOUT = 30000; // 30 sec
let server;
beforeAll(() => {
// Start the Express app on a test port
server = app.listen(3000);
});
afterAll(() => {
// Close the server after tests
server.close();
});
describe('POST /api/opey/stream', () => {
let response: Response;
it('Should return 200', async () => {
let userInput: UserInput = {
message: "Hello Opey",
is_tool_call_approval: false
}
const response = await fetch("http://localhost:3000/api/opey/stream", {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(userInput)
});
expect(response.status).toBe(200);
});
});

353
yarn.lock
View File

@ -2,6 +2,51 @@
# yarn lockfile v1
"@ai-sdk/provider-utils@2.1.5":
version "2.1.5"
resolved "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-2.1.5.tgz"
integrity sha512-PcNR7E4ovZGV/J47gUqaFlvzorgca6uUfN5WzfXJSFWeOeLunN+oxRVwgUOwj0zbmO0yGQTHQD+FHVw8s3Rz8w==
dependencies:
"@ai-sdk/provider" "1.0.6"
eventsource-parser "^3.0.0"
nanoid "^3.3.8"
secure-json-parse "^2.7.0"
"@ai-sdk/provider@1.0.6":
version "1.0.6"
resolved "https://registry.npmjs.org/@ai-sdk/provider/-/provider-1.0.6.tgz"
integrity sha512-hwj/gFNxpDgEfTaYzCYoslmw01IY9kWLKl/wf8xuPvHtQIzlfXWmmUwc8PnCwxyt8cKzIuV0dfUghCf68HQ0SA==
dependencies:
json-schema "^0.4.0"
"@ai-sdk/react@1.1.6":
version "1.1.6"
resolved "https://registry.npmjs.org/@ai-sdk/react/-/react-1.1.6.tgz"
integrity sha512-kP5pimLyNWldw8+0j3ym+AACFEXcQHdELNtk45wDJA3HoH486x/zffdn7yLc3c1DOu5apew+COl8CNL4A+2E4g==
dependencies:
"@ai-sdk/provider-utils" "2.1.5"
"@ai-sdk/ui-utils" "1.1.6"
swr "^2.2.5"
throttleit "2.1.0"
"@ai-sdk/ui-utils@1.1.6":
version "1.1.6"
resolved "https://registry.npmjs.org/@ai-sdk/ui-utils/-/ui-utils-1.1.6.tgz"
integrity sha512-YAwZhFwpIcvWERIjkET2o2MAwMFfJG18WdtcIjtxxMW7hA0bt5cliOV78DVcwRrxqJ2IKBlxaFmwUjW6M4SdOQ==
dependencies:
"@ai-sdk/provider" "1.0.6"
"@ai-sdk/provider-utils" "2.1.5"
zod-to-json-schema "^3.24.1"
"@ai-sdk/vue@^1.1.6":
version "1.1.6"
resolved "https://registry.npmjs.org/@ai-sdk/vue/-/vue-1.1.6.tgz"
integrity sha512-lo9WslJn/E52qHrmQj2PM74LBpzctqjHg94gQOz4YdlQLsCDG5BmD4o3dnRm1yKfYQZkB31XYTfOComo9gki2Q==
dependencies:
"@ai-sdk/provider-utils" "2.1.5"
"@ai-sdk/ui-utils" "1.1.6"
swrv "^1.0.4"
"@ampproject/remapping@^2.2.0", "@ampproject/remapping@^2.3.0":
version "2.3.0"
resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz"
@ -698,6 +743,11 @@
resolved "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz"
integrity sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==
"@opentelemetry/api@1.9.0":
version "1.9.0"
resolved "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz"
integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==
"@pkgjs/parseargs@^0.11.0":
version "0.11.0"
resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz"
@ -834,6 +884,11 @@
dependencies:
"@types/node" "*"
"@types/diff-match-patch@^1.0.36":
version "1.0.36"
resolved "https://registry.npmjs.org/@types/diff-match-patch/-/diff-match-patch-1.0.36.tgz"
integrity sha512-xFdR6tkm0MWvBfO8xXCSsinYxHcqkQUlcHeSpMC2ukzOb6lwQAfDmW+Qt0AvlGd8HpsS28qKsB+oPeJn9I39jg==
"@types/estree@^1.0.0", "@types/estree@^1.0.5", "@types/estree@^1.0.6":
version "1.0.6"
resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz"
@ -1306,6 +1361,18 @@ agent-base@^7.1.0, agent-base@^7.1.2:
resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz"
integrity sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==
ai@^4.1.9:
version "4.1.9"
resolved "https://registry.npmjs.org/ai/-/ai-4.1.9.tgz"
integrity sha512-EUc21jyV/2Fv0hEd4toLxQMxjTXBWjKnw16tpto12Vrg/EvkmfVSEvtwXDa+J70iPDmASxL10VKmJk/wnb6bZA==
dependencies:
"@ai-sdk/provider" "1.0.6"
"@ai-sdk/provider-utils" "2.1.5"
"@ai-sdk/react" "1.1.6"
"@ai-sdk/ui-utils" "1.1.6"
"@opentelemetry/api" "1.9.0"
jsondiffpatch "0.6.0"
ajv@^6.12.4:
version "6.12.6"
resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz"
@ -1331,6 +1398,11 @@ alien-signals@^0.4.9:
resolved "https://registry.npmjs.org/alien-signals/-/alien-signals-0.4.14.tgz"
integrity sha512-itUAVzhczTmP2U5yX67xVpsbbOiquusbWVyA9N+sy6+r6YVbFkahXvNCeEPWEOMhwDYwbVbGHFkVL03N9I5g+Q==
ansi-colors@^4.1.3:
version "4.1.3"
resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz"
integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==
ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz"
@ -1572,6 +1644,11 @@ browser-resolve@^2.0.0:
dependencies:
resolve "^1.17.0"
browser-stdout@^1.3.1:
version "1.3.1"
resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz"
integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
browserify-aes@^1.0.0, browserify-aes@^1.0.4:
version "1.2.0"
resolved "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz"
@ -1733,6 +1810,11 @@ callsites@^3.0.0:
resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz"
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
camelcase@^6.0.0:
version "6.3.0"
resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz"
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
caniuse-lite@^1.0.30001669:
version "1.0.30001683"
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001683.tgz"
@ -1751,7 +1833,7 @@ chai@^4.3.10:
pathval "^1.1.1"
type-detect "^4.1.0"
chalk@^4.0.0:
chalk@^4.0.0, chalk@^4.1.0:
version "4.1.2"
resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
@ -1759,6 +1841,11 @@ chalk@^4.0.0:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
chalk@^5.3.0:
version "5.4.1"
resolved "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz"
integrity sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==
check-error@^1.0.3:
version "1.0.3"
resolved "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz"
@ -1795,7 +1882,7 @@ cheerio@^1.0.0:
undici "^6.19.5"
whatwg-mimetype "^4.0.0"
chokidar@^3.6.0:
chokidar@^3.5.3, chokidar@^3.6.0:
version "3.6.0"
resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz"
integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==
@ -1832,6 +1919,15 @@ class-validator@^0.14.0:
libphonenumber-js "^1.10.14"
validator "^13.7.0"
cliui@^8.0.1:
version "8.0.1"
resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz"
integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==
dependencies:
string-width "^4.2.0"
strip-ansi "^6.0.1"
wrap-ansi "^7.0.0"
clsx@^2.1.1:
version "2.1.1"
resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz"
@ -2148,6 +2244,13 @@ debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3
dependencies:
ms "2.1.2"
debug@^4.3.5:
version "4.4.0"
resolved "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz"
integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==
dependencies:
ms "^2.1.3"
debug@^4.3.7:
version "4.4.0"
resolved "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz"
@ -2169,6 +2272,11 @@ debug@2.6.9:
dependencies:
ms "2.0.0"
decamelize@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz"
integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==
decimal.js@^10.4.3:
version "10.4.3"
resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz"
@ -2219,6 +2327,11 @@ depd@~1.1.2:
resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz"
integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==
dequal@^2.0.3:
version "2.0.3"
resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz"
integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==
des.js@^1.0.0:
version "1.1.0"
resolved "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz"
@ -2240,6 +2353,11 @@ dezalgo@^1.0.4:
asap "^2.0.0"
wrappy "1"
diff-match-patch@^1.0.5:
version "1.0.5"
resolved "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz"
integrity sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==
diff-sequences@^29.4.3, diff-sequences@^29.6.3:
version "29.6.3"
resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz"
@ -2250,6 +2368,11 @@ diff@^4.0.1:
resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
diff@^5.2.0:
version "5.2.0"
resolved "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz"
integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==
diffie-hellman@^5.0.0:
version "5.0.3"
resolved "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz"
@ -2532,7 +2655,7 @@ esbuild@^0.18.10:
"@esbuild/win32-ia32" "0.18.20"
"@esbuild/win32-x64" "0.18.20"
escalade@^3.2.0:
escalade@^3.1.1, escalade@^3.2.0:
version "3.2.0"
resolved "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz"
integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==
@ -2721,6 +2844,11 @@ events@^3.0.0:
resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
eventsource-parser@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.0.tgz"
integrity sha512-T1C0XCUimhxVQzW4zFipdx0SficT651NnkR0ZSH3yQwh+mFMdLfgjABVi4YtMTtaL4s168593DaoaRLMqryavA==
evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
version "1.0.3"
resolved "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz"
@ -2880,6 +3008,11 @@ flat-cache@^4.0.0:
flatted "^3.2.9"
keyv "^4.5.4"
flat@^5.0.2:
version "5.0.2"
resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz"
integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==
flatted@^3.2.9:
version "3.3.2"
resolved "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz"
@ -2958,6 +3091,11 @@ gensync@^1.0.0-beta.2:
resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz"
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
get-caller-file@^2.0.5:
version "2.0.5"
resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
get-func-name@^2.0.0, get-func-name@^2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz"
@ -3008,7 +3146,7 @@ glob-parent@~5.1.2:
dependencies:
is-glob "^4.0.1"
glob@^10.2.2, glob@^10.3.3:
glob@^10.2.2, glob@^10.3.3, glob@^10.4.5:
version "10.4.5"
resolved "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz"
integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==
@ -3359,6 +3497,11 @@ is-number@^7.0.0:
resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
is-plain-obj@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz"
integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
is-potential-custom-element-name@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz"
@ -3382,6 +3525,11 @@ is-typed-array@^1.1.10, is-typed-array@^1.1.3:
gopd "^1.0.1"
has-tostringtag "^1.0.0"
is-unicode-supported@^0.1.0:
version "0.1.0"
resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz"
integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==
isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
@ -3519,6 +3667,11 @@ json-schema-traverse@^1.0.0:
resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz"
integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
json-schema@^0.4.0:
version "0.4.0"
resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-source-map@^0.6.1:
version "0.6.1"
resolved "https://registry.npmjs.org/json-source-map/-/json-source-map-0.6.1.tgz"
@ -3534,6 +3687,15 @@ json5@^2.2.3:
resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
jsondiffpatch@0.6.0:
version "0.6.0"
resolved "https://registry.npmjs.org/jsondiffpatch/-/jsondiffpatch-0.6.0.tgz"
integrity sha512-3QItJOXp2AP1uv7waBkao5nCvhEv+QmJAd38Ybq7wNI74Q+BBmnLn4EDKz6yI9xGAIQoUF87qHt+kc1IVxB4zQ==
dependencies:
"@types/diff-match-patch" "^1.0.36"
chalk "^5.3.0"
diff-match-patch "^1.0.5"
"jsonpath-plus@^9.0.0 || ^10.2.0":
version "10.2.0"
resolved "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.2.0.tgz"
@ -3745,6 +3907,14 @@ lodash@*, lodash@^4.17.21:
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
log-symbols@^4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz"
integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==
dependencies:
chalk "^4.1.0"
is-unicode-supported "^0.1.0"
loupe@^2.3.6:
version "2.3.6"
resolved "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz"
@ -3918,6 +4088,13 @@ minimatch@^3.1.2:
dependencies:
brace-expansion "^1.1.7"
minimatch@^5.1.6:
version "5.1.6"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz"
integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
dependencies:
brace-expansion "^2.0.1"
minimatch@^9.0.0, minimatch@^9.0.3, minimatch@^9.0.4, minimatch@^9.0.5:
version "9.0.5"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz"
@ -3959,6 +4136,32 @@ mlly@^1.4.0, mlly@^1.7.2, mlly@^1.7.3:
pkg-types "^1.2.1"
ufo "^1.5.4"
mocha@^11.1.0:
version "11.1.0"
resolved "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz"
integrity sha512-8uJR5RTC2NgpY3GrYcgpZrsEd9zKbPDpob1RezyR2upGHRQtHWofmzTMzTMSV6dru3tj5Ukt0+Vnq1qhFEEwAg==
dependencies:
ansi-colors "^4.1.3"
browser-stdout "^1.3.1"
chokidar "^3.5.3"
debug "^4.3.5"
diff "^5.2.0"
escape-string-regexp "^4.0.0"
find-up "^5.0.0"
glob "^10.4.5"
he "^1.2.0"
js-yaml "^4.1.0"
log-symbols "^4.1.0"
minimatch "^5.1.6"
ms "^2.1.3"
serialize-javascript "^6.0.2"
strip-json-comments "^3.1.1"
supports-color "^8.1.1"
workerpool "^6.5.1"
yargs "^17.7.2"
yargs-parser "^21.1.1"
yargs-unparser "^2.0.0"
ms@^2.1.1, ms@2.1.2:
version "2.1.2"
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
@ -3997,10 +4200,10 @@ multer@*, multer@^1.4.5-lts.1:
type-is "^1.6.4"
xtend "^4.0.0"
nanoid@^3.3.7:
version "3.3.7"
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz"
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
nanoid@^3.3.7, nanoid@^3.3.8:
version "3.3.8"
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz"
integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==
natural-compare-lite@^1.4.0:
version "1.4.0"
@ -4511,7 +4714,7 @@ random-bytes@~1.0.0:
resolved "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz"
integrity sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz"
integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
@ -4546,6 +4749,11 @@ react-is@^18.0.0:
resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz"
integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==
"react@^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^18 || ^19 || ^19.0.0-rc":
version "19.0.0"
resolved "https://registry.npmjs.org/react/-/react-19.0.0.tgz"
integrity sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==
read-package-json-fast@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-4.0.0.tgz"
@ -4609,6 +4817,11 @@ reflect-metadata@^0.1.13:
resolved "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz"
integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==
require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz"
integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
require-from-string@^2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz"
@ -4716,6 +4929,11 @@ scule@^1.3.0:
resolved "https://registry.npmjs.org/scule/-/scule-1.3.0.tgz"
integrity sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==
secure-json-parse@^2.7.0:
version "2.7.0"
resolved "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz"
integrity sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==
semver@^6.3.1:
version "6.3.1"
resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
@ -4774,6 +4992,13 @@ send@0.19.0:
range-parser "~1.2.1"
statuses "2.0.1"
serialize-javascript@^6.0.2:
version "6.0.2"
resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz"
integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==
dependencies:
randombytes "^2.1.0"
serve-static@1.16.2:
version "1.16.2"
resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz"
@ -4998,7 +5223,16 @@ string_decoder@^1.0.0, string_decoder@^1.1.1, string_decoder@~1.1.1:
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
string-width@^4.1.0:
string-width@^4.1.0, string-width@^4.2.0:
version "4.2.3"
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@ -5077,7 +5311,7 @@ superagent@^8.0.9:
qs "^6.11.0"
semver "^7.3.8"
superagent@^9.0.0:
superagent@^9.0.0, superagent@^9.0.1:
version "9.0.2"
resolved "https://registry.npmjs.org/superagent/-/superagent-9.0.2.tgz"
integrity sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w==
@ -5092,6 +5326,14 @@ superagent@^9.0.0:
mime "2.6.0"
qs "^6.11.0"
supertest@^7.0.0:
version "7.0.0"
resolved "https://registry.npmjs.org/supertest/-/supertest-7.0.0.tgz"
integrity sha512-qlsr7fIC0lSddmA3tzojvzubYxvlGtzumcdHgPwbFWMISQwL22MhM2Y3LNt+6w9Yyx7559VW5ab70dgphm8qQA==
dependencies:
methods "^1.1.2"
superagent "^9.0.1"
supports-color@^7.1.0:
version "7.2.0"
resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz"
@ -5099,6 +5341,13 @@ supports-color@^7.1.0:
dependencies:
has-flag "^4.0.0"
supports-color@^8.1.1:
version "8.1.1"
resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz"
integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
dependencies:
has-flag "^4.0.0"
supports-preserve-symlinks-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
@ -5129,6 +5378,19 @@ svg-tags@^1.0.0:
resolved "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz"
integrity sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==
swr@^2.2.5:
version "2.3.0"
resolved "https://registry.npmjs.org/swr/-/swr-2.3.0.tgz"
integrity sha512-NyZ76wA4yElZWBHzSgEJc28a0u6QZvhb6w0azeL2k7+Q1gAzVK+IqQYXhVOC/mzi+HZIozrZvBVeSeOZNR2bqA==
dependencies:
dequal "^2.0.3"
use-sync-external-store "^1.4.0"
swrv@^1.0.4:
version "1.0.4"
resolved "https://registry.npmjs.org/swrv/-/swrv-1.0.4.tgz"
integrity sha512-zjEkcP8Ywmj+xOJW3lIT65ciY/4AL4e/Or7Gj0MzU3zBJNMdJiT8geVZhINavnlHRMMCcJLHhraLTAiDOTmQ9g==
symbol-tree@^3.2.4:
version "3.2.4"
resolved "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz"
@ -5147,6 +5409,11 @@ template-url@^1.0.0:
resolved "https://registry.npmjs.org/template-url/-/template-url-1.0.0.tgz"
integrity sha512-QUjZNE7yTdIzB91sITTSYcSX5GRF5FulKvIYCqV5350NfSNfiuuCYQIJZ5PIN7k/uJ+kpurEEv9hFqRRc+JilA==
throttleit@2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/throttleit/-/throttleit-2.1.0.tgz"
integrity sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==
timers-browserify@^2.0.4:
version "2.0.12"
resolved "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz"
@ -5422,6 +5689,11 @@ url@^0.11.0:
punycode "1.3.2"
querystring "0.2.0"
use-sync-external-store@^1.4.0:
version "1.4.0"
resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz"
integrity sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==
util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
@ -5641,7 +5913,7 @@ vue-tsc@^2.0.0:
"@volar/typescript" "~2.4.11"
"@vue/language-core" "2.2.0"
"vue@^2.6.14 || ^3.5.11", vue@^3, vue@^3.0.0, "vue@^3.0.0-0 || ^2.6.0", vue@^3.2.0, vue@^3.2.25, vue@^3.5.1, "vue@2 || 3", vue@2||3, vue@3.5.13:
"vue@^2.6.14 || ^3.5.11", vue@^3, vue@^3.0.0, "vue@^3.0.0-0 || ^2.6.0", vue@^3.2.0, vue@^3.2.25, vue@^3.3.4, vue@^3.5.1, "vue@>=3.2.26 < 4", "vue@2 || 3", vue@2||3, vue@3.5.13:
version "3.5.13"
resolved "https://registry.npmjs.org/vue/-/vue-3.5.13.tgz"
integrity sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==
@ -5733,6 +6005,11 @@ word-wrap@^1.2.5:
resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz"
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
workerpool@^6.5.1:
version "6.5.1"
resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz"
integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
version "7.0.0"
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"
@ -5742,6 +6019,15 @@ word-wrap@^1.2.5:
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz"
@ -5801,6 +6087,11 @@ xtend@^4.0.0, xtend@^4.0.2:
resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
y18n@^5.0.5:
version "5.0.8"
resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz"
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
yallist@^3.0.2:
version "3.1.1"
resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz"
@ -5816,6 +6107,34 @@ yallist@4.0.0:
resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yargs-parser@^21.1.1:
version "21.1.1"
resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz"
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
yargs-unparser@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz"
integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==
dependencies:
camelcase "^6.0.0"
decamelize "^4.0.0"
flat "^5.0.2"
is-plain-obj "^2.1.0"
yargs@^17.7.2:
version "17.7.2"
resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz"
integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
dependencies:
cliui "^8.0.1"
escalade "^3.1.1"
get-caller-file "^2.0.5"
require-directory "^2.1.1"
string-width "^4.2.3"
y18n "^5.0.5"
yargs-parser "^21.1.1"
yeast@0.1.2:
version "0.1.2"
resolved "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz"
@ -5845,3 +6164,13 @@ zimmerframe@^1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.2.tgz"
integrity sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==
zod-to-json-schema@^3.24.1:
version "3.24.1"
resolved "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.1.tgz"
integrity sha512-3h08nf3Vw3Wl3PK+q3ow/lIil81IT2Oa7YpQyUUDsEWbXveMesdfK1xBd2RhCkynwZndAxixji/7SYJJowr62w==
zod@^3.0.0, zod@^3.24.1:
version "3.24.1"
resolved "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz"
integrity sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==