diff --git a/.gitignore b/.gitignore index 45f70470..98285231 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ # Dependencies node_modules/ +# Build output +dist/ + # Logs logs *.log diff --git a/mcp-server/Dockerfile b/mcp-server/Dockerfile new file mode 100644 index 00000000..86cfd0f7 --- /dev/null +++ b/mcp-server/Dockerfile @@ -0,0 +1,78 @@ +# Dockerfile for Umaaas MCP Server +# +# This Dockerfile builds a Docker image for the MCP Server. +# +# To build the image locally: +# docker build -f packages/mcp-server/Dockerfile -t umaaas_mcp:local . +# +# To run the image: +# docker run -i umaaas_mcp:local [OPTIONS] +# +# Common options: +# --tool= Include specific tools +# --resource= Include tools for specific resources +# --operation=read|write Filter by operation type +# --client= Set client compatibility (e.g., claude, cursor) +# --transport= Set transport type (stdio or http) +# +# For a full list of options: +# docker run -i umaaas_mcp:local --help +# +# Note: The MCP server uses stdio transport by default. Docker's -i flag +# enables interactive mode, allowing the container to communicate over stdin/stdout. + +# Build stage +FROM node:24-alpine AS builder + +# Install bash for build script +RUN apk add --no-cache bash openssl + +# Set working directory +WORKDIR /build + +# Copy entire repository +COPY . . + +# Install all dependencies and build everything +RUN yarn install --frozen-lockfile && \ + yarn build && \ + # Remove the symlink to the SDK so it doesn't interfere with the explicit COPY below + rm -Rf packages/mcp-server/node_modules/umaaas + +FROM denoland/deno:alpine-2.7.1 + +# Install node and npm +RUN apk add --no-cache nodejs npm + +ENV LD_LIBRARY_PATH=/usr/lib:/usr/local/lib + +# Add non-root user +RUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001 + +# Set working directory +WORKDIR /app + +# Copy the built mcp-server dist directory +COPY --from=builder /build/packages/mcp-server/dist ./ + +# Copy node_modules from mcp-server (includes all production deps) +COPY --from=builder /build/packages/mcp-server/node_modules ./node_modules + +# Copy the built umaaas into node_modules +COPY --from=builder /build/dist ./node_modules/umaaas + +# Change ownership to nodejs user +RUN chown -R nodejs:nodejs /app +RUN chown -R nodejs:nodejs /deno-dir + +# Switch to non-root user +USER nodejs + +# The MCP server uses stdio transport by default +# No exposed ports needed for stdio communication + +# Set the entrypoint to the MCP server +ENTRYPOINT ["node", "index.js"] + +# Allow passing arguments to the MCP server +CMD [] diff --git a/mcp-server/README.md b/mcp-server/README.md new file mode 100644 index 00000000..4b13a064 --- /dev/null +++ b/mcp-server/README.md @@ -0,0 +1,96 @@ +# Umaaas TypeScript MCP Server + +It is generated with [Stainless](https://www.stainless.com/). + +## Installation + +### Building + +Because it's not published yet, clone the repo and build it: + +```sh +git clone git@github.com:stainless-sdks/umaaas-typescript.git +cd umaaas-typescript +./scripts/bootstrap +./scripts/build +``` + +### Running + +```sh +# set env vars as needed +export UMAAAS_CLIENT_ID="My Username" +export UMAAAS_CLIENT_SECRET="My Password" +node ./packages/mcp-server/dist/index.js +``` + +> [!NOTE] +> Once this package is [published to npm](https://www.stainless.com/docs/guides/publish), this will become: `npx -y umaaas_mcp` + +### Via MCP Client + +[Build the project](#building) as mentioned above. + +There is a partial list of existing clients at [modelcontextprotocol.io](https://modelcontextprotocol.io/clients). If you already +have a client, consult their documentation to install the MCP server. + +For clients with a configuration JSON, it might look something like this: + +```json +{ + "mcpServers": { + "umaaas_api": { + "command": "node", + "args": ["/path/to/local/umaaas-typescript/packages/mcp-server"], + "env": { + "UMAAAS_CLIENT_ID": "My Username", + "UMAAAS_CLIENT_SECRET": "My Password" + } + } + } +} +``` + +## Code Mode + +This MCP server is built on the "Code Mode" tool scheme. In this MCP Server, +your agent will write code against the TypeScript SDK, which will then be executed in an +isolated sandbox. To accomplish this, the server will expose two tools to your agent: + +- The first tool is a docs search tool, which can be used to generically query for + documentation about your API/SDK. + +- The second tool is a code tool, where the agent can write code against the TypeScript SDK. + The code will be executed in a sandbox environment without web or filesystem access. Then, + anything the code returns or prints will be returned to the agent as the result of the + tool call. + +Using this scheme, agents are capable of performing very complex tasks deterministically +and repeatably. + +## Running remotely + +Launching the client with `--transport=http` launches the server as a remote server using Streamable HTTP transport. The `--port` setting can choose the port it will run on, and the `--socket` setting allows it to run on a Unix socket. + +Authorization can be provided via the `Authorization` header using the Basic scheme. + +Additionally, authorization can be provided via the following headers: +| Header | Equivalent client option | Security scheme | +| ------------------------ | ------------------------ | --------------- | +| `x-umaaas-client-id` | `username` | BasicAuth | +| `x-umaaas-client-secret` | `password` | BasicAuth | + +A configuration JSON for this server might look like this, assuming the server is hosted at `http://localhost:3000`: + +```json +{ + "mcpServers": { + "umaaas_api": { + "url": "http://localhost:3000", + "headers": { + "Authorization": "Basic " + } + } + } +} +``` diff --git a/mcp-server/build b/mcp-server/build new file mode 100644 index 00000000..dc2c459e --- /dev/null +++ b/mcp-server/build @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +set -exuo pipefail + +rm -rf dist; mkdir dist + +# Copy src to dist/src and build from dist/src into dist, so that +# the source map for index.js.map will refer to ./src/index.ts etc +cp -rp src README.md dist + +for file in LICENSE; do + if [ -e "../../${file}" ]; then cp "../../${file}" dist; fi +done + +for file in CHANGELOG.md; do + if [ -e "${file}" ]; then cp "${file}" dist; fi +done + +# this converts the export map paths for the dist directory +# and does a few other minor things +PKG_JSON_PATH=../../packages/mcp-server/package.json node ../../scripts/utils/make-dist-package-json.cjs > dist/package.json + +# updates the `umaaas` dependency to point to NPM +node scripts/postprocess-dist-package-json.cjs + +# build to .js/.mjs/.d.ts files +./node_modules/.bin/tsc-multi + +cp tsconfig.dist-src.json dist/src/tsconfig.json + +chmod +x dist/index.js + +DIST_PATH=./dist PKG_IMPORT_PATH=umaaas_mcp/ node ../../scripts/utils/postprocess-files.cjs + +# mcp bundle +rm -rf dist-bundle umaaas_api.mcpb; mkdir dist-bundle + +# copy package.json +PKG_JSON_PATH=../../packages/mcp-server/package.json node ../../scripts/utils/make-dist-package-json.cjs > dist-bundle/package.json + +# copy files +node scripts/copy-bundle-files.cjs + +# install runtime deps +cd dist-bundle +npm install +cd .. + +# pack bundle +cp manifest.json dist-bundle + +npx mcpb pack dist-bundle umaaas_api.mcpb + +npx mcpb sign umaaas_api.mcpb --self-signed + +# clean up +rm -rf dist-bundle diff --git a/mcp-server/jest.config.ts b/mcp-server/jest.config.ts new file mode 100644 index 00000000..81e70a21 --- /dev/null +++ b/mcp-server/jest.config.ts @@ -0,0 +1,17 @@ +import type { JestConfigWithTsJest } from 'ts-jest'; + +const config: JestConfigWithTsJest = { + preset: 'ts-jest/presets/default-esm', + testEnvironment: 'node', + transform: { + '^.+\\.(t|j)sx?$': ['@swc/jest', { sourceMaps: 'inline' }], + }, + moduleNameMapper: { + '^umaaas_mcp$': '/src/index.ts', + '^umaaas_mcp/(.*)$': '/src/$1', + }, + modulePathIgnorePatterns: ['/dist/'], + testPathIgnorePatterns: ['scripts'], +}; + +export default config; diff --git a/mcp-server/manifest.json b/mcp-server/manifest.json new file mode 100644 index 00000000..d1415b46 --- /dev/null +++ b/mcp-server/manifest.json @@ -0,0 +1,54 @@ +{ + "dxt_version": "0.2", + "name": "umaaas_mcp", + "version": "0.0.1-alpha.0", + "description": "The official MCP Server for the Umaaas API", + "author": { + "name": "Umaaas", + "email": "support@lightspark.com" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/stainless-sdks/umaaas-typescript.git" + }, + "homepage": "https://github.com/stainless-sdks/umaaas-typescript/tree/main/packages/mcp-server#readme", + "documentation": "https://lightsparkdev.github.io/umaaas-api/", + "server": { + "type": "node", + "entry_point": "index.js", + "mcp_config": { + "command": "node", + "args": [ + "${__dirname}/index.js" + ], + "env": { + "UMAAAS_CLIENT_ID": "${user_config.UMAAAS_CLIENT_ID}", + "UMAAAS_CLIENT_SECRET": "${user_config.UMAAAS_CLIENT_SECRET}" + } + } + }, + "user_config": { + "UMAAAS_CLIENT_ID": { + "title": "username", + "description": "API token authentication using format `:`", + "required": true, + "type": "string" + }, + "UMAAAS_CLIENT_SECRET": { + "title": "password", + "description": "API token authentication using format `:`", + "required": true, + "type": "string" + } + }, + "tools": [], + "tools_generated": true, + "compatibility": { + "runtimes": { + "node": ">=18.0.0" + } + }, + "keywords": [ + "api" + ] +} diff --git a/mcp-server/package.json b/mcp-server/package.json new file mode 100644 index 00000000..b1040ff6 --- /dev/null +++ b/mcp-server/package.json @@ -0,0 +1,96 @@ +{ + "name": "umaaas_mcp", + "version": "0.0.1-alpha.0", + "description": "The official MCP Server for the Umaaas API", + "author": "Umaaas ", + "types": "dist/index.d.ts", + "main": "dist/index.js", + "type": "commonjs", + "repository": { + "type": "git", + "url": "git+https://github.com/stainless-sdks/umaaas-typescript.git", + "directory": "packages/mcp-server" + }, + "homepage": "https://github.com/stainless-sdks/umaaas-typescript/tree/main/packages/mcp-server#readme", + "license": "Apache-2.0", + "packageManager": "yarn@1.22.22", + "private": false, + "publishConfig": { + "access": "public" + }, + "scripts": { + "test": "jest", + "build": "bash ./build", + "prepack": "echo 'to pack, run yarn build && (cd dist; yarn pack)' && exit 1", + "prepublishOnly": "echo 'to publish, run yarn build && (cd dist; yarn publish)' && exit 1", + "format": "prettier --write --cache --cache-strategy metadata . !dist", + "prepare": "npm run build", + "tsn": "ts-node -r tsconfig-paths/register", + "lint": "eslint .", + "fix": "eslint --fix ." + }, + "dependencies": { + "umaaas": "link:../../dist/", + "ajv": "^8.18.0", + "@cloudflare/cabidela": "^0.2.4", + "@hono/node-server": "^1.19.10", + "@modelcontextprotocol/sdk": "^1.27.1", + "hono": "^4.12.4", + "@valtown/deno-http-worker": "^0.0.21", + "cookie-parser": "^1.4.6", + "cors": "^2.8.5", + "express": "^5.1.0", + "fuse.js": "^7.1.0", + "minisearch": "^7.2.0", + "jq-web": "https://github.com/stainless-api/jq-web/releases/download/v0.8.8/jq-web.tar.gz", + "pino": "^10.3.1", + "pino-http": "^11.0.0", + "pino-pretty": "^13.1.3", + "qs": "^6.14.1", + "typescript": "5.8.3", + "yargs": "^17.7.2", + "zod": "^3.25.20", + "zod-to-json-schema": "^3.24.5", + "zod-validation-error": "^4.0.1" + }, + "bin": { + "mcp-server": "dist/index.js" + }, + "devDependencies": { + "@anthropic-ai/mcpb": "^2.1.2", + "@types/cookie-parser": "^1.4.10", + "@types/cors": "^2.8.19", + "@types/express": "^5.0.3", + "@types/jest": "^29.4.0", + "@types/qs": "^6.14.0", + "@types/yargs": "^17.0.8", + "@typescript-eslint/eslint-plugin": "8.31.1", + "@typescript-eslint/parser": "8.31.1", + "eslint": "^9.39.1", + "eslint-plugin-prettier": "^5.4.1", + "eslint-plugin-unused-imports": "^4.1.4", + "jest": "^29.4.0", + "prettier": "^3.0.0", + "ts-jest": "^29.1.0", + "ts-morph": "^19.0.0", + "ts-node": "^10.5.0", + "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz", + "tsconfig-paths": "^4.0.0" + }, + "imports": { + "umaaas_mcp": ".", + "umaaas_mcp/*": "./src/*" + }, + "exports": { + ".": { + "require": "./dist/index.js", + "default": "./dist/index.mjs" + }, + "./*.mjs": "./dist/*.mjs", + "./*.js": "./dist/*.js", + "./*": { + "require": "./dist/*.js", + "default": "./dist/*.mjs" + } + } +} diff --git a/mcp-server/scripts/copy-bundle-files.cjs b/mcp-server/scripts/copy-bundle-files.cjs new file mode 100644 index 00000000..dc3fddca --- /dev/null +++ b/mcp-server/scripts/copy-bundle-files.cjs @@ -0,0 +1,36 @@ +const fs = require('fs'); +const path = require('path'); +const pkgJson = require('../dist-bundle/package.json'); + +const distDir = path.resolve(__dirname, '..', 'dist'); +const distBundleDir = path.resolve(__dirname, '..', 'dist-bundle'); +const distBundlePkgJson = path.join(distBundleDir, 'package.json'); + +async function* walk(dir) { + for await (const d of await fs.promises.opendir(dir)) { + const entry = path.join(dir, d.name); + if (d.isDirectory()) yield* walk(entry); + else if (d.isFile()) yield entry; + } +} + +async function copyFiles() { + // copy runtime files + for await (const file of walk(distDir)) { + if (!/[cm]?js$/.test(file)) continue; + const dest = path.join(distBundleDir, path.relative(distDir, file)); + await fs.promises.mkdir(path.dirname(dest), { recursive: true }); + await fs.promises.copyFile(file, dest); + } + + // replace package.json reference with local reference + for (const dep in pkgJson.dependencies) { + if (dep === 'umaaas') { + pkgJson.dependencies[dep] = 'file:../../../dist/'; + } + } + + await fs.promises.writeFile(distBundlePkgJson, JSON.stringify(pkgJson, null, 2)); +} + +copyFiles(); diff --git a/mcp-server/scripts/postprocess-dist-package-json.cjs b/mcp-server/scripts/postprocess-dist-package-json.cjs new file mode 100644 index 00000000..b609240a --- /dev/null +++ b/mcp-server/scripts/postprocess-dist-package-json.cjs @@ -0,0 +1,12 @@ +const fs = require('fs'); +const pkgJson = require('../dist/package.json'); +const parentPkgJson = require('../../../package.json'); + +for (const dep in pkgJson.dependencies) { + // ensure we point to NPM instead of a local directory + if (dep === 'umaaas') { + pkgJson.dependencies[dep] = '^' + parentPkgJson.version; + } +} + +fs.writeFileSync('dist/package.json', JSON.stringify(pkgJson, null, 2)); diff --git a/mcp-server/src/auth.ts b/mcp-server/src/auth.ts new file mode 100644 index 00000000..00f8d9d2 --- /dev/null +++ b/mcp-server/src/auth.ts @@ -0,0 +1,50 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { IncomingMessage } from 'node:http'; +import { ClientOptions } from 'umaaas'; +import { McpOptions } from './options'; + +export const parseClientAuthHeaders = (req: IncomingMessage, required?: boolean): Partial => { + if (req.headers.authorization) { + const scheme = req.headers.authorization.split(' ')[0]!; + const value = req.headers.authorization.slice(scheme.length + 1); + switch (scheme) { + case 'Basic': + const rawValue = Buffer.from(value, 'base64').toString(); + return { + username: rawValue.slice(0, rawValue.search(':')), + password: rawValue.slice(rawValue.search(':') + 1), + }; + default: + throw new Error( + 'Unsupported authorization scheme. Expected the "Authorization" header to be a supported scheme (Basic).', + ); + } + } else if (required) { + throw new Error('Missing required Authorization header; see WWW-Authenticate header for details.'); + } + + const username = + Array.isArray(req.headers['x-umaaas-client-id']) ? + req.headers['x-umaaas-client-id'][0] + : req.headers['x-umaaas-client-id']; + const password = + Array.isArray(req.headers['x-umaaas-client-secret']) ? + req.headers['x-umaaas-client-secret'][0] + : req.headers['x-umaaas-client-secret']; + return { username, password }; +}; + +export const getStainlessApiKey = (req: IncomingMessage, mcpOptions: McpOptions): string | undefined => { + // Try to get the key from the x-stainless-api-key header + const headerKey = + Array.isArray(req.headers['x-stainless-api-key']) ? + req.headers['x-stainless-api-key'][0] + : req.headers['x-stainless-api-key']; + if (headerKey && typeof headerKey === 'string') { + return headerKey; + } + + // Fall back to value set in the mcpOptions (e.g. from environment variable), if provided + return mcpOptions.stainlessApiKey; +}; diff --git a/mcp-server/src/code-tool-paths.cts b/mcp-server/src/code-tool-paths.cts new file mode 100644 index 00000000..78263e45 --- /dev/null +++ b/mcp-server/src/code-tool-paths.cts @@ -0,0 +1,5 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +export function getWorkerPath(): string { + return require.resolve('./code-tool-worker.mjs'); +} diff --git a/mcp-server/src/code-tool-types.ts b/mcp-server/src/code-tool-types.ts new file mode 100644 index 00000000..dbe49994 --- /dev/null +++ b/mcp-server/src/code-tool-types.ts @@ -0,0 +1,17 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { ClientOptions } from 'umaaas'; + +export type WorkerInput = { + project_name: string; + code: string; + client_opts: ClientOptions; + intent?: string | undefined; +}; + +export type WorkerOutput = { + is_error: boolean; + result: unknown | null; + log_lines: string[]; + err_lines: string[]; +}; diff --git a/mcp-server/src/code-tool-worker.ts b/mcp-server/src/code-tool-worker.ts new file mode 100644 index 00000000..ade831ea --- /dev/null +++ b/mcp-server/src/code-tool-worker.ts @@ -0,0 +1,309 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import path from 'node:path'; +import util from 'node:util'; +import Fuse from 'fuse.js'; +import ts from 'typescript'; +import { WorkerOutput } from './code-tool-types'; +import { Umaaas, ClientOptions } from 'umaaas'; + +async function tseval(code: string) { + return import('data:application/typescript;charset=utf-8;base64,' + Buffer.from(code).toString('base64')); +} + +function getRunFunctionSource(code: string): { + type: 'declaration' | 'expression'; + client: string | undefined; + code: string; +} | null { + const sourceFile = ts.createSourceFile('code.ts', code, ts.ScriptTarget.Latest, true); + const printer = ts.createPrinter(); + + for (const statement of sourceFile.statements) { + // Check for top-level function declarations + if (ts.isFunctionDeclaration(statement)) { + if (statement.name?.text === 'run') { + return { + type: 'declaration', + client: statement.parameters[0]?.name.getText(), + code: printer.printNode(ts.EmitHint.Unspecified, statement.body!, sourceFile), + }; + } + } + + // Check for variable declarations: const run = () => {} or const run = function() {} + if (ts.isVariableStatement(statement)) { + for (const declaration of statement.declarationList.declarations) { + if ( + ts.isIdentifier(declaration.name) && + declaration.name.text === 'run' && + // Check if it's initialized with a function + declaration.initializer && + (ts.isFunctionExpression(declaration.initializer) || ts.isArrowFunction(declaration.initializer)) + ) { + return { + type: 'expression', + client: declaration.initializer.parameters[0]?.name.getText(), + code: printer.printNode(ts.EmitHint.Unspecified, declaration.initializer, sourceFile), + }; + } + } + } + } + + return null; +} + +function getTSDiagnostics(code: string): string[] { + const functionSource = getRunFunctionSource(code)!; + const codeWithImport = [ + 'import { Umaaas } from "umaaas";', + functionSource.type === 'declaration' ? + `async function run(${functionSource.client}: Umaaas)` + : `const run: (${functionSource.client}: Umaaas) => Promise =`, + functionSource.code, + ].join('\n'); + const sourcePath = path.resolve('code.ts'); + const ast = ts.createSourceFile(sourcePath, codeWithImport, ts.ScriptTarget.Latest, true); + const options = ts.getDefaultCompilerOptions(); + options.target = ts.ScriptTarget.Latest; + options.module = ts.ModuleKind.NodeNext; + options.moduleResolution = ts.ModuleResolutionKind.NodeNext; + const host = ts.createCompilerHost(options, true); + const newHost: typeof host = { + ...host, + getSourceFile: (...args) => { + if (path.resolve(args[0]) === sourcePath) { + return ast; + } + return host.getSourceFile(...args); + }, + readFile: (...args) => { + if (path.resolve(args[0]) === sourcePath) { + return codeWithImport; + } + return host.readFile(...args); + }, + fileExists: (...args) => { + if (path.resolve(args[0]) === sourcePath) { + return true; + } + return host.fileExists(...args); + }, + }; + const program = ts.createProgram({ + options, + rootNames: [sourcePath], + host: newHost, + }); + const diagnostics = ts.getPreEmitDiagnostics(program, ast); + return diagnostics.map((d) => { + const message = ts.flattenDiagnosticMessageText(d.messageText, '\n'); + if (!d.file || !d.start) return `- ${message}`; + const { line: lineNumber } = ts.getLineAndCharacterOfPosition(d.file, d.start); + const line = codeWithImport.split('\n').at(lineNumber)?.trim(); + return line ? `- ${message}\n ${line}` : `- ${message}`; + }); +} + +const fuse = new Fuse( + [ + 'client.users.create', + 'client.users.delete', + 'client.users.list', + 'client.users.retrieve', + 'client.users.update', + 'client.users.bulk.getJobStatus', + 'client.users.bulk.upload', + 'client.tokens.create', + 'client.tokens.delete', + 'client.tokens.list', + 'client.tokens.retrieve', + 'client.config.retrieve', + 'client.config.update', + 'client.webhooks.sendTest', + 'client.transactions.approve', + 'client.transactions.list', + 'client.transactions.reject', + 'client.transactions.retrieve', + 'client.receiver.lookup', + 'client.quotes.create', + 'client.quotes.retrieve', + 'client.quotes.retry', + 'client.invitations.cancel', + 'client.invitations.claim', + 'client.invitations.create', + 'client.invitations.retrieve', + 'client.sandbox.receivePayment', + 'client.sandbox.sendFunds', + 'client.umaProviders.list', + 'client.fbo.confirmPayment', + ], + { threshold: 1, shouldSort: true }, +); + +function getMethodSuggestions(fullyQualifiedMethodName: string): string[] { + return fuse + .search(fullyQualifiedMethodName) + .map(({ item }) => item) + .slice(0, 5); +} + +const proxyToObj = new WeakMap(); +const objToProxy = new WeakMap(); + +type ClientProxyConfig = { + path: string[]; + isBelievedBad?: boolean; +}; + +function makeSdkProxy(obj: T, { path, isBelievedBad = false }: ClientProxyConfig): T { + let proxy: T = objToProxy.get(obj); + + if (!proxy) { + proxy = new Proxy(obj, { + get(target, prop, receiver) { + const propPath = [...path, String(prop)]; + const value = Reflect.get(target, prop, receiver); + + if (isBelievedBad || (!(prop in target) && value === undefined)) { + // If we're accessing a path that doesn't exist, it will probably eventually error. + // Let's proxy it and mark it bad so that we can control the error message. + // We proxy an empty class so that an invocation or construction attempt is possible. + return makeSdkProxy(class {}, { path: propPath, isBelievedBad: true }); + } + + if (value !== null && (typeof value === 'object' || typeof value === 'function')) { + return makeSdkProxy(value, { path: propPath, isBelievedBad }); + } + + return value; + }, + + apply(target, thisArg, args) { + if (isBelievedBad || typeof target !== 'function') { + const fullyQualifiedMethodName = path.join('.'); + const suggestions = getMethodSuggestions(fullyQualifiedMethodName); + throw new Error( + `${fullyQualifiedMethodName} is not a function. Did you mean: ${suggestions.join(', ')}`, + ); + } + + return Reflect.apply(target, proxyToObj.get(thisArg) ?? thisArg, args); + }, + + construct(target, args, newTarget) { + if (isBelievedBad || typeof target !== 'function') { + const fullyQualifiedMethodName = path.join('.'); + const suggestions = getMethodSuggestions(fullyQualifiedMethodName); + throw new Error( + `${fullyQualifiedMethodName} is not a constructor. Did you mean: ${suggestions.join(', ')}`, + ); + } + + return Reflect.construct(target, args, newTarget); + }, + }); + + objToProxy.set(obj, proxy); + proxyToObj.set(proxy, obj); + } + + return proxy; +} + +function parseError(code: string, error: unknown): string | undefined { + if (!(error instanceof Error)) return; + const cause = error.cause instanceof Error ? `: ${error.cause.message}` : ''; + const message = error.name ? `${error.name}: ${error.message}${cause}` : `${error.message}${cause}`; + try { + // Deno uses V8; the first ":LINE:COLUMN" is the top of stack. + const lineNumber = error.stack?.match(/:([0-9]+):[0-9]+/)?.[1]; + // -1 for the zero-based indexing + const line = + lineNumber && + code + .split('\n') + .at(parseInt(lineNumber, 10) - 1) + ?.trim(); + return line ? `${message}\n at line ${lineNumber}\n ${line}` : message; + } catch { + return message; + } +} + +const fetch = async (req: Request): Promise => { + const { opts, code } = (await req.json()) as { opts: ClientOptions; code: string }; + + const runFunctionSource = code ? getRunFunctionSource(code) : null; + if (!runFunctionSource) { + const message = + code ? + 'The code is missing a top-level `run` function.' + : 'The code argument is missing. Provide one containing a top-level `run` function.'; + return Response.json( + { + is_error: true, + result: `${message} Write code within this template:\n\n\`\`\`\nasync function run(client) {\n // Fill this out\n}\n\`\`\``, + log_lines: [], + err_lines: [], + } satisfies WorkerOutput, + { status: 400, statusText: 'Code execution error' }, + ); + } + + const diagnostics = getTSDiagnostics(code); + if (diagnostics.length > 0) { + return Response.json( + { + is_error: true, + result: `The code contains TypeScript diagnostics:\n${diagnostics.join('\n')}`, + log_lines: [], + err_lines: [], + } satisfies WorkerOutput, + { status: 400, statusText: 'Code execution error' }, + ); + } + + const client = new Umaaas({ + ...opts, + }); + + const log_lines: string[] = []; + const err_lines: string[] = []; + const originalConsole = globalThis.console; + globalThis.console = { + ...originalConsole, + log: (...args: unknown[]) => { + log_lines.push(util.format(...args)); + }, + error: (...args: unknown[]) => { + err_lines.push(util.format(...args)); + }, + }; + try { + let run_ = async (client: any) => {}; + run_ = (await tseval(`${code}\nexport default run;`)).default; + const result = await run_(makeSdkProxy(client, { path: ['client'] })); + return Response.json({ + is_error: false, + result, + log_lines, + err_lines, + } satisfies WorkerOutput); + } catch (e) { + return Response.json( + { + is_error: true, + result: parseError(code, e), + log_lines, + err_lines, + } satisfies WorkerOutput, + { status: 400, statusText: 'Code execution error' }, + ); + } finally { + globalThis.console = originalConsole; + } +}; + +export default { fetch }; diff --git a/mcp-server/src/code-tool.ts b/mcp-server/src/code-tool.ts new file mode 100644 index 00000000..cb1ea1b9 --- /dev/null +++ b/mcp-server/src/code-tool.ts @@ -0,0 +1,406 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { + ContentBlock, + McpRequestContext, + McpTool, + Metadata, + ToolCallResult, + asErrorResult, + asTextContentResult, +} from './types'; +import { Tool } from '@modelcontextprotocol/sdk/types.js'; +import { readEnv, requireValue } from './util'; +import { WorkerInput, WorkerOutput } from './code-tool-types'; +import { getLogger } from './logger'; +import { SdkMethod } from './methods'; +import { McpCodeExecutionMode } from './options'; +import { ClientOptions } from 'umaaas'; + +const prompt = `Runs JavaScript code to interact with the Umaaas API. + +You are a skilled TypeScript programmer writing code to interface with the service. +Define an async function named "run" that takes a single parameter of an initialized SDK client and it will be run. +For example: + +\`\`\` +async function run(client) { + const user = await client.users.create({ + bankAccountInfo: { + bankName: 'BBVA Mexico', + clabeNumber: '123456789012345678', + accountType: 'CLABE', + }, + platformUserId: '9f84e0c2a72c4fa', + umaAddress: '$john.doe@uma.domain.com', + userType: 'INDIVIDUAL', + }); +} +\`\`\` + +You will be returned anything that your function returns, plus the results of any console.log statements. +Do not add try-catch blocks for single API calls. The tool will handle errors for you. +Do not add comments unless necessary for generating better code. +Code will run in a container, and cannot interact with the network outside of the given SDK client. +Variables will not persist between calls, so make sure to return or log any data you might need later. +Remember that you are writing TypeScript code, so you need to be careful with your types. +Always type dynamic key-value stores explicitly as Record instead of {}.`; + +/** + * A tool that runs code against a copy of the SDK. + * + * Instead of exposing every endpoint as its own tool, which uses up too many tokens for LLMs to use at once, + * we expose a single tool that can be used to search for endpoints by name, resource, operation, or tag, and then + * a generic endpoint that can be used to invoke any endpoint with the provided arguments. + * + * @param blockedMethods - The methods to block for code execution. Blocking is done by simple string + * matching, so it is not secure against obfuscation. For stronger security, block in the downstream API + * with limited API keys. + * @param codeExecutionMode - Whether to execute code in a local Deno environment or in a remote + * sandbox environment hosted by Stainless. + */ +export function codeTool({ + blockedMethods, + codeExecutionMode, +}: { + blockedMethods: SdkMethod[] | undefined; + codeExecutionMode: McpCodeExecutionMode; +}): McpTool { + const metadata: Metadata = { resource: 'all', operation: 'write', tags: [] }; + const tool: Tool = { + name: 'execute', + description: prompt, + inputSchema: { + type: 'object', + properties: { + code: { + type: 'string', + description: 'Code to execute.', + }, + intent: { + type: 'string', + description: 'Task you are trying to perform. Used for improving the service.', + }, + }, + required: ['code'], + }, + }; + + const logger = getLogger(); + + const handler = async ({ + reqContext, + args, + }: { + reqContext: McpRequestContext; + args: any; + }): Promise => { + const code = args.code as string; + // Do very basic blocking of code that includes forbidden method names. + // + // WARNING: This is not secure against obfuscation and other evasion methods. If + // stronger security blocks are required, then these should be enforced in the downstream + // API (e.g., by having users call the MCP server with API keys with limited permissions). + if (blockedMethods) { + const blockedMatches = blockedMethods.filter((method) => code.includes(method.fullyQualifiedName)); + if (blockedMatches.length > 0) { + return asErrorResult( + `The following methods have been blocked by the MCP server and cannot be used in code execution: ${blockedMatches + .map((m) => m.fullyQualifiedName) + .join(', ')}`, + ); + } + } + + let result: ToolCallResult; + const startTime = Date.now(); + + if (codeExecutionMode === 'local') { + logger.debug('Executing code in local Deno environment'); + result = await localDenoHandler({ reqContext, args }); + } else { + logger.debug('Executing code in remote Stainless environment'); + result = await remoteStainlessHandler({ reqContext, args }); + } + + logger.info( + { + codeExecutionMode, + durationMs: Date.now() - startTime, + isError: result.isError, + contentRows: result.content?.length ?? 0, + }, + 'Got code tool execution result', + ); + return result; + }; + + return { metadata, tool, handler }; +} + +const remoteStainlessHandler = async ({ + reqContext, + args, +}: { + reqContext: McpRequestContext; + args: any; +}): Promise => { + const code = args.code as string; + const intent = args.intent as string | undefined; + const client = reqContext.client; + + const codeModeEndpoint = readEnv('CODE_MODE_ENDPOINT_URL') ?? 'https://api.stainless.com/api/ai/code-tool'; + + const localClientEnvs = { + UMAAAS_CLIENT_ID: requireValue( + readEnv('UMAAAS_CLIENT_ID') ?? client.username, + 'set UMAAAS_CLIENT_ID environment variable or provide username client option', + ), + UMAAAS_CLIENT_SECRET: requireValue( + readEnv('UMAAAS_CLIENT_SECRET') ?? client.password, + 'set UMAAAS_CLIENT_SECRET environment variable or provide password client option', + ), + UMAAAS_BASE_URL: readEnv('UMAAAS_BASE_URL') ?? client.baseURL ?? undefined, + }; + // Merge any upstream client envs from the request header, with upstream values taking precedence. + const mergedClientEnvs = { ...localClientEnvs, ...reqContext.upstreamClientEnvs }; + + // Setting a Stainless API key authenticates requests to the code tool endpoint. + const res = await fetch(codeModeEndpoint, { + method: 'POST', + headers: { + ...(reqContext.stainlessApiKey && { Authorization: reqContext.stainlessApiKey }), + 'Content-Type': 'application/json', + 'x-stainless-mcp-client-envs': JSON.stringify(mergedClientEnvs), + }, + body: JSON.stringify({ + project_name: 'umaaas', + code, + intent, + client_opts: {}, + } satisfies WorkerInput), + }); + + if (!res.ok) { + if (res.status === 404 && !reqContext.stainlessApiKey) { + throw new Error( + 'Could not access code tool for this project. You may need to provide a Stainless API key via the STAINLESS_API_KEY environment variable, the --stainless-api-key flag, or the x-stainless-api-key HTTP header.', + ); + } + throw new Error( + `${res.status}: ${ + res.statusText + } error when trying to contact Code Tool server. Details: ${await res.text()}`, + ); + } + + const { is_error, result, log_lines, err_lines } = (await res.json()) as WorkerOutput; + const hasLogs = log_lines.length > 0 || err_lines.length > 0; + const output = { + result, + ...(log_lines.length > 0 && { log_lines }), + ...(err_lines.length > 0 && { err_lines }), + }; + if (is_error) { + return asErrorResult(typeof result === 'string' && !hasLogs ? result : JSON.stringify(output, null, 2)); + } + return asTextContentResult(output); +}; + +const localDenoHandler = async ({ + reqContext, + args, +}: { + reqContext: McpRequestContext; + args: unknown; +}): Promise => { + const fs = await import('node:fs'); + const path = await import('node:path'); + const url = await import('node:url'); + const { newDenoHTTPWorker } = await import('@valtown/deno-http-worker'); + const { getWorkerPath } = await import('./code-tool-paths.cjs'); + const workerPath = getWorkerPath(); + + const client = reqContext.client; + const baseURLHostname = new URL(client.baseURL).hostname; + const { code } = args as { code: string }; + + let denoPath: string; + + const packageRoot = path.resolve(path.dirname(workerPath), '..'); + const packageNodeModulesPath = path.resolve(packageRoot, 'node_modules'); + + // Check if deno is in PATH + const { execSync } = await import('node:child_process'); + try { + execSync('command -v deno', { stdio: 'ignore' }); + denoPath = 'deno'; + } catch { + try { + // Use deno binary in node_modules if it's found + const denoNodeModulesPath = path.resolve(packageNodeModulesPath, 'deno', 'bin.cjs'); + await fs.promises.access(denoNodeModulesPath, fs.constants.X_OK); + denoPath = denoNodeModulesPath; + } catch { + return asErrorResult( + 'Deno is required for code execution but was not found. ' + + 'Install it from https://deno.land or run: npm install deno', + ); + } + } + + const allowReadPaths = [ + 'code-tool-worker.mjs', + `${workerPath.replace(/([\/\\]node_modules)[\/\\].+$/, '$1')}/`, + packageRoot, + ]; + + // Follow symlinks in node_modules to allow read access to workspace-linked packages + try { + const sdkPkgName = 'umaaas'; + const sdkDir = path.resolve(packageNodeModulesPath, sdkPkgName); + const realSdkDir = fs.realpathSync(sdkDir); + if (realSdkDir !== sdkDir) { + allowReadPaths.push(realSdkDir); + } + } catch { + // Ignore if symlink resolution fails + } + + const allowRead = allowReadPaths.join(','); + + const worker = await newDenoHTTPWorker(url.pathToFileURL(workerPath), { + denoExecutable: denoPath, + runFlags: [ + `--node-modules-dir=manual`, + `--allow-read=${allowRead}`, + `--allow-net=${baseURLHostname}`, + // Allow environment variables because instantiating the client will try to read from them, + // even though they are not set. + '--allow-env', + ], + printOutput: true, + spawnOptions: { + cwd: path.dirname(workerPath), + // Merge any upstream client envs into the Deno subprocess environment, + // with the upstream env vars taking precedence. + env: { ...process.env, ...reqContext.upstreamClientEnvs }, + }, + }); + + try { + const resp = await new Promise((resolve, reject) => { + worker.addEventListener('exit', (exitCode) => { + reject(new Error(`Worker exited with code ${exitCode}`)); + }); + + // Strip null/undefined values so that the worker SDK client can fall back to + // reading from environment variables (including any upstreamClientEnvs). + const opts = { + ...(client.baseURL != null ? { baseURL: client.baseURL } : undefined), + ...(client.username != null ? { username: client.username } : undefined), + ...(client.password != null ? { password: client.password } : undefined), + defaultHeaders: { + 'X-Stainless-MCP': 'true', + }, + } satisfies Partial as ClientOptions; + + const req = worker.request( + 'http://localhost', + { + headers: { + 'content-type': 'application/json', + }, + method: 'POST', + }, + (resp) => { + const body: Uint8Array[] = []; + resp.on('error', (err) => { + reject(err); + }); + resp.on('data', (chunk) => { + body.push(chunk); + }); + resp.on('end', () => { + resolve( + new Response(Buffer.concat(body).toString(), { + status: resp.statusCode ?? 200, + headers: resp.headers as any, + }), + ); + }); + }, + ); + + const body = JSON.stringify({ + opts, + code, + }); + + req.write(body, (err) => { + if (err != null) { + reject(err); + } + }); + + req.end(); + }); + + if (resp.status === 200) { + const { result, log_lines, err_lines } = (await resp.json()) as WorkerOutput; + const returnOutput: ContentBlock | null = + result == null ? null : ( + { + type: 'text', + text: typeof result === 'string' ? result : JSON.stringify(result), + } + ); + const logOutput: ContentBlock | null = + log_lines.length === 0 ? + null + : { + type: 'text', + text: log_lines.join('\n'), + }; + const errOutput: ContentBlock | null = + err_lines.length === 0 ? + null + : { + type: 'text', + text: 'Error output:\n' + err_lines.join('\n'), + }; + return { + content: [returnOutput, logOutput, errOutput].filter((block) => block !== null), + }; + } else { + const { result, log_lines, err_lines } = (await resp.json()) as WorkerOutput; + const messageOutput: ContentBlock | null = + result == null ? null : ( + { + type: 'text', + text: typeof result === 'string' ? result : JSON.stringify(result), + } + ); + const logOutput: ContentBlock | null = + log_lines.length === 0 ? + null + : { + type: 'text', + text: log_lines.join('\n'), + }; + const errOutput: ContentBlock | null = + err_lines.length === 0 ? + null + : { + type: 'text', + text: 'Error output:\n' + err_lines.join('\n'), + }; + return { + content: [messageOutput, logOutput, errOutput].filter((block) => block !== null), + isError: true, + }; + } + } finally { + worker.terminate(); + } +}; diff --git a/mcp-server/src/docs-search-tool.ts b/mcp-server/src/docs-search-tool.ts new file mode 100644 index 00000000..7cb87a03 --- /dev/null +++ b/mcp-server/src/docs-search-tool.ts @@ -0,0 +1,138 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { Tool } from '@modelcontextprotocol/sdk/types.js'; +import { Metadata, McpRequestContext, asTextContentResult } from './types'; +import { getLogger } from './logger'; +import type { LocalDocsSearch } from './local-docs-search'; + +export const metadata: Metadata = { + resource: 'all', + operation: 'read', + tags: [], + httpMethod: 'get', +}; + +export const tool: Tool = { + name: 'search_docs', + description: + 'Search SDK documentation to find methods, parameters, and usage examples for interacting with the API. Use this before writing code when you need to discover the right approach.', + inputSchema: { + type: 'object', + properties: { + query: { + type: 'string', + description: 'The query to search for.', + }, + language: { + type: 'string', + description: 'The language for the SDK to search for.', + enum: ['http', 'python', 'go', 'typescript', 'javascript', 'terraform', 'ruby', 'java', 'kotlin'], + }, + detail: { + type: 'string', + description: 'The amount of detail to return.', + enum: ['default', 'verbose'], + }, + }, + required: ['query', 'language'], + }, + annotations: { + readOnlyHint: true, + }, +}; + +const docsSearchURL = + process.env['DOCS_SEARCH_URL'] || 'https://api.stainless.com/api/projects/umaaas/docs/search'; + +let _localSearch: LocalDocsSearch | undefined; + +export function setLocalSearch(search: LocalDocsSearch): void { + _localSearch = search; +} + +async function searchLocal(args: Record): Promise { + if (!_localSearch) { + throw new Error('Local search not initialized'); + } + + const query = (args['query'] as string) ?? ''; + const language = (args['language'] as string) ?? 'typescript'; + const detail = (args['detail'] as string) ?? 'default'; + + return _localSearch.search({ + query, + language, + detail, + maxResults: 10, + }).results; +} + +async function searchRemote(args: Record, reqContext: McpRequestContext): Promise { + const body = args as any; + const query = new URLSearchParams(body).toString(); + + const startTime = Date.now(); + const result = await fetch(`${docsSearchURL}?${query}`, { + headers: { + ...(reqContext.stainlessApiKey && { Authorization: reqContext.stainlessApiKey }), + ...(reqContext.mcpSessionId && { 'x-stainless-mcp-session-id': reqContext.mcpSessionId }), + ...(reqContext.mcpClientInfo && { + 'x-stainless-mcp-client-info': JSON.stringify(reqContext.mcpClientInfo), + }), + }, + }); + + const logger = getLogger(); + + if (!result.ok) { + const errorText = await result.text(); + logger.warn( + { + durationMs: Date.now() - startTime, + query: body.query, + status: result.status, + statusText: result.statusText, + errorText, + }, + 'Got error response from docs search tool', + ); + + if (result.status === 404 && !reqContext.stainlessApiKey) { + throw new Error( + 'Could not find docs for this project. You may need to provide a Stainless API key via the STAINLESS_API_KEY environment variable, the --stainless-api-key flag, or the x-stainless-api-key HTTP header.', + ); + } + + throw new Error( + `${result.status}: ${result.statusText} when using doc search tool. Details: ${errorText}`, + ); + } + + const resultBody = await result.json(); + logger.info( + { + durationMs: Date.now() - startTime, + query: body.query, + }, + 'Got docs search result', + ); + return resultBody; +} + +export const handler = async ({ + reqContext, + args, +}: { + reqContext: McpRequestContext; + args: Record | undefined; +}) => { + const body = args ?? {}; + + if (_localSearch) { + return asTextContentResult(await searchLocal(body)); + } + + return asTextContentResult(await searchRemote(body, reqContext)); +}; + +export default { metadata, tool, handler }; diff --git a/mcp-server/src/http.ts b/mcp-server/src/http.ts new file mode 100644 index 00000000..ed0a6833 --- /dev/null +++ b/mcp-server/src/http.ts @@ -0,0 +1,227 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp'; +import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'; +import { ClientOptions } from 'umaaas'; +import express from 'express'; +import pino from 'pino'; +import pinoHttp from 'pino-http'; +import { getStainlessApiKey, parseClientAuthHeaders } from './auth'; +import { getLogger } from './logger'; +import { McpOptions } from './options'; +import { initMcpServer, newMcpServer } from './server'; + +const newServer = async ({ + clientOptions, + mcpOptions, + req, + res, +}: { + clientOptions: ClientOptions; + mcpOptions: McpOptions; + req: express.Request; + res: express.Response; +}): Promise => { + const stainlessApiKey = getStainlessApiKey(req, mcpOptions); + const customInstructionsPath = mcpOptions.customInstructionsPath; + const server = await newMcpServer({ stainlessApiKey, customInstructionsPath }); + + const authOptions = parseClientAuthHeaders(req, false); + + let upstreamClientEnvs: Record | undefined; + const clientEnvsHeader = req.headers['x-stainless-mcp-client-envs']; + if (typeof clientEnvsHeader === 'string') { + try { + const parsed = JSON.parse(clientEnvsHeader); + if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) { + upstreamClientEnvs = parsed; + } + } catch { + // Ignore malformed header + } + } + + // Parse x-stainless-mcp-client-permissions header to override permission options + // + // Note: Permissions are best-effort and intended to prevent clients from doing unexpected things; + // they're not a hard security boundary, so we allow arbitrary, client-driven overrides. + // + // See the Stainless MCP documentation for more details. + let effectiveMcpOptions = mcpOptions; + const clientPermissionsHeader = req.headers['x-stainless-mcp-client-permissions']; + if (typeof clientPermissionsHeader === 'string') { + try { + const parsed = JSON.parse(clientPermissionsHeader); + if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) { + effectiveMcpOptions = { + ...mcpOptions, + ...(typeof parsed.allow_http_gets === 'boolean' && { codeAllowHttpGets: parsed.allow_http_gets }), + ...(Array.isArray(parsed.allowed_methods) && { codeAllowedMethods: parsed.allowed_methods }), + ...(Array.isArray(parsed.blocked_methods) && { codeBlockedMethods: parsed.blocked_methods }), + }; + getLogger().info( + { clientPermissions: parsed }, + 'Overriding code execution permissions from x-stainless-mcp-client-permissions header', + ); + } + } catch (error) { + getLogger().warn({ error }, 'Failed to parse x-stainless-mcp-client-permissions header'); + } + } + + const mcpClientInfo = + typeof req.body?.params?.clientInfo?.name === 'string' ? + { name: req.body.params.clientInfo.name, version: String(req.body.params.clientInfo.version ?? '') } + : undefined; + + await initMcpServer({ + server: server, + mcpOptions: effectiveMcpOptions, + clientOptions: { + ...clientOptions, + ...authOptions, + }, + stainlessApiKey: stainlessApiKey, + upstreamClientEnvs, + mcpSessionId: (req as any).mcpSessionId, + mcpClientInfo, + }); + + if (mcpClientInfo) { + getLogger().info({ mcpSessionId: (req as any).mcpSessionId, mcpClientInfo }, 'MCP client connected'); + } + + return server; +}; + +const post = + (options: { clientOptions: ClientOptions; mcpOptions: McpOptions }) => + async (req: express.Request, res: express.Response) => { + const server = await newServer({ ...options, req, res }); + // If we return null, we already set the authorization error. + if (server === null) return; + const transport = new StreamableHTTPServerTransport(); + await server.connect(transport as any); + await transport.handleRequest(req, res, req.body); + }; + +const get = async (req: express.Request, res: express.Response) => { + res.status(405).json({ + jsonrpc: '2.0', + error: { + code: -32000, + message: 'Method not supported', + }, + }); +}; + +const del = async (req: express.Request, res: express.Response) => { + res.status(405).json({ + jsonrpc: '2.0', + error: { + code: -32000, + message: 'Method not supported', + }, + }); +}; + +const redactHeaders = (headers: Record) => { + const hiddenHeaders = /auth|cookie|key|token|x-stainless-mcp-client-envs/i; + const filtered = { ...headers }; + Object.keys(filtered).forEach((key) => { + if (hiddenHeaders.test(key)) { + filtered[key] = '[REDACTED]'; + } + }); + return filtered; +}; + +export const streamableHTTPApp = ({ + clientOptions = {}, + mcpOptions, +}: { + clientOptions?: ClientOptions; + mcpOptions: McpOptions; +}): express.Express => { + const app = express(); + app.set('query parser', 'extended'); + app.use(express.json()); + app.use((req: express.Request, res: express.Response, next: express.NextFunction) => { + const existing = req.headers['mcp-session-id']; + const sessionId = (Array.isArray(existing) ? existing[0] : existing) || crypto.randomUUID(); + (req as any).mcpSessionId = sessionId; + const origWriteHead = res.writeHead.bind(res); + res.writeHead = function (statusCode: number, ...rest: any[]) { + res.setHeader('mcp-session-id', sessionId); + return origWriteHead(statusCode, ...rest); + } as typeof res.writeHead; + next(); + }); + app.use( + pinoHttp({ + logger: getLogger(), + customProps: (req) => ({ + mcpSessionId: (req as any).mcpSessionId, + }), + customLogLevel: (req, res) => { + if (res.statusCode >= 500) { + return 'error'; + } else if (res.statusCode >= 400) { + return 'warn'; + } + return 'info'; + }, + customSuccessMessage: function (req, res) { + return `Request ${req.method} to ${req.url} completed with status ${res.statusCode}`; + }, + customErrorMessage: function (req, res, err) { + return `Request ${req.method} to ${req.url} errored with status ${res.statusCode}`; + }, + serializers: { + req: pino.stdSerializers.wrapRequestSerializer((req) => { + return { + ...req, + headers: redactHeaders(req.raw.headers), + }; + }), + res: pino.stdSerializers.wrapResponseSerializer((res) => { + return { + ...res, + headers: redactHeaders(res.headers), + }; + }), + }, + }), + ); + + app.get('/health', async (req: express.Request, res: express.Response) => { + res.status(200).send('OK'); + }); + app.get('/', get); + app.post('/', post({ clientOptions, mcpOptions })); + app.delete('/', del); + + return app; +}; + +export const launchStreamableHTTPServer = async ({ + mcpOptions, + port, +}: { + mcpOptions: McpOptions; + port: number | string | undefined; +}) => { + const app = streamableHTTPApp({ mcpOptions }); + const server = app.listen(port); + const address = server.address(); + + const logger = getLogger(); + + if (typeof address === 'string') { + logger.info(`MCP Server running on streamable HTTP at ${address}`); + } else if (address !== null) { + logger.info(`MCP Server running on streamable HTTP on port ${address.port}`); + } else { + logger.info(`MCP Server running on streamable HTTP on port ${port}`); + } +}; diff --git a/mcp-server/src/index.ts b/mcp-server/src/index.ts new file mode 100644 index 00000000..5bca4a60 --- /dev/null +++ b/mcp-server/src/index.ts @@ -0,0 +1,67 @@ +#!/usr/bin/env node + +import { selectTools } from './server'; +import { McpOptions, parseCLIOptions } from './options'; +import { launchStdioServer } from './stdio'; +import { launchStreamableHTTPServer } from './http'; +import type { McpTool } from './types'; +import { configureLogger, getLogger } from './logger'; + +async function main() { + const options = parseOptionsOrError(); + configureLogger({ + level: options.debug ? 'debug' : 'info', + pretty: options.logFormat === 'pretty', + }); + + const selectedTools = await selectToolsOrError(options); + + getLogger().info( + { tools: selectedTools.map((e) => e.tool.name) }, + `MCP Server starting with ${selectedTools.length} tools`, + ); + + switch (options.transport) { + case 'stdio': + await launchStdioServer(options); + break; + case 'http': + await launchStreamableHTTPServer({ + mcpOptions: options, + port: options.socket ?? options.port, + }); + break; + } +} + +if (require.main === module) { + main().catch((error) => { + // Logger might not be initialized yet + console.error('Fatal error in main()', error); + process.exit(1); + }); +} + +function parseOptionsOrError() { + try { + return parseCLIOptions(); + } catch (error) { + // Logger is initialized after options, so use console.error here + console.error('Error parsing options', error); + process.exit(1); + } +} + +async function selectToolsOrError(options: McpOptions): Promise { + try { + const includedTools = selectTools(options); + if (includedTools.length === 0) { + getLogger().error('No tools match the provided filters'); + process.exit(1); + } + return includedTools; + } catch (error) { + getLogger().error({ error }, 'Error filtering tools'); + process.exit(1); + } +} diff --git a/mcp-server/src/instructions.ts b/mcp-server/src/instructions.ts new file mode 100644 index 00000000..64be12b8 --- /dev/null +++ b/mcp-server/src/instructions.ts @@ -0,0 +1,83 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import fs from 'fs/promises'; +import { getLogger } from './logger'; +import { readEnv } from './util'; + +const INSTRUCTIONS_CACHE_TTL_MS = 15 * 60 * 1000; // 15 minutes + +interface InstructionsCacheEntry { + fetchedInstructions: string; + fetchedAt: number; +} + +const instructionsCache = new Map(); + +export async function getInstructions({ + stainlessApiKey, + customInstructionsPath, +}: { + stainlessApiKey?: string | undefined; + customInstructionsPath?: string | undefined; +}): Promise { + const now = Date.now(); + const cacheKey = customInstructionsPath ?? stainlessApiKey ?? ''; + const cached = instructionsCache.get(cacheKey); + + if (cached && now - cached.fetchedAt <= INSTRUCTIONS_CACHE_TTL_MS) { + return cached.fetchedInstructions; + } + + // Evict stale entries so the cache doesn't grow unboundedly. + for (const [key, entry] of instructionsCache) { + if (now - entry.fetchedAt > INSTRUCTIONS_CACHE_TTL_MS) { + instructionsCache.delete(key); + } + } + + let fetchedInstructions: string; + + if (customInstructionsPath) { + fetchedInstructions = await fetchLatestInstructionsFromFile(customInstructionsPath); + } else { + fetchedInstructions = await fetchLatestInstructionsFromApi(stainlessApiKey); + } + + instructionsCache.set(cacheKey, { fetchedInstructions, fetchedAt: now }); + return fetchedInstructions; +} + +async function fetchLatestInstructionsFromFile(path: string): Promise { + try { + return await fs.readFile(path, 'utf-8'); + } catch (error) { + getLogger().error({ error, path }, 'Error fetching instructions from file'); + throw error; + } +} + +async function fetchLatestInstructionsFromApi(stainlessApiKey: string | undefined): Promise { + // Setting the stainless API key is optional, but may be required + // to authenticate requests to the Stainless API. + const response = await fetch( + readEnv('CODE_MODE_INSTRUCTIONS_URL') ?? 'https://api.stainless.com/api/ai/instructions/umaaas', + { + method: 'GET', + headers: { ...(stainlessApiKey && { Authorization: stainlessApiKey }) }, + }, + ); + + let instructions: string | undefined; + if (!response.ok) { + getLogger().warn( + 'Warning: failed to retrieve MCP server instructions. Proceeding with default instructions...', + ); + + instructions = + '\n This is the umaaas MCP server.\n\n Available tools:\n - search_docs: Search SDK documentation to find the right methods and parameters.\n - execute: Run TypeScript code against a pre-authenticated SDK client. Define an async run(client) function.\n\n Workflow:\n - If unsure about the API, call search_docs first.\n - Write complete solutions in a single execute call when possible. For large datasets, use API filters to narrow results or paginate within a single execute block.\n - If execute returns an error, read the error and fix your code rather than retrying the same approach.\n - Variables do not persist between execute calls. Return or log all data you need.\n - Individual HTTP requests to the API have a 30-second timeout. If a request times out, try a smaller query or add filters.\n - Code execution has a total timeout of approximately 5 minutes. If your code times out, simplify it or break it into smaller steps.\n '; + } + + instructions ??= ((await response.json()) as { instructions: string }).instructions; + + return instructions; +} diff --git a/mcp-server/src/local-docs-search.ts b/mcp-server/src/local-docs-search.ts new file mode 100644 index 00000000..72dfe918 --- /dev/null +++ b/mcp-server/src/local-docs-search.ts @@ -0,0 +1,1311 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import MiniSearch from 'minisearch'; +import * as fs from 'node:fs/promises'; +import * as path from 'node:path'; +import { getLogger } from './logger'; + +type PerLanguageData = { + method?: string; + example?: string; +}; + +type MethodEntry = { + name: string; + endpoint: string; + httpMethod: string; + summary: string; + description: string; + stainlessPath: string; + qualified: string; + params?: string[]; + response?: string; + markdown?: string; + perLanguage?: Record; +}; + +type ProseChunk = { + content: string; + tag: string; + sectionContext?: string; + source?: string; +}; + +type MiniSearchDocument = { + id: string; + kind: 'http_method' | 'prose'; + name?: string; + endpoint?: string; + summary?: string; + description?: string; + qualified?: string; + stainlessPath?: string; + content?: string; + sectionContext?: string; + _original: Record; +}; + +type SearchResult = { + results: (string | Record)[]; +}; + +const EMBEDDED_METHODS: MethodEntry[] = [ + { + name: 'create', + endpoint: '/users', + httpMethod: 'post', + summary: 'Add a new user', + description: 'Register a new user in the system with UMA address and bank account information', + stainlessPath: '(resource) users > (method) create', + qualified: 'client.users.create', + params: [ + "{ platformUserId: string; umaAddress: string; userType: 'INDIVIDUAL' | 'BUSINESS'; id?: string; createdAt?: string; isDeleted?: boolean; updatedAt?: string; } | { platformUserId: string; umaAddress: string; userType: 'INDIVIDUAL' | 'BUSINESS'; id?: string; createdAt?: string; isDeleted?: boolean; updatedAt?: string; };", + ], + response: + '{ platformUserId: string; umaAddress: string; userType: user_type; id?: string; createdAt?: string; isDeleted?: boolean; updatedAt?: string; } | { platformUserId: string; umaAddress: string; userType: user_type; id?: string; createdAt?: string; isDeleted?: boolean; updatedAt?: string; }', + perLanguage: { + typescript: { + method: 'client.users.create', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst user = await client.users.create({\n bankAccountInfo: {\n accountType: 'US_ACCOUNT',\n bankName: 'Chase Bank',\n platformAccountId: 'chase_primary_1234',\n },\n platformUserId: '7b3c5a89d2f1e0',\n umaAddress: '$jane.doe@uma.domain.com',\n userType: 'INDIVIDUAL',\n address: {\n line1: '123 Pine Street',\n line2: 'Unit 501',\n city: 'Seattle',\n state: 'WA',\n postalCode: '98101',\n country: 'US',\n },\n birthDate: '1992-03-25',\n fullName: 'Jane Doe',\n});\n\nconsole.log(user);", + }, + kotlin: { + method: 'users().create', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.users.BankAccountType\nimport com.lightspark.umaaas.models.users.IndividualUser\nimport com.lightspark.umaaas.models.users.UserBankAccountInfo\nimport com.lightspark.umaaas.models.users.UserCreateResponse\nimport com.lightspark.umaaas.models.users.UserType\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val params: IndividualUser = IndividualUser.builder()\n .platformUserId("7b3c5a89d2f1e0")\n .umaAddress("\\$jane.doe@uma.domain.com")\n .userType(UserType.INDIVIDUAL)\n .bankAccountInfo(UserBankAccountInfo.UserClabeAccountInfo.builder()\n .bankName("Chase Bank")\n .clabeNumber("123456789012345678")\n .accountType(BankAccountType.US_ACCOUNT)\n .build())\n .build()\n val user: UserCreateResponse = client.users().create(params)\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/users \\\n -H \'Content-Type: application/json\' \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET" \\\n -d \'{\n "bankAccountInfo": {\n "bankName": "BBVA Mexico",\n "clabeNumber": "123456789012345678",\n "accountType": "CLABE"\n },\n "platformUserId": "9f84e0c2a72c4fa",\n "umaAddress": "$john.doe@uma.domain.com",\n "userType": "INDIVIDUAL",\n "birthDate": "1990-01-15",\n "fullName": "John Michael Doe",\n "nationality": "US"\n }\'', + }, + }, + }, + { + name: 'list', + endpoint: '/users', + httpMethod: 'get', + summary: 'List users', + description: + 'Retrieve a list of users with optional filtering parameters. Returns all users that match\nthe specified filters. If no filters are provided, returns all users (paginated).\n', + stainlessPath: '(resource) users > (method) list', + qualified: 'client.users.list', + params: [ + 'createdAfter?: string;', + 'createdBefore?: string;', + 'cursor?: string;', + 'isIncludingDeleted?: boolean;', + 'limit?: number;', + 'platformUserId?: string;', + 'umaAddress?: string;', + 'updatedAfter?: string;', + 'updatedBefore?: string;', + "userType?: 'INDIVIDUAL' | 'BUSINESS';", + ], + response: + '{ platformUserId: string; umaAddress: string; userType: user_type; id?: string; createdAt?: string; isDeleted?: boolean; updatedAt?: string; } | { platformUserId: string; umaAddress: string; userType: user_type; id?: string; createdAt?: string; isDeleted?: boolean; updatedAt?: string; }', + markdown: + "## list\n\n`client.users.list(createdAfter?: string, createdBefore?: string, cursor?: string, isIncludingDeleted?: boolean, limit?: number, platformUserId?: string, umaAddress?: string, updatedAfter?: string, updatedBefore?: string, userType?: 'INDIVIDUAL' | 'BUSINESS'): user | user`\n\n**get** `/users`\n\nRetrieve a list of users with optional filtering parameters. Returns all users that match\nthe specified filters. If no filters are provided, returns all users (paginated).\n\n\n### Parameters\n\n- `createdAfter?: string`\n Filter users created after this timestamp (inclusive)\n\n- `createdBefore?: string`\n Filter users created before this timestamp (inclusive)\n\n- `cursor?: string`\n Cursor for pagination (returned from previous request)\n\n- `isIncludingDeleted?: boolean`\n Whether to include deleted users in the results. Default is false.\n\n- `limit?: number`\n Maximum number of results to return (default 20, max 100)\n\n- `platformUserId?: string`\n Filter by platform-specific user identifier\n\n- `umaAddress?: string`\n Filter by UMA address\n\n- `updatedAfter?: string`\n Filter users updated after this timestamp (inclusive)\n\n- `updatedBefore?: string`\n Filter users updated before this timestamp (inclusive)\n\n- `userType?: 'INDIVIDUAL' | 'BUSINESS'`\n Filter by user type\n\n### Returns\n\n- `{ platformUserId: string; umaAddress: string; userType: user_type; id?: string; createdAt?: string; isDeleted?: boolean; updatedAt?: string; } | { platformUserId: string; umaAddress: string; userType: user_type; id?: string; createdAt?: string; isDeleted?: boolean; updatedAt?: string; }`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\n// Automatically fetches more pages as needed.\nfor await (const userListResponse of client.users.list()) {\n console.log(userListResponse);\n}\n```", + perLanguage: { + typescript: { + method: 'client.users.list', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\n// Automatically fetches more pages as needed.\nfor await (const userListResponse of client.users.list()) {\n console.log(userListResponse);\n}", + }, + kotlin: { + method: 'users().list', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.users.UserListPage\nimport com.lightspark.umaaas.models.users.UserListParams\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val page: UserListPage = client.users().list()\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/users \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET"', + }, + }, + }, + { + name: 'retrieve', + endpoint: '/users/{userId}', + httpMethod: 'get', + summary: 'Get user by ID', + description: 'Retrieve a user by their system-generated ID', + stainlessPath: '(resource) users > (method) retrieve', + qualified: 'client.users.retrieve', + params: ['userId: string;'], + response: + '{ platformUserId: string; umaAddress: string; userType: user_type; id?: string; createdAt?: string; isDeleted?: boolean; updatedAt?: string; } | { platformUserId: string; umaAddress: string; userType: user_type; id?: string; createdAt?: string; isDeleted?: boolean; updatedAt?: string; }', + markdown: + "## retrieve\n\n`client.users.retrieve(userId: string): user | user`\n\n**get** `/users/{userId}`\n\nRetrieve a user by their system-generated ID\n\n### Parameters\n\n- `userId: string`\n\n### Returns\n\n- `{ platformUserId: string; umaAddress: string; userType: user_type; id?: string; createdAt?: string; isDeleted?: boolean; updatedAt?: string; } | { platformUserId: string; umaAddress: string; userType: user_type; id?: string; createdAt?: string; isDeleted?: boolean; updatedAt?: string; }`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst user = await client.users.retrieve('userId');\n\nconsole.log(user);\n```", + perLanguage: { + typescript: { + method: 'client.users.retrieve', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst user = await client.users.retrieve('userId');\n\nconsole.log(user);", + }, + kotlin: { + method: 'users().retrieve', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.users.UserRetrieveParams\nimport com.lightspark.umaaas.models.users.UserRetrieveResponse\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val user: UserRetrieveResponse = client.users().retrieve("userId")\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/users/$USER_ID \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET"', + }, + }, + }, + { + name: 'update', + endpoint: '/users/{userId}', + httpMethod: 'patch', + summary: 'Update user by ID', + description: "Update a user's metadata by their system-generated ID", + stainlessPath: '(resource) users > (method) update', + qualified: 'client.users.update', + params: [ + 'userId: string;', + "body: { address?: { country: string; line1: string; postalCode: string; city?: string; line2?: string; state?: string; town?: string; }; bankAccountInfo?: { bankName: string; clabeNumber: string; accountHolderName?: string; } & { accountType: bank_account_type; platformAccountId?: string; } | { accountCategory: 'CHECKING' | 'SAVINGS'; accountNumber: string; routingNumber: string; accountHolderName?: string; bankName?: string; } & { accountType: bank_account_type; platformAccountId?: string; } | { pixKey: string; pixKeyType: 'CPF' | 'CNPJ' | 'EMAIL' | 'PHONE' | 'RANDOM'; accountHolderName?: string; bankName?: string; } & { accountType: bank_account_type; platformAccountId?: string; } | { bankName: string; iban: string; accountHolderName?: string; swiftBic?: string; } & { accountType: bank_account_type; platformAccountId?: string; } | { accountType: bank_account_type; platformAccountId?: string; } | { vpa: string; accountHolderName?: string; } & { accountType: bank_account_type; platformAccountId?: string; }; birthDate?: string; fullName?: string; nationality?: string; umaAddress?: string; } | { address?: { country: string; line1: string; postalCode: string; city?: string; line2?: string; state?: string; town?: string; }; bankAccountInfo?: { bankName: string; clabeNumber: string; accountHolderName?: string; } & { accountType: bank_account_type; platformAccountId?: string; } | { accountCategory: 'CHECKING' | 'SAVINGS'; accountNumber: string; routingNumber: string; accountHolderName?: string; bankName?: string; } & { accountType: bank_account_type; platformAccountId?: string; } | { pixKey: string; pixKeyType: 'CPF' | 'CNPJ' | 'EMAIL' | 'PHONE' | 'RANDOM'; accountHolderName?: string; bankName?: string; } & { accountType: bank_account_type; platformAccountId?: string; } | { bankName: string; iban: string; accountHolderName?: string; swiftBic?: string; } & { accountType: bank_account_type; platformAccountId?: string; } | { accountType: bank_account_type; platformAccountId?: string; } | { vpa: string; accountHolderName?: string; } & { accountType: bank_account_type; platformAccountId?: string; }; businessInfo?: { legalName?: string; registrationNumber?: string; taxId?: string; }; umaAddress?: string; };", + ], + response: + '{ platformUserId: string; umaAddress: string; userType: user_type; id?: string; createdAt?: string; isDeleted?: boolean; updatedAt?: string; } | { platformUserId: string; umaAddress: string; userType: user_type; id?: string; createdAt?: string; isDeleted?: boolean; updatedAt?: string; }', + perLanguage: { + typescript: { + method: 'client.users.update', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst user = await client.users.update('userId', {\n address: {\n line1: '456 Market St',\n city: 'San Francisco',\n state: 'CA',\n postalCode: '94103',\n country: 'US',\n },\n bankAccountInfo: {\n accountType: 'US_ACCOUNT',\n bankName: 'Wells Fargo',\n platformAccountId: 'wf_checking_9012',\n },\n birthDate: '1985-06-15',\n fullName: 'John Smith',\n});\n\nconsole.log(user);", + }, + kotlin: { + method: 'users().update', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.users.UserUpdateParams\nimport com.lightspark.umaaas.models.users.UserUpdateResponse\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val params: UserUpdateParams = UserUpdateParams.builder()\n .userId("userId")\n .body(UserUpdateParams.Body.IndividualUpdate.builder().build())\n .build()\n val user: UserUpdateResponse = client.users().update(params)\n}', + }, + http: { + example: + "curl https://api.uma.money/umaaas/2025-05-15/users/$USER_ID \\\n -X PATCH \\\n -H 'Content-Type: application/json' \\\n -u \"$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET\" \\\n -d '{}'", + }, + }, + }, + { + name: 'delete', + endpoint: '/users/{userId}', + httpMethod: 'delete', + summary: 'Delete user by ID', + description: 'Delete a user by their system-generated ID', + stainlessPath: '(resource) users > (method) delete', + qualified: 'client.users.delete', + params: ['userId: string;'], + response: + '{ platformUserId: string; umaAddress: string; userType: user_type; id?: string; createdAt?: string; isDeleted?: boolean; updatedAt?: string; } | { platformUserId: string; umaAddress: string; userType: user_type; id?: string; createdAt?: string; isDeleted?: boolean; updatedAt?: string; }', + markdown: + "## delete\n\n`client.users.delete(userId: string): user | user`\n\n**delete** `/users/{userId}`\n\nDelete a user by their system-generated ID\n\n### Parameters\n\n- `userId: string`\n\n### Returns\n\n- `{ platformUserId: string; umaAddress: string; userType: user_type; id?: string; createdAt?: string; isDeleted?: boolean; updatedAt?: string; } | { platformUserId: string; umaAddress: string; userType: user_type; id?: string; createdAt?: string; isDeleted?: boolean; updatedAt?: string; }`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst user = await client.users.delete('userId');\n\nconsole.log(user);\n```", + perLanguage: { + typescript: { + method: 'client.users.delete', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst user = await client.users.delete('userId');\n\nconsole.log(user);", + }, + kotlin: { + method: 'users().delete', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.users.UserDeleteParams\nimport com.lightspark.umaaas.models.users.UserDeleteResponse\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val user: UserDeleteResponse = client.users().delete("userId")\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/users/$USER_ID \\\n -X DELETE \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET"', + }, + }, + }, + { + name: 'upload', + endpoint: '/users/bulk/csv', + httpMethod: 'post', + summary: 'Upload users via CSV file', + description: + 'Upload a CSV file containing user information for bulk creation. The CSV file should follow\na specific format with required and optional columns based on user type.\n\n### CSV Format\nThe CSV file should have the following columns:\n\nRequired columns for all users:\n- umaAddress: The user\'s UMA address (e.g., $john.doe@uma.domain.com)\n- platformUserId: Your platform\'s unique identifier for the user\n- userType: Either "INDIVIDUAL" or "BUSINESS"\n\nRequired columns for individual users:\n- fullName: Individual\'s full name\n- birthDate: Date of birth in YYYY-MM-DD format\n- addressLine1: Street address line 1\n- city: City\n- state: State/Province/Region\n- postalCode: Postal/ZIP code\n- country: Country code (ISO 3166-1 alpha-2)\n- accountType: Bank account type (CLABE, US_ACCOUNT, PIX, IBAN)\n- accountNumber: Bank account number\n- bankName: Name of the bank\n\nRequired columns for business users:\n- businessLegalName: Legal name of the business\n- addressLine1: Street address line 1\n- city: City\n- state: State/Province/Region\n- postalCode: Postal/ZIP code\n- country: Country code (ISO 3166-1 alpha-2)\n- accountType: Bank account type (CLABE, US_ACCOUNT, PIX, IBAN)\n- accountNumber: Bank account number\n- bankName: Name of the bank\n\nOptional columns for all users:\n- addressLine2: Street address line 2\n- platformAccountId: Your platform\'s identifier for the bank account\n- description: Optional description for the user\n\nOptional columns for individual users:\n- email: User\'s email address\n\nOptional columns for business users:\n- businessRegistrationNumber: Business registration number\n- businessTaxId: Tax identification number\n\nAdditional required columns based on account type:\n\nFor US_ACCOUNT:\n- routingNumber: ACH routing number (9 digits)\n- accountCategory: Either "CHECKING" or "SAVINGS"\n\nFor CLABE:\n- clabeNumber: 18-digit CLABE number\n\nFor PIX:\n- pixKey: PIX key value\n- pixKeyType: Type of PIX key (CPF, CNPJ, EMAIL, PHONE, RANDOM)\n\nFor IBAN:\n- iban: International Bank Account Number\n- swiftBic: SWIFT/BIC code (8 or 11 characters)\n\nSee the UserBankAccountInfo and UserInfo schemas for more details on the required and optional fields.\n\n### Example CSV\n```csv\numaAddress,platformUserId,userType,fullName,birthDate,addressLine1,city,state,postalCode,country,accountType,accountNumber,bankName,platformAccountId,businessLegalName,routingNumber,accountCategory\njohn.doe@uma.domain.com,user123,INDIVIDUAL,John Doe,1990-01-15,123 Main St,San Francisco,CA,94105,US,US_ACCOUNT,123456789,Chase Bank,chase_primary_1234,,222888888,SAVINGS\nacme@uma.domain.com,biz456,BUSINESS,,,400 Commerce Way,Austin,TX,78701,US,US_ACCOUNT,987654321,Bank of America,boa_business_5678,Acme Corp,121212121,CHECKING\n```\n\nThe upload process is asynchronous and will return a job ID that can be used to track progress.\nYou can monitor the job status using the `/users/bulk/jobs/{jobId}` endpoint.\n', + stainlessPath: '(resource) users.bulk > (method) upload', + qualified: 'client.users.bulk.upload', + params: ['file: string;'], + response: "{ jobId: string; status: 'PENDING' | 'PROCESSING'; }", + markdown: + "## upload\n\n`client.users.bulk.upload(file: string): { jobId: string; status: 'PENDING' | 'PROCESSING'; }`\n\n**post** `/users/bulk/csv`\n\nUpload a CSV file containing user information for bulk creation. The CSV file should follow\na specific format with required and optional columns based on user type.\n\n### CSV Format\nThe CSV file should have the following columns:\n\nRequired columns for all users:\n- umaAddress: The user's UMA address (e.g., $john.doe@uma.domain.com)\n- platformUserId: Your platform's unique identifier for the user\n- userType: Either \"INDIVIDUAL\" or \"BUSINESS\"\n\nRequired columns for individual users:\n- fullName: Individual's full name\n- birthDate: Date of birth in YYYY-MM-DD format\n- addressLine1: Street address line 1\n- city: City\n- state: State/Province/Region\n- postalCode: Postal/ZIP code\n- country: Country code (ISO 3166-1 alpha-2)\n- accountType: Bank account type (CLABE, US_ACCOUNT, PIX, IBAN)\n- accountNumber: Bank account number\n- bankName: Name of the bank\n\nRequired columns for business users:\n- businessLegalName: Legal name of the business\n- addressLine1: Street address line 1\n- city: City\n- state: State/Province/Region\n- postalCode: Postal/ZIP code\n- country: Country code (ISO 3166-1 alpha-2)\n- accountType: Bank account type (CLABE, US_ACCOUNT, PIX, IBAN)\n- accountNumber: Bank account number\n- bankName: Name of the bank\n\nOptional columns for all users:\n- addressLine2: Street address line 2\n- platformAccountId: Your platform's identifier for the bank account\n- description: Optional description for the user\n\nOptional columns for individual users:\n- email: User's email address\n\nOptional columns for business users:\n- businessRegistrationNumber: Business registration number\n- businessTaxId: Tax identification number\n\nAdditional required columns based on account type:\n\nFor US_ACCOUNT:\n- routingNumber: ACH routing number (9 digits)\n- accountCategory: Either \"CHECKING\" or \"SAVINGS\"\n\nFor CLABE:\n- clabeNumber: 18-digit CLABE number\n\nFor PIX:\n- pixKey: PIX key value\n- pixKeyType: Type of PIX key (CPF, CNPJ, EMAIL, PHONE, RANDOM)\n\nFor IBAN:\n- iban: International Bank Account Number\n- swiftBic: SWIFT/BIC code (8 or 11 characters)\n\nSee the UserBankAccountInfo and UserInfo schemas for more details on the required and optional fields.\n\n### Example CSV\n```csv\numaAddress,platformUserId,userType,fullName,birthDate,addressLine1,city,state,postalCode,country,accountType,accountNumber,bankName,platformAccountId,businessLegalName,routingNumber,accountCategory\njohn.doe@uma.domain.com,user123,INDIVIDUAL,John Doe,1990-01-15,123 Main St,San Francisco,CA,94105,US,US_ACCOUNT,123456789,Chase Bank,chase_primary_1234,,222888888,SAVINGS\nacme@uma.domain.com,biz456,BUSINESS,,,400 Commerce Way,Austin,TX,78701,US,US_ACCOUNT,987654321,Bank of America,boa_business_5678,Acme Corp,121212121,CHECKING\n```\n\nThe upload process is asynchronous and will return a job ID that can be used to track progress.\nYou can monitor the job status using the `/users/bulk/jobs/{jobId}` endpoint.\n\n\n### Parameters\n\n- `file: string`\n CSV file containing user information\n\n### Returns\n\n- `{ jobId: string; status: 'PENDING' | 'PROCESSING'; }`\n\n - `jobId: string`\n - `status: 'PENDING' | 'PROCESSING'`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst response = await client.users.bulk.upload({ file: fs.createReadStream('path/to/file') });\n\nconsole.log(response);\n```", + perLanguage: { + typescript: { + method: 'client.users.bulk.upload', + example: + "import fs from 'fs';\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst response = await client.users.bulk.upload({ file: fs.createReadStream('path/to/file') });\n\nconsole.log(response.jobId);", + }, + kotlin: { + method: 'users().bulk().upload', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.users.bulk.BulkUploadParams\nimport com.lightspark.umaaas.models.users.bulk.BulkUploadResponse\nimport java.io.ByteArrayInputStream\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val params: BulkUploadParams = BulkUploadParams.builder()\n .file("Example data".byteInputStream())\n .build()\n val response: BulkUploadResponse = client.users().bulk().upload(params)\n}', + }, + http: { + example: + "curl https://api.uma.money/umaaas/2025-05-15/users/bulk/csv \\\n -H 'Content-Type: multipart/form-data' \\\n -u \"$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET\" \\\n -F 'file=@/path/to/file'", + }, + }, + }, + { + name: 'get_job_status', + endpoint: '/users/bulk/jobs/{jobId}', + httpMethod: 'get', + summary: 'Get bulk import job status', + description: + 'Retrieve the current status and results of a bulk user import job. This endpoint can be used\nto track the progress of both CSV uploads.\n\nThe response includes:\n- Overall job status\n- Progress statistics\n- Detailed error information for failed entries\n- Completion timestamp when finished\n', + stainlessPath: '(resource) users.bulk > (method) get_job_status', + qualified: 'client.users.bulk.getJobStatus', + params: ['jobId: string;'], + response: + "{ jobId: string; progress: { failed: number; processed: number; successful: number; total: number; }; status: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED'; completedAt?: string; errors?: { correlationId: string; error: { code?: string; details?: object; message?: string; }; }[]; }", + markdown: + "## get_job_status\n\n`client.users.bulk.getJobStatus(jobId: string): { jobId: string; progress: object; status: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED'; completedAt?: string; errors?: object[]; }`\n\n**get** `/users/bulk/jobs/{jobId}`\n\nRetrieve the current status and results of a bulk user import job. This endpoint can be used\nto track the progress of both CSV uploads.\n\nThe response includes:\n- Overall job status\n- Progress statistics\n- Detailed error information for failed entries\n- Completion timestamp when finished\n\n\n### Parameters\n\n- `jobId: string`\n\n### Returns\n\n- `{ jobId: string; progress: { failed: number; processed: number; successful: number; total: number; }; status: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED'; completedAt?: string; errors?: { correlationId: string; error: { code?: string; details?: object; message?: string; }; }[]; }`\n\n - `jobId: string`\n - `progress: { failed: number; processed: number; successful: number; total: number; }`\n - `status: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED'`\n - `completedAt?: string`\n - `errors?: { correlationId: string; error: { code?: string; details?: object; message?: string; }; }[]`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst response = await client.users.bulk.getJobStatus('jobId');\n\nconsole.log(response);\n```", + perLanguage: { + typescript: { + method: 'client.users.bulk.getJobStatus', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst response = await client.users.bulk.getJobStatus('jobId');\n\nconsole.log(response.jobId);", + }, + kotlin: { + method: 'users().bulk().getJobStatus', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.users.bulk.BulkGetJobStatusParams\nimport com.lightspark.umaaas.models.users.bulk.BulkGetJobStatusResponse\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val response: BulkGetJobStatusResponse = client.users().bulk().getJobStatus("jobId")\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/users/bulk/jobs/$JOB_ID \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET"', + }, + }, + }, + { + name: 'create', + endpoint: '/tokens', + httpMethod: 'post', + summary: 'Create a new API token', + description: 'Create a new API token to access the UMAaaS APIs.', + stainlessPath: '(resource) tokens > (method) create', + qualified: 'client.tokens.create', + params: ['name: string;', "permissions: 'VIEW' | 'TRANSACT' | 'MANAGE'[];"], + response: + "{ id: string; clientId: string; createdAt: string; name: string; permissions: 'VIEW' | 'TRANSACT' | 'MANAGE'[]; updatedAt: string; clientSecret?: string; }", + markdown: + "## create\n\n`client.tokens.create(name: string, permissions: 'VIEW' | 'TRANSACT' | 'MANAGE'[]): { id: string; clientId: string; createdAt: string; name: string; permissions: permission[]; updatedAt: string; clientSecret?: string; }`\n\n**post** `/tokens`\n\nCreate a new API token to access the UMAaaS APIs.\n\n### Parameters\n\n- `name: string`\n Name of the token to help identify it\n\n- `permissions: 'VIEW' | 'TRANSACT' | 'MANAGE'[]`\n A list of permissions to grant to the token\n\n### Returns\n\n- `{ id: string; clientId: string; createdAt: string; name: string; permissions: 'VIEW' | 'TRANSACT' | 'MANAGE'[]; updatedAt: string; clientSecret?: string; }`\n\n - `id: string`\n - `clientId: string`\n - `createdAt: string`\n - `name: string`\n - `permissions: 'VIEW' | 'TRANSACT' | 'MANAGE'[]`\n - `updatedAt: string`\n - `clientSecret?: string`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst apiToken = await client.tokens.create({ name: 'Sandbox read-only', permissions: ['VIEW'] });\n\nconsole.log(apiToken);\n```", + perLanguage: { + typescript: { + method: 'client.tokens.create', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst apiToken = await client.tokens.create({ name: 'Sandbox read-only', permissions: ['VIEW'] });\n\nconsole.log(apiToken.id);", + }, + kotlin: { + method: 'tokens().create', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.tokens.ApiToken\nimport com.lightspark.umaaas.models.tokens.Permission\nimport com.lightspark.umaaas.models.tokens.TokenCreateParams\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val params: TokenCreateParams = TokenCreateParams.builder()\n .name("Sandbox read-only")\n .addPermission(Permission.VIEW)\n .build()\n val apiToken: ApiToken = client.tokens().create(params)\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/tokens \\\n -H \'Content-Type: application/json\' \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET" \\\n -d \'{\n "name": "Sandbox read-only",\n "permissions": [\n "VIEW"\n ]\n }\'', + }, + }, + }, + { + name: 'list', + endpoint: '/tokens', + httpMethod: 'get', + summary: 'List tokens', + description: + 'Retrieve a list of API tokens with optional filtering parameters. Returns all tokens that match\nthe specified filters. If no filters are provided, returns all tokens (paginated).\n', + stainlessPath: '(resource) tokens > (method) list', + qualified: 'client.tokens.list', + params: [ + 'createdAfter?: string;', + 'createdBefore?: string;', + 'cursor?: string;', + 'limit?: number;', + 'name?: string;', + 'updatedAfter?: string;', + 'updatedBefore?: string;', + ], + response: + "{ id: string; clientId: string; createdAt: string; name: string; permissions: 'VIEW' | 'TRANSACT' | 'MANAGE'[]; updatedAt: string; clientSecret?: string; }", + markdown: + "## list\n\n`client.tokens.list(createdAfter?: string, createdBefore?: string, cursor?: string, limit?: number, name?: string, updatedAfter?: string, updatedBefore?: string): { id: string; clientId: string; createdAt: string; name: string; permissions: permission[]; updatedAt: string; clientSecret?: string; }`\n\n**get** `/tokens`\n\nRetrieve a list of API tokens with optional filtering parameters. Returns all tokens that match\nthe specified filters. If no filters are provided, returns all tokens (paginated).\n\n\n### Parameters\n\n- `createdAfter?: string`\n Filter users created after this timestamp (inclusive)\n\n- `createdBefore?: string`\n Filter users created before this timestamp (inclusive)\n\n- `cursor?: string`\n Cursor for pagination (returned from previous request)\n\n- `limit?: number`\n Maximum number of results to return (default 20, max 100)\n\n- `name?: string`\n Filter by name of the token\n\n- `updatedAfter?: string`\n Filter users updated after this timestamp (inclusive)\n\n- `updatedBefore?: string`\n Filter users updated before this timestamp (inclusive)\n\n### Returns\n\n- `{ id: string; clientId: string; createdAt: string; name: string; permissions: 'VIEW' | 'TRANSACT' | 'MANAGE'[]; updatedAt: string; clientSecret?: string; }`\n\n - `id: string`\n - `clientId: string`\n - `createdAt: string`\n - `name: string`\n - `permissions: 'VIEW' | 'TRANSACT' | 'MANAGE'[]`\n - `updatedAt: string`\n - `clientSecret?: string`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\n// Automatically fetches more pages as needed.\nfor await (const apiToken of client.tokens.list()) {\n console.log(apiToken);\n}\n```", + perLanguage: { + typescript: { + method: 'client.tokens.list', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\n// Automatically fetches more pages as needed.\nfor await (const apiToken of client.tokens.list()) {\n console.log(apiToken.id);\n}", + }, + kotlin: { + method: 'tokens().list', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.tokens.TokenListPage\nimport com.lightspark.umaaas.models.tokens.TokenListParams\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val page: TokenListPage = client.tokens().list()\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/tokens \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET"', + }, + }, + }, + { + name: 'retrieve', + endpoint: '/tokens/{tokenId}', + httpMethod: 'get', + summary: 'Get API token by ID', + description: 'Retrieve an API token by their system-generated ID', + stainlessPath: '(resource) tokens > (method) retrieve', + qualified: 'client.tokens.retrieve', + params: ['tokenId: string;'], + response: + "{ id: string; clientId: string; createdAt: string; name: string; permissions: 'VIEW' | 'TRANSACT' | 'MANAGE'[]; updatedAt: string; clientSecret?: string; }", + markdown: + "## retrieve\n\n`client.tokens.retrieve(tokenId: string): { id: string; clientId: string; createdAt: string; name: string; permissions: permission[]; updatedAt: string; clientSecret?: string; }`\n\n**get** `/tokens/{tokenId}`\n\nRetrieve an API token by their system-generated ID\n\n### Parameters\n\n- `tokenId: string`\n\n### Returns\n\n- `{ id: string; clientId: string; createdAt: string; name: string; permissions: 'VIEW' | 'TRANSACT' | 'MANAGE'[]; updatedAt: string; clientSecret?: string; }`\n\n - `id: string`\n - `clientId: string`\n - `createdAt: string`\n - `name: string`\n - `permissions: 'VIEW' | 'TRANSACT' | 'MANAGE'[]`\n - `updatedAt: string`\n - `clientSecret?: string`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst apiToken = await client.tokens.retrieve('tokenId');\n\nconsole.log(apiToken);\n```", + perLanguage: { + typescript: { + method: 'client.tokens.retrieve', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst apiToken = await client.tokens.retrieve('tokenId');\n\nconsole.log(apiToken.id);", + }, + kotlin: { + method: 'tokens().retrieve', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.tokens.ApiToken\nimport com.lightspark.umaaas.models.tokens.TokenRetrieveParams\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val apiToken: ApiToken = client.tokens().retrieve("tokenId")\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/tokens/$TOKEN_ID \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET"', + }, + }, + }, + { + name: 'delete', + endpoint: '/tokens/{tokenId}', + httpMethod: 'delete', + summary: 'Delete API token by ID', + description: 'Delete an API token by their system-generated ID', + stainlessPath: '(resource) tokens > (method) delete', + qualified: 'client.tokens.delete', + params: ['tokenId: string;'], + markdown: + "## delete\n\n`client.tokens.delete(tokenId: string): void`\n\n**delete** `/tokens/{tokenId}`\n\nDelete an API token by their system-generated ID\n\n### Parameters\n\n- `tokenId: string`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nawait client.tokens.delete('tokenId')\n```", + perLanguage: { + typescript: { + method: 'client.tokens.delete', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nawait client.tokens.delete('tokenId');", + }, + kotlin: { + method: 'tokens().delete', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.tokens.TokenDeleteParams\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n client.tokens().delete("tokenId")\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/tokens/$TOKEN_ID \\\n -X DELETE \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET"', + }, + }, + }, + { + name: 'retrieve', + endpoint: '/config', + httpMethod: 'get', + summary: 'Get platform configuration', + description: 'Retrieve the current platform configuration', + stainlessPath: '(resource) config > (method) retrieve', + qualified: 'client.config.retrieve', + response: + '{ id?: string; createdAt?: string; proxyUmaaasSubdomain?: string; supportedCurrencies?: { currencyCode: string; enabledTransactionTypes: transaction_type[]; maxAmount: number; minAmount: number; requiredCounterpartyFields: counterparty_field_definition[]; umaProviderRequiredCounterpartyUserFields?: user_info_field_name[]; umaProviderRequiredUserFields?: user_info_field_name[]; }[]; umaDomain?: string; updatedAt?: string; webhookEndpoint?: string; }', + markdown: + "## retrieve\n\n`client.config.retrieve(): { id?: string; createdAt?: string; proxyUmaaasSubdomain?: string; supportedCurrencies?: platform_currency_config[]; umaDomain?: string; updatedAt?: string; webhookEndpoint?: string; }`\n\n**get** `/config`\n\nRetrieve the current platform configuration\n\n### Returns\n\n- `{ id?: string; createdAt?: string; proxyUmaaasSubdomain?: string; supportedCurrencies?: { currencyCode: string; enabledTransactionTypes: transaction_type[]; maxAmount: number; minAmount: number; requiredCounterpartyFields: counterparty_field_definition[]; umaProviderRequiredCounterpartyUserFields?: user_info_field_name[]; umaProviderRequiredUserFields?: user_info_field_name[]; }[]; umaDomain?: string; updatedAt?: string; webhookEndpoint?: string; }`\n\n - `id?: string`\n - `createdAt?: string`\n - `proxyUmaaasSubdomain?: string`\n - `supportedCurrencies?: { currencyCode: string; enabledTransactionTypes: 'INCOMING' | 'OUTGOING'[]; maxAmount: number; minAmount: number; requiredCounterpartyFields: { mandatory: boolean; name: user_info_field_name; }[]; umaProviderRequiredCounterpartyUserFields?: string[]; umaProviderRequiredUserFields?: string[]; }[]`\n - `umaDomain?: string`\n - `updatedAt?: string`\n - `webhookEndpoint?: string`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst platformConfig = await client.config.retrieve();\n\nconsole.log(platformConfig);\n```", + perLanguage: { + typescript: { + method: 'client.config.retrieve', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst platformConfig = await client.config.retrieve();\n\nconsole.log(platformConfig.id);", + }, + kotlin: { + method: 'config().retrieve', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.config.ConfigRetrieveParams\nimport com.lightspark.umaaas.models.config.PlatformConfig\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val platformConfig: PlatformConfig = client.config().retrieve()\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/config \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET"', + }, + }, + }, + { + name: 'update', + endpoint: '/config', + httpMethod: 'patch', + summary: 'Update platform configuration', + description: 'Update the platform configuration settings', + stainlessPath: '(resource) config > (method) update', + qualified: 'client.config.update', + params: [ + "supportedCurrencies?: { currencyCode: string; enabledTransactionTypes: 'INCOMING' | 'OUTGOING'[]; maxAmount: number; minAmount: number; requiredCounterpartyFields: { mandatory: boolean; name: user_info_field_name; }[]; umaProviderRequiredCounterpartyUserFields?: string[]; umaProviderRequiredUserFields?: string[]; }[];", + 'umaDomain?: string;', + 'webhookEndpoint?: string;', + ], + response: + '{ id?: string; createdAt?: string; proxyUmaaasSubdomain?: string; supportedCurrencies?: { currencyCode: string; enabledTransactionTypes: transaction_type[]; maxAmount: number; minAmount: number; requiredCounterpartyFields: counterparty_field_definition[]; umaProviderRequiredCounterpartyUserFields?: user_info_field_name[]; umaProviderRequiredUserFields?: user_info_field_name[]; }[]; umaDomain?: string; updatedAt?: string; webhookEndpoint?: string; }', + markdown: + "## update\n\n`client.config.update(supportedCurrencies?: { currencyCode: string; enabledTransactionTypes: transaction_type[]; maxAmount: number; minAmount: number; requiredCounterpartyFields: counterparty_field_definition[]; umaProviderRequiredCounterpartyUserFields?: user_info_field_name[]; umaProviderRequiredUserFields?: user_info_field_name[]; }[], umaDomain?: string, webhookEndpoint?: string): { id?: string; createdAt?: string; proxyUmaaasSubdomain?: string; supportedCurrencies?: platform_currency_config[]; umaDomain?: string; updatedAt?: string; webhookEndpoint?: string; }`\n\n**patch** `/config`\n\nUpdate the platform configuration settings\n\n### Parameters\n\n- `supportedCurrencies?: { currencyCode: string; enabledTransactionTypes: 'INCOMING' | 'OUTGOING'[]; maxAmount: number; minAmount: number; requiredCounterpartyFields: { mandatory: boolean; name: user_info_field_name; }[]; umaProviderRequiredCounterpartyUserFields?: string[]; umaProviderRequiredUserFields?: string[]; }[]`\n\n- `umaDomain?: string`\n\n- `webhookEndpoint?: string`\n\n### Returns\n\n- `{ id?: string; createdAt?: string; proxyUmaaasSubdomain?: string; supportedCurrencies?: { currencyCode: string; enabledTransactionTypes: transaction_type[]; maxAmount: number; minAmount: number; requiredCounterpartyFields: counterparty_field_definition[]; umaProviderRequiredCounterpartyUserFields?: user_info_field_name[]; umaProviderRequiredUserFields?: user_info_field_name[]; }[]; umaDomain?: string; updatedAt?: string; webhookEndpoint?: string; }`\n\n - `id?: string`\n - `createdAt?: string`\n - `proxyUmaaasSubdomain?: string`\n - `supportedCurrencies?: { currencyCode: string; enabledTransactionTypes: 'INCOMING' | 'OUTGOING'[]; maxAmount: number; minAmount: number; requiredCounterpartyFields: { mandatory: boolean; name: user_info_field_name; }[]; umaProviderRequiredCounterpartyUserFields?: string[]; umaProviderRequiredUserFields?: string[]; }[]`\n - `umaDomain?: string`\n - `updatedAt?: string`\n - `webhookEndpoint?: string`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst platformConfig = await client.config.update();\n\nconsole.log(platformConfig);\n```", + perLanguage: { + typescript: { + method: 'client.config.update', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst platformConfig = await client.config.update({\n supportedCurrencies: [\n {\n currencyCode: 'USD',\n minAmount: 100,\n maxAmount: 1000000,\n enabledTransactionTypes: ['OUTGOING', 'INCOMING'],\n requiredCounterpartyFields: [\n { name: 'FULL_NAME', mandatory: true },\n { name: 'NATIONALITY', mandatory: true },\n { name: 'BIRTH_DATE', mandatory: true },\n ],\n },\n ],\n umaDomain: 'mycompany.com',\n webhookEndpoint: 'https://api.mycompany.com/webhooks/uma',\n});\n\nconsole.log(platformConfig.id);", + }, + kotlin: { + method: 'config().update', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.config.ConfigUpdateParams\nimport com.lightspark.umaaas.models.config.PlatformConfig\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val platformConfig: PlatformConfig = client.config().update()\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/config \\\n -X PATCH \\\n -H \'Content-Type: application/json\' \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET" \\\n -d \'{\n "supportedCurrencies": [\n {\n "currencyCode": "USD",\n "enabledTransactionTypes": [\n "OUTGOING",\n "INCOMING"\n ],\n "maxAmount": 1000000,\n "minAmount": 100,\n "requiredCounterpartyFields": [\n {\n "mandatory": true,\n "name": "FULL_NAME"\n },\n {\n "mandatory": true,\n "name": "NATIONALITY"\n },\n {\n "mandatory": true,\n "name": "BIRTH_DATE"\n }\n ]\n }\n ],\n "umaDomain": "mycompany.com",\n "webhookEndpoint": "https://api.mycompany.com/webhooks/uma"\n }\'', + }, + }, + }, + { + name: 'send_test', + endpoint: '/webhooks/test', + httpMethod: 'post', + summary: 'Send a test webhook', + description: 'Send a test webhook to the configured endpoint', + stainlessPath: '(resource) webhooks > (method) send_test', + qualified: 'client.webhooks.sendTest', + response: '{ response_status: number; response_body?: string; url?: string; }', + markdown: + "## send_test\n\n`client.webhooks.sendTest(): { response_status: number; response_body?: string; url?: string; }`\n\n**post** `/webhooks/test`\n\nSend a test webhook to the configured endpoint\n\n### Returns\n\n- `{ response_status: number; response_body?: string; url?: string; }`\n\n - `response_status: number`\n - `response_body?: string`\n - `url?: string`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst response = await client.webhooks.sendTest();\n\nconsole.log(response);\n```", + perLanguage: { + typescript: { + method: 'client.webhooks.sendTest', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst response = await client.webhooks.sendTest();\n\nconsole.log(response.response_status);", + }, + kotlin: { + method: 'webhooks().sendTest', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.webhooks.WebhookSendTestParams\nimport com.lightspark.umaaas.models.webhooks.WebhookSendTestResponse\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val response: WebhookSendTestResponse = client.webhooks().sendTest()\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/webhooks/test \\\n -X POST \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET"', + }, + }, + }, + { + name: 'retrieve', + endpoint: '/transactions/{transactionId}', + httpMethod: 'get', + summary: 'Get transaction by ID', + description: 'Retrieve detailed information about a specific transaction', + stainlessPath: '(resource) transactions > (method) retrieve', + qualified: 'client.transactions.retrieve', + params: ['transactionId: string;'], + response: + "{ id: string; platformUserId: string; receiverUmaAddress: string; senderUmaAddress: string; status: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED'; type: 'INCOMING' | 'OUTGOING'; userId: string; counterpartyInformation?: object; createdAt?: string; description?: string; settledAt?: string; }", + markdown: + "## retrieve\n\n`client.transactions.retrieve(transactionId: string): { id: string; platformUserId: string; receiverUmaAddress: string; senderUmaAddress: string; status: transaction_status; type: transaction_type; userId: string; counterpartyInformation?: object; createdAt?: string; description?: string; settledAt?: string; }`\n\n**get** `/transactions/{transactionId}`\n\nRetrieve detailed information about a specific transaction\n\n### Parameters\n\n- `transactionId: string`\n\n### Returns\n\n- `{ id: string; platformUserId: string; receiverUmaAddress: string; senderUmaAddress: string; status: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED'; type: 'INCOMING' | 'OUTGOING'; userId: string; counterpartyInformation?: object; createdAt?: string; description?: string; settledAt?: string; }`\n\n - `id: string`\n - `platformUserId: string`\n - `receiverUmaAddress: string`\n - `senderUmaAddress: string`\n - `status: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED'`\n - `type: 'INCOMING' | 'OUTGOING'`\n - `userId: string`\n - `counterpartyInformation?: object`\n - `createdAt?: string`\n - `description?: string`\n - `settledAt?: string`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst transaction = await client.transactions.retrieve('transactionId');\n\nconsole.log(transaction);\n```", + perLanguage: { + typescript: { + method: 'client.transactions.retrieve', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst transaction = await client.transactions.retrieve('transactionId');\n\nconsole.log(transaction.id);", + }, + kotlin: { + method: 'transactions().retrieve', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.transactions.Transaction\nimport com.lightspark.umaaas.models.transactions.TransactionRetrieveParams\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val transaction: Transaction = client.transactions().retrieve("transactionId")\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/transactions/$TRANSACTION_ID \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET"', + }, + }, + }, + { + name: 'list', + endpoint: '/transactions', + httpMethod: 'get', + summary: 'List transactions', + description: + 'Retrieve a paginated list of transactions with optional filtering.\nThe transactions can be filtered by user ID, platform user ID, UMA address, \ndate range, status, and transaction type.\n', + stainlessPath: '(resource) transactions > (method) list', + qualified: 'client.transactions.list', + params: [ + 'cursor?: string;', + 'endDate?: string;', + 'limit?: number;', + 'platformUserId?: string;', + 'receiverUmaAddress?: string;', + 'reference?: string;', + 'senderUmaAddress?: string;', + "sortOrder?: 'asc' | 'desc';", + 'startDate?: string;', + "status?: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED';", + "type?: 'INCOMING' | 'OUTGOING';", + 'umaAddress?: string;', + 'userId?: string;', + ], + response: + "{ id: string; platformUserId: string; receiverUmaAddress: string; senderUmaAddress: string; status: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED'; type: 'INCOMING' | 'OUTGOING'; userId: string; counterpartyInformation?: object; createdAt?: string; description?: string; settledAt?: string; }", + markdown: + "## list\n\n`client.transactions.list(cursor?: string, endDate?: string, limit?: number, platformUserId?: string, receiverUmaAddress?: string, reference?: string, senderUmaAddress?: string, sortOrder?: 'asc' | 'desc', startDate?: string, status?: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED', type?: 'INCOMING' | 'OUTGOING', umaAddress?: string, userId?: string): { id: string; platformUserId: string; receiverUmaAddress: string; senderUmaAddress: string; status: transaction_status; type: transaction_type; userId: string; counterpartyInformation?: object; createdAt?: string; description?: string; settledAt?: string; }`\n\n**get** `/transactions`\n\nRetrieve a paginated list of transactions with optional filtering.\nThe transactions can be filtered by user ID, platform user ID, UMA address, \ndate range, status, and transaction type.\n\n\n### Parameters\n\n- `cursor?: string`\n Cursor for pagination (returned from previous request)\n\n- `endDate?: string`\n Filter by end date (inclusive) in ISO 8601 format\n\n- `limit?: number`\n Maximum number of results to return (default 20, max 100)\n\n- `platformUserId?: string`\n Filter by platform-specific user ID\n\n- `receiverUmaAddress?: string`\n Filter by receiver UMA address\n\n- `reference?: string`\n Filter by reference\n\n- `senderUmaAddress?: string`\n Filter by sender UMA address\n\n- `sortOrder?: 'asc' | 'desc'`\n Order to sort results in\n\n- `startDate?: string`\n Filter by start date (inclusive) in ISO 8601 format\n\n- `status?: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED'`\n Filter by transaction status\n\n- `type?: 'INCOMING' | 'OUTGOING'`\n Filter by transaction type\n\n- `umaAddress?: string`\n Filter by UMA address (either sender or receiver)\n\n- `userId?: string`\n Filter by system user ID\n\n### Returns\n\n- `{ id: string; platformUserId: string; receiverUmaAddress: string; senderUmaAddress: string; status: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED'; type: 'INCOMING' | 'OUTGOING'; userId: string; counterpartyInformation?: object; createdAt?: string; description?: string; settledAt?: string; }`\n\n - `id: string`\n - `platformUserId: string`\n - `receiverUmaAddress: string`\n - `senderUmaAddress: string`\n - `status: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED'`\n - `type: 'INCOMING' | 'OUTGOING'`\n - `userId: string`\n - `counterpartyInformation?: object`\n - `createdAt?: string`\n - `description?: string`\n - `settledAt?: string`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\n// Automatically fetches more pages as needed.\nfor await (const transaction of client.transactions.list()) {\n console.log(transaction);\n}\n```", + perLanguage: { + typescript: { + method: 'client.transactions.list', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\n// Automatically fetches more pages as needed.\nfor await (const transaction of client.transactions.list()) {\n console.log(transaction.id);\n}", + }, + kotlin: { + method: 'transactions().list', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.transactions.TransactionListPage\nimport com.lightspark.umaaas.models.transactions.TransactionListParams\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val page: TransactionListPage = client.transactions().list()\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/transactions \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET"', + }, + }, + }, + { + name: 'approve', + endpoint: '/transactions/{transactionId}/approve', + httpMethod: 'post', + summary: 'Approve a pending incoming payment', + description: + 'Approve a pending incoming payment that was previously acknowledged with a 202 response.\nThis endpoint allows platforms to asynchronously approve payments after async processing.\n', + stainlessPath: '(resource) transactions > (method) approve', + qualified: 'client.transactions.approve', + params: ['transactionId: string;', 'receiverUserInfo?: object;'], + response: + "{ id: string; platformUserId: string; receiverUmaAddress: string; senderUmaAddress: string; status: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED'; type: 'INCOMING' | 'OUTGOING'; userId: string; counterpartyInformation?: object; createdAt?: string; description?: string; settledAt?: string; }", + markdown: + "## approve\n\n`client.transactions.approve(transactionId: string, receiverUserInfo?: object): object`\n\n**post** `/transactions/{transactionId}/approve`\n\nApprove a pending incoming payment that was previously acknowledged with a 202 response.\nThis endpoint allows platforms to asynchronously approve payments after async processing.\n\n\n### Parameters\n\n- `transactionId: string`\n\n- `receiverUserInfo?: object`\n Information about the recipient, provided by the platform if requested in the original webhook via `requestedReceiverUserInfoFields`.\n\n### Returns\n\n- `{ id: string; platformUserId: string; receiverUmaAddress: string; senderUmaAddress: string; status: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED'; type: 'INCOMING' | 'OUTGOING'; userId: string; counterpartyInformation?: object; createdAt?: string; description?: string; settledAt?: string; }`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst incomingTransaction = await client.transactions.approve('transactionId');\n\nconsole.log(incomingTransaction);\n```", + perLanguage: { + typescript: { + method: 'client.transactions.approve', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst incomingTransaction = await client.transactions.approve('transactionId');\n\nconsole.log(incomingTransaction);", + }, + kotlin: { + method: 'transactions().approve', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.transactions.IncomingTransaction\nimport com.lightspark.umaaas.models.transactions.TransactionApproveParams\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val incomingTransaction: IncomingTransaction = client.transactions().approve("transactionId")\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/transactions/$TRANSACTION_ID/approve \\\n -X POST \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET"', + }, + }, + }, + { + name: 'reject', + endpoint: '/transactions/{transactionId}/reject', + httpMethod: 'post', + summary: 'Reject a pending incoming payment', + description: + 'Reject a pending incoming payment that was previously acknowledged with a 202 response.\nThis endpoint allows platforms to asynchronously reject payments after additional processing.\n', + stainlessPath: '(resource) transactions > (method) reject', + qualified: 'client.transactions.reject', + params: ['transactionId: string;', 'reason?: string;'], + response: + "{ id: string; platformUserId: string; receiverUmaAddress: string; senderUmaAddress: string; status: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED'; type: 'INCOMING' | 'OUTGOING'; userId: string; counterpartyInformation?: object; createdAt?: string; description?: string; settledAt?: string; }", + markdown: + "## reject\n\n`client.transactions.reject(transactionId: string, reason?: string): object`\n\n**post** `/transactions/{transactionId}/reject`\n\nReject a pending incoming payment that was previously acknowledged with a 202 response.\nThis endpoint allows platforms to asynchronously reject payments after additional processing.\n\n\n### Parameters\n\n- `transactionId: string`\n\n- `reason?: string`\n Optional reason for rejecting the payment. This is just for debugging purposes or can be used for a platform's own purposes.\n\n### Returns\n\n- `{ id: string; platformUserId: string; receiverUmaAddress: string; senderUmaAddress: string; status: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED'; type: 'INCOMING' | 'OUTGOING'; userId: string; counterpartyInformation?: object; createdAt?: string; description?: string; settledAt?: string; }`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst incomingTransaction = await client.transactions.reject('transactionId');\n\nconsole.log(incomingTransaction);\n```", + perLanguage: { + typescript: { + method: 'client.transactions.reject', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst incomingTransaction = await client.transactions.reject('transactionId');\n\nconsole.log(incomingTransaction);", + }, + kotlin: { + method: 'transactions().reject', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.transactions.IncomingTransaction\nimport com.lightspark.umaaas.models.transactions.TransactionRejectParams\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val incomingTransaction: IncomingTransaction = client.transactions().reject("transactionId")\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/transactions/$TRANSACTION_ID/reject \\\n -X POST \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET"', + }, + }, + }, + { + name: 'lookup', + endpoint: '/receiver/{receiverUmaAddress}', + httpMethod: 'get', + summary: 'Look up a UMA address for payment', + description: + 'Lookup a receiving UMA address to determine supported currencies and exchange rates.\nThis endpoint helps platforms determine what currencies they can send to a given UMA address.\n', + stainlessPath: '(resource) receiver > (method) lookup', + qualified: 'client.receiver.lookup', + params: ['receiverUmaAddress: string;', 'senderUmaAddress?: string;', 'userId?: string;'], + response: + "{ kycStatus: 'UNKNOWN' | 'NOT_VERIFIED' | 'PENDING' | 'VERIFIED'; lookupId: string; receiverUmaAddress: string; supportedCurrencies: { currency: object; estimatedExchangeRate: number; max: number; min: number; }[]; bankAccountNameMatchingStatus?: 'UNKNOWN' | 'NOT_MATCHED' | 'MATCHED'; requiredPayerDataFields?: { mandatory: boolean; name: user_info_field_name; }[]; }", + markdown: + "## lookup\n\n`client.receiver.lookup(receiverUmaAddress: string, senderUmaAddress?: string, userId?: string): { kycStatus: 'UNKNOWN' | 'NOT_VERIFIED' | 'PENDING' | 'VERIFIED'; lookupId: string; receiverUmaAddress: string; supportedCurrencies: object[]; bankAccountNameMatchingStatus?: 'UNKNOWN' | 'NOT_MATCHED' | 'MATCHED'; requiredPayerDataFields?: counterparty_field_definition[]; }`\n\n**get** `/receiver/{receiverUmaAddress}`\n\nLookup a receiving UMA address to determine supported currencies and exchange rates.\nThis endpoint helps platforms determine what currencies they can send to a given UMA address.\n\n\n### Parameters\n\n- `receiverUmaAddress: string`\n\n- `senderUmaAddress?: string`\n UMA address of the sender (optional if userId is provided)\n\n- `userId?: string`\n System ID of the sender (optional if senderUmaAddress is provided)\n\n### Returns\n\n- `{ kycStatus: 'UNKNOWN' | 'NOT_VERIFIED' | 'PENDING' | 'VERIFIED'; lookupId: string; receiverUmaAddress: string; supportedCurrencies: { currency: object; estimatedExchangeRate: number; max: number; min: number; }[]; bankAccountNameMatchingStatus?: 'UNKNOWN' | 'NOT_MATCHED' | 'MATCHED'; requiredPayerDataFields?: { mandatory: boolean; name: user_info_field_name; }[]; }`\n\n - `kycStatus: 'UNKNOWN' | 'NOT_VERIFIED' | 'PENDING' | 'VERIFIED'`\n - `lookupId: string`\n - `receiverUmaAddress: string`\n - `supportedCurrencies: { currency: { code?: string; decimals?: number; name?: string; symbol?: string; }; estimatedExchangeRate: number; max: number; min: number; }[]`\n - `bankAccountNameMatchingStatus?: 'UNKNOWN' | 'NOT_MATCHED' | 'MATCHED'`\n - `requiredPayerDataFields?: { mandatory: boolean; name: string; }[]`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst response = await client.receiver.lookup('receiverUmaAddress');\n\nconsole.log(response);\n```", + perLanguage: { + typescript: { + method: 'client.receiver.lookup', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst response = await client.receiver.lookup('receiverUmaAddress');\n\nconsole.log(response.kycStatus);", + }, + kotlin: { + method: 'receiver().lookup', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.receiver.ReceiverLookupParams\nimport com.lightspark.umaaas.models.receiver.ReceiverLookupResponse\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val response: ReceiverLookupResponse = client.receiver().lookup("receiverUmaAddress")\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/receiver/$RECEIVER_UMA_ADDRESS \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET"', + }, + }, + }, + { + name: 'create', + endpoint: '/quotes', + httpMethod: 'post', + summary: 'Create a payment quote', + description: + 'Generate a quote for a payment from one UMA address to another.\nThe quote locks in exchange rates and fees for a set period of time and provides\npayment instructions that can be used to execute the payment.\n\nDepending on the `lockedCurrencySide` parameter, either the sending amount or \nreceiving amount will be locked.\n\nThe returned quote includes payment instructions with the banking details\nneeded to execute the payment and fulfill the quote. These instructions\nmust be followed precisely, including any reference codes provided.\n', + stainlessPath: '(resource) quotes > (method) create', + qualified: 'client.quotes.create', + params: [ + 'lockedCurrencyAmount: number;', + "lockedCurrencySide: 'SENDING' | 'RECEIVING';", + 'lookupId: string;', + 'receivingCurrencyCode: string;', + 'sendingCurrencyCode: string;', + 'description?: string;', + 'senderUserInfo?: object;', + ], + response: + "{ exchangeRate: number; expiresAt: string; feesIncluded: number; paymentInstructions: { bankAccountInfo: payment_clabe_account_info | payment_us_account_info | payment_pix_account_info | payment_iban_account_info | payment_fbo_account_info | payment_upi_account_info; reference: string; instructionsNotes?: string; }; quoteId: string; receivingCurrency: { code?: string; decimals?: number; name?: string; symbol?: string; }; sendingCurrency: { code?: string; decimals?: number; name?: string; symbol?: string; }; totalReceivingAmount: number; totalSendingAmount: number; transactionId: string; counterpartyInformation?: object; originalQuoteId?: string; rateDetails?: { counterpartyFixedFee: number; counterpartyMultiplier: number; umaaasFixedFee: number; umaaasMultiplier: number; umaaasVariableFeeAmount: number; umaaasVariableFeeRate: number; }; status?: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'EXPIRED'; }", + markdown: + "## create\n\n`client.quotes.create(lockedCurrencyAmount: number, lockedCurrencySide: 'SENDING' | 'RECEIVING', lookupId: string, receivingCurrencyCode: string, sendingCurrencyCode: string, description?: string, senderUserInfo?: object): { exchangeRate: number; expiresAt: string; feesIncluded: number; paymentInstructions: payment_instructions; quoteId: string; receivingCurrency: currency; sendingCurrency: currency; totalReceivingAmount: number; totalSendingAmount: number; transactionId: string; counterpartyInformation?: object; originalQuoteId?: string; rateDetails?: outgoing_rate_details; status?: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'EXPIRED'; }`\n\n**post** `/quotes`\n\nGenerate a quote for a payment from one UMA address to another.\nThe quote locks in exchange rates and fees for a set period of time and provides\npayment instructions that can be used to execute the payment.\n\nDepending on the `lockedCurrencySide` parameter, either the sending amount or \nreceiving amount will be locked.\n\nThe returned quote includes payment instructions with the banking details\nneeded to execute the payment and fulfill the quote. These instructions\nmust be followed precisely, including any reference codes provided.\n\n\n### Parameters\n\n- `lockedCurrencyAmount: number`\n The amount to send/receive in the smallest unit of the locked currency (eg. cents). See `lockedCurrencySide` for more information.\n\n- `lockedCurrencySide: 'SENDING' | 'RECEIVING'`\n The side of the quote which should be locked and specified in the `lockedCurrencyAmount`. For example, if I want to send exactly $5 MXN from my wallet, I would set this to \"sending\", and the `lockedCurrencyAmount` to 500 (in cents). If I want the receiver to receive exactly $10 USD, I would set this to \"receiving\" and the `lockedCurrencyAmount` to 10000 (in cents).\n\n- `lookupId: string`\n Unique identifier for the prior receiver uma address lookup request.\n\n- `receivingCurrencyCode: string`\n Currency code for the receiving amount\n\n- `sendingCurrencyCode: string`\n Currency code for the sending amount\n\n- `description?: string`\n Optional description/memo for the payment\n\n- `senderUserInfo?: object`\n Key-value pairs of information about the sender which was requested by the counterparty (recipient) institution.\nAny fields specified in `requiredPayerDataFields` from the response of the `/receiver/{receiverUmaAddress}` (lookupUma) endpoint\nMUST be provided here if they were requested. If the counterparty (recipient) institution did not request any information,\nthis field can be omitted.\n\n\n### Returns\n\n- `{ exchangeRate: number; expiresAt: string; feesIncluded: number; paymentInstructions: { bankAccountInfo: payment_clabe_account_info | payment_us_account_info | payment_pix_account_info | payment_iban_account_info | payment_fbo_account_info | payment_upi_account_info; reference: string; instructionsNotes?: string; }; quoteId: string; receivingCurrency: { code?: string; decimals?: number; name?: string; symbol?: string; }; sendingCurrency: { code?: string; decimals?: number; name?: string; symbol?: string; }; totalReceivingAmount: number; totalSendingAmount: number; transactionId: string; counterpartyInformation?: object; originalQuoteId?: string; rateDetails?: { counterpartyFixedFee: number; counterpartyMultiplier: number; umaaasFixedFee: number; umaaasMultiplier: number; umaaasVariableFeeAmount: number; umaaasVariableFeeRate: number; }; status?: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'EXPIRED'; }`\n\n - `exchangeRate: number`\n - `expiresAt: string`\n - `feesIncluded: number`\n - `paymentInstructions: { bankAccountInfo: object & object | object & object | object & object | object & object | object | object & object; reference: string; instructionsNotes?: string; }`\n - `quoteId: string`\n - `receivingCurrency: { code?: string; decimals?: number; name?: string; symbol?: string; }`\n - `sendingCurrency: { code?: string; decimals?: number; name?: string; symbol?: string; }`\n - `totalReceivingAmount: number`\n - `totalSendingAmount: number`\n - `transactionId: string`\n - `counterpartyInformation?: object`\n - `originalQuoteId?: string`\n - `rateDetails?: { counterpartyFixedFee: number; counterpartyMultiplier: number; umaaasFixedFee: number; umaaasMultiplier: number; umaaasVariableFeeAmount: number; umaaasVariableFeeRate: number; }`\n - `status?: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'EXPIRED'`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst quote = await client.quotes.create({\n lockedCurrencyAmount: 1000,\n lockedCurrencySide: 'SENDING',\n lookupId: 'LookupRequest:019542f5-b3e7-1d02-0000-000000000009',\n receivingCurrencyCode: 'EUR',\n sendingCurrencyCode: 'USD',\n});\n\nconsole.log(quote);\n```", + perLanguage: { + typescript: { + method: 'client.quotes.create', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst quote = await client.quotes.create({\n lockedCurrencyAmount: 1000,\n lockedCurrencySide: 'SENDING',\n lookupId: 'LookupRequest:019542f5-b3e7-1d02-0000-000000000009',\n receivingCurrencyCode: 'EUR',\n sendingCurrencyCode: 'USD',\n description: 'Payment for invoice #1234',\n});\n\nconsole.log(quote.exchangeRate);", + }, + kotlin: { + method: 'quotes().create', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.quotes.Quote\nimport com.lightspark.umaaas.models.quotes.QuoteCreateParams\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val params: QuoteCreateParams = QuoteCreateParams.builder()\n .lockedCurrencyAmount(1000L)\n .lockedCurrencySide(QuoteCreateParams.LockedCurrencySide.SENDING)\n .lookupId("LookupRequest:019542f5-b3e7-1d02-0000-000000000009")\n .receivingCurrencyCode("EUR")\n .sendingCurrencyCode("USD")\n .build()\n val quote: Quote = client.quotes().create(params)\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/quotes \\\n -H \'Content-Type: application/json\' \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET" \\\n -d \'{\n "lockedCurrencyAmount": 1000,\n "lockedCurrencySide": "SENDING",\n "lookupId": "LookupRequest:019542f5-b3e7-1d02-0000-000000000009",\n "receivingCurrencyCode": "EUR",\n "sendingCurrencyCode": "USD",\n "description": "Payment for invoice #1234",\n "senderUserInfo": {\n "FULL_NAME": "bar",\n "NATIONALITY": "bar"\n }\n }\'', + }, + }, + }, + { + name: 'retrieve', + endpoint: '/quotes/{quoteId}', + httpMethod: 'get', + summary: 'Get quote by ID', + description: + 'Retrieve a quote by its ID. If the quote has been settled, it will include \nthe transaction ID. This allows clients to track the full lifecycle of a payment\nfrom quote creation to settlement.\n', + stainlessPath: '(resource) quotes > (method) retrieve', + qualified: 'client.quotes.retrieve', + params: ['quoteId: string;'], + response: + "{ exchangeRate: number; expiresAt: string; feesIncluded: number; paymentInstructions: { bankAccountInfo: payment_clabe_account_info | payment_us_account_info | payment_pix_account_info | payment_iban_account_info | payment_fbo_account_info | payment_upi_account_info; reference: string; instructionsNotes?: string; }; quoteId: string; receivingCurrency: { code?: string; decimals?: number; name?: string; symbol?: string; }; sendingCurrency: { code?: string; decimals?: number; name?: string; symbol?: string; }; totalReceivingAmount: number; totalSendingAmount: number; transactionId: string; counterpartyInformation?: object; originalQuoteId?: string; rateDetails?: { counterpartyFixedFee: number; counterpartyMultiplier: number; umaaasFixedFee: number; umaaasMultiplier: number; umaaasVariableFeeAmount: number; umaaasVariableFeeRate: number; }; status?: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'EXPIRED'; }", + markdown: + "## retrieve\n\n`client.quotes.retrieve(quoteId: string): { exchangeRate: number; expiresAt: string; feesIncluded: number; paymentInstructions: payment_instructions; quoteId: string; receivingCurrency: currency; sendingCurrency: currency; totalReceivingAmount: number; totalSendingAmount: number; transactionId: string; counterpartyInformation?: object; originalQuoteId?: string; rateDetails?: outgoing_rate_details; status?: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'EXPIRED'; }`\n\n**get** `/quotes/{quoteId}`\n\nRetrieve a quote by its ID. If the quote has been settled, it will include \nthe transaction ID. This allows clients to track the full lifecycle of a payment\nfrom quote creation to settlement.\n\n\n### Parameters\n\n- `quoteId: string`\n\n### Returns\n\n- `{ exchangeRate: number; expiresAt: string; feesIncluded: number; paymentInstructions: { bankAccountInfo: payment_clabe_account_info | payment_us_account_info | payment_pix_account_info | payment_iban_account_info | payment_fbo_account_info | payment_upi_account_info; reference: string; instructionsNotes?: string; }; quoteId: string; receivingCurrency: { code?: string; decimals?: number; name?: string; symbol?: string; }; sendingCurrency: { code?: string; decimals?: number; name?: string; symbol?: string; }; totalReceivingAmount: number; totalSendingAmount: number; transactionId: string; counterpartyInformation?: object; originalQuoteId?: string; rateDetails?: { counterpartyFixedFee: number; counterpartyMultiplier: number; umaaasFixedFee: number; umaaasMultiplier: number; umaaasVariableFeeAmount: number; umaaasVariableFeeRate: number; }; status?: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'EXPIRED'; }`\n\n - `exchangeRate: number`\n - `expiresAt: string`\n - `feesIncluded: number`\n - `paymentInstructions: { bankAccountInfo: object & object | object & object | object & object | object & object | object | object & object; reference: string; instructionsNotes?: string; }`\n - `quoteId: string`\n - `receivingCurrency: { code?: string; decimals?: number; name?: string; symbol?: string; }`\n - `sendingCurrency: { code?: string; decimals?: number; name?: string; symbol?: string; }`\n - `totalReceivingAmount: number`\n - `totalSendingAmount: number`\n - `transactionId: string`\n - `counterpartyInformation?: object`\n - `originalQuoteId?: string`\n - `rateDetails?: { counterpartyFixedFee: number; counterpartyMultiplier: number; umaaasFixedFee: number; umaaasMultiplier: number; umaaasVariableFeeAmount: number; umaaasVariableFeeRate: number; }`\n - `status?: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'EXPIRED'`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst quote = await client.quotes.retrieve('quoteId');\n\nconsole.log(quote);\n```", + perLanguage: { + typescript: { + method: 'client.quotes.retrieve', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst quote = await client.quotes.retrieve('quoteId');\n\nconsole.log(quote.exchangeRate);", + }, + kotlin: { + method: 'quotes().retrieve', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.quotes.Quote\nimport com.lightspark.umaaas.models.quotes.QuoteRetrieveParams\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val quote: Quote = client.quotes().retrieve("quoteId")\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/quotes/$QUOTE_ID \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET"', + }, + }, + }, + { + name: 'retry', + endpoint: '/quotes/{quoteId}/retry', + httpMethod: 'post', + summary: 'Retry an incomplete payment', + description: + "In the case where a customer is debited but the Lightning payment fails to complete, integrators can retry the payment using this endpoint. \n\nPayments retried with this endpoint will debit from the sender and deliver to the recipient the same amount as the original quote.\nAs UMA as a service does not persist customer PII, retries need to start with a lookup request to retrieve the original quote's recipient counter party data requirements then pass that sender information in the request body.\nBefore calling this endpoint, you should reach out to the UMA as a service team to investigate the underlying issue. As part of resolution, they'll update the transaction to the appropriate state. The quote / transaction to retry must be in a `FAILED` or `REFUNDED` state.\n", + stainlessPath: '(resource) quotes > (method) retry', + qualified: 'client.quotes.retry', + params: ['quoteId: string;', 'lookupId: string;', 'senderUserInfo?: object;'], + response: + "{ exchangeRate: number; expiresAt: string; feesIncluded: number; paymentInstructions: { bankAccountInfo: payment_clabe_account_info | payment_us_account_info | payment_pix_account_info | payment_iban_account_info | payment_fbo_account_info | payment_upi_account_info; reference: string; instructionsNotes?: string; }; quoteId: string; receivingCurrency: { code?: string; decimals?: number; name?: string; symbol?: string; }; sendingCurrency: { code?: string; decimals?: number; name?: string; symbol?: string; }; totalReceivingAmount: number; totalSendingAmount: number; transactionId: string; counterpartyInformation?: object; originalQuoteId?: string; rateDetails?: { counterpartyFixedFee: number; counterpartyMultiplier: number; umaaasFixedFee: number; umaaasMultiplier: number; umaaasVariableFeeAmount: number; umaaasVariableFeeRate: number; }; status?: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'EXPIRED'; }", + markdown: + "## retry\n\n`client.quotes.retry(quoteId: string, lookupId: string, senderUserInfo?: object): { exchangeRate: number; expiresAt: string; feesIncluded: number; paymentInstructions: payment_instructions; quoteId: string; receivingCurrency: currency; sendingCurrency: currency; totalReceivingAmount: number; totalSendingAmount: number; transactionId: string; counterpartyInformation?: object; originalQuoteId?: string; rateDetails?: outgoing_rate_details; status?: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'EXPIRED'; }`\n\n**post** `/quotes/{quoteId}/retry`\n\nIn the case where a customer is debited but the Lightning payment fails to complete, integrators can retry the payment using this endpoint. \n\nPayments retried with this endpoint will debit from the sender and deliver to the recipient the same amount as the original quote.\nAs UMA as a service does not persist customer PII, retries need to start with a lookup request to retrieve the original quote's recipient counter party data requirements then pass that sender information in the request body.\nBefore calling this endpoint, you should reach out to the UMA as a service team to investigate the underlying issue. As part of resolution, they'll update the transaction to the appropriate state. The quote / transaction to retry must be in a `FAILED` or `REFUNDED` state.\n\n\n### Parameters\n\n- `quoteId: string`\n\n- `lookupId: string`\n Unique identifier for the prior receiver uma address lookup request.\n\n- `senderUserInfo?: object`\n Key-value pairs of information about the sender which was requested by the counterparty (recipient) institution.\nAny fields specified in `requiredPayerDataFields` from the response of the `/receiver/{receiverUmaAddress}` (lookupUma) endpoint\nMUST be provided here if they were requested. If the counterparty (recipient) institution did not request any information,\nthis field can be omitted.\n\n\n### Returns\n\n- `{ exchangeRate: number; expiresAt: string; feesIncluded: number; paymentInstructions: { bankAccountInfo: payment_clabe_account_info | payment_us_account_info | payment_pix_account_info | payment_iban_account_info | payment_fbo_account_info | payment_upi_account_info; reference: string; instructionsNotes?: string; }; quoteId: string; receivingCurrency: { code?: string; decimals?: number; name?: string; symbol?: string; }; sendingCurrency: { code?: string; decimals?: number; name?: string; symbol?: string; }; totalReceivingAmount: number; totalSendingAmount: number; transactionId: string; counterpartyInformation?: object; originalQuoteId?: string; rateDetails?: { counterpartyFixedFee: number; counterpartyMultiplier: number; umaaasFixedFee: number; umaaasMultiplier: number; umaaasVariableFeeAmount: number; umaaasVariableFeeRate: number; }; status?: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'EXPIRED'; }`\n\n - `exchangeRate: number`\n - `expiresAt: string`\n - `feesIncluded: number`\n - `paymentInstructions: { bankAccountInfo: object & object | object & object | object & object | object & object | object | object & object; reference: string; instructionsNotes?: string; }`\n - `quoteId: string`\n - `receivingCurrency: { code?: string; decimals?: number; name?: string; symbol?: string; }`\n - `sendingCurrency: { code?: string; decimals?: number; name?: string; symbol?: string; }`\n - `totalReceivingAmount: number`\n - `totalSendingAmount: number`\n - `transactionId: string`\n - `counterpartyInformation?: object`\n - `originalQuoteId?: string`\n - `rateDetails?: { counterpartyFixedFee: number; counterpartyMultiplier: number; umaaasFixedFee: number; umaaasMultiplier: number; umaaasVariableFeeAmount: number; umaaasVariableFeeRate: number; }`\n - `status?: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'EXPIRED'`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst quote = await client.quotes.retry('quoteId', { lookupId: 'Lookup:019542f5-b3e7-1d02-0000-000000000009' });\n\nconsole.log(quote);\n```", + perLanguage: { + typescript: { + method: 'client.quotes.retry', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst quote = await client.quotes.retry('quoteId', {\n lookupId: 'Lookup:019542f5-b3e7-1d02-0000-000000000009',\n});\n\nconsole.log(quote.exchangeRate);", + }, + kotlin: { + method: 'quotes().retry', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.quotes.Quote\nimport com.lightspark.umaaas.models.quotes.QuoteRetryParams\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val params: QuoteRetryParams = QuoteRetryParams.builder()\n .quoteId("quoteId")\n .lookupId("Lookup:019542f5-b3e7-1d02-0000-000000000009")\n .build()\n val quote: Quote = client.quotes().retry(params)\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/quotes/$QUOTE_ID/retry \\\n -H \'Content-Type: application/json\' \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET" \\\n -d \'{\n "lookupId": "Lookup:019542f5-b3e7-1d02-0000-000000000009",\n "senderUserInfo": {\n "FULL_NAME": "bar",\n "NATIONALITY": "bar"\n }\n }\'', + }, + }, + }, + { + name: 'create', + endpoint: '/invitations', + httpMethod: 'post', + summary: 'Create an UMA invitation from a given platform user.', + description: 'Create an UMA invitation from a given platform user.\n', + stainlessPath: '(resource) invitations > (method) create', + qualified: 'client.invitations.create', + params: ['inviterUma: string;', 'amountToSend?: number;', 'expiresAt?: string;', 'firstName?: string;'], + response: + "{ code: string; createdAt: string; inviterUma: string; status: 'PENDING' | 'CLAIMED' | 'EXPIRED' | 'CANCELLED'; url: string; amountToSend?: { amount: number; currency: currency; }; claimedAt?: string; expiresAt?: string; firstName?: string; inviteeCountryCode?: string; inviteeUma?: string; }", + markdown: + "## create\n\n`client.invitations.create(inviterUma: string, amountToSend?: number, expiresAt?: string, firstName?: string): { code: string; createdAt: string; inviterUma: string; status: 'PENDING' | 'CLAIMED' | 'EXPIRED' | 'CANCELLED'; url: string; amountToSend?: currency_amount; claimedAt?: string; expiresAt?: string; firstName?: string; inviteeCountryCode?: string; inviteeUma?: string; }`\n\n**post** `/invitations`\n\nCreate an UMA invitation from a given platform user.\n\n\n### Parameters\n\n- `inviterUma: string`\n The UMA address of the user creating the invitation\n\n- `amountToSend?: number`\n An amount to send (in the smallest unit of the user's currency) to the invitee when the invitation is claimed.\nThis is optional and if not provided, the invitee will not receive any amount. Note that the actual sending of\nthe amount must be done by the inviter platform once the INVITATION_CLAIMED webhook is received. If the inviter\nplatform either does not send the payment or the payment fails, the invitee will not receive this amount. This\nfield is primarily used for display purposes on the claiming side of the invitation.\n\n\n- `expiresAt?: string`\n When the invitation expires (if at all)\n\n- `firstName?: string`\n First name of the inviter to show as part of the invite\n\n### Returns\n\n- `{ code: string; createdAt: string; inviterUma: string; status: 'PENDING' | 'CLAIMED' | 'EXPIRED' | 'CANCELLED'; url: string; amountToSend?: { amount: number; currency: currency; }; claimedAt?: string; expiresAt?: string; firstName?: string; inviteeCountryCode?: string; inviteeUma?: string; }`\n\n - `code: string`\n - `createdAt: string`\n - `inviterUma: string`\n - `status: 'PENDING' | 'CLAIMED' | 'EXPIRED' | 'CANCELLED'`\n - `url: string`\n - `amountToSend?: { amount: number; currency: { code?: string; decimals?: number; name?: string; symbol?: string; }; }`\n - `claimedAt?: string`\n - `expiresAt?: string`\n - `firstName?: string`\n - `inviteeCountryCode?: string`\n - `inviteeUma?: string`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst umaInvitation = await client.invitations.create({ inviterUma: '$inviter@uma.domain' });\n\nconsole.log(umaInvitation);\n```", + perLanguage: { + typescript: { + method: 'client.invitations.create', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst umaInvitation = await client.invitations.create({ inviterUma: '$inviter@uma.domain' });\n\nconsole.log(umaInvitation.code);", + }, + kotlin: { + method: 'invitations().create', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.invitations.InvitationCreateParams\nimport com.lightspark.umaaas.models.invitations.UmaInvitation\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val params: InvitationCreateParams = InvitationCreateParams.builder()\n .inviterUma("\\$inviter@uma.domain")\n .build()\n val umaInvitation: UmaInvitation = client.invitations().create(params)\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/invitations \\\n -H \'Content-Type: application/json\' \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET" \\\n -d \'{\n "inviterUma": "$inviter@uma.domain",\n "amountToSend": 12550,\n "expiresAt": "2023-09-01T14:30:00Z",\n "firstName": "Alice"\n }\'', + }, + }, + }, + { + name: 'retrieve', + endpoint: '/invitations/{invitationCode}', + httpMethod: 'get', + summary: 'Get a specific UMA invitation by code.', + description: 'Get a specific UMA invitation by code.\n', + stainlessPath: '(resource) invitations > (method) retrieve', + qualified: 'client.invitations.retrieve', + params: ['invitationCode: string;'], + response: + "{ code: string; createdAt: string; inviterUma: string; status: 'PENDING' | 'CLAIMED' | 'EXPIRED' | 'CANCELLED'; url: string; amountToSend?: { amount: number; currency: currency; }; claimedAt?: string; expiresAt?: string; firstName?: string; inviteeCountryCode?: string; inviteeUma?: string; }", + markdown: + "## retrieve\n\n`client.invitations.retrieve(invitationCode: string): { code: string; createdAt: string; inviterUma: string; status: 'PENDING' | 'CLAIMED' | 'EXPIRED' | 'CANCELLED'; url: string; amountToSend?: currency_amount; claimedAt?: string; expiresAt?: string; firstName?: string; inviteeCountryCode?: string; inviteeUma?: string; }`\n\n**get** `/invitations/{invitationCode}`\n\nGet a specific UMA invitation by code.\n\n\n### Parameters\n\n- `invitationCode: string`\n\n### Returns\n\n- `{ code: string; createdAt: string; inviterUma: string; status: 'PENDING' | 'CLAIMED' | 'EXPIRED' | 'CANCELLED'; url: string; amountToSend?: { amount: number; currency: currency; }; claimedAt?: string; expiresAt?: string; firstName?: string; inviteeCountryCode?: string; inviteeUma?: string; }`\n\n - `code: string`\n - `createdAt: string`\n - `inviterUma: string`\n - `status: 'PENDING' | 'CLAIMED' | 'EXPIRED' | 'CANCELLED'`\n - `url: string`\n - `amountToSend?: { amount: number; currency: { code?: string; decimals?: number; name?: string; symbol?: string; }; }`\n - `claimedAt?: string`\n - `expiresAt?: string`\n - `firstName?: string`\n - `inviteeCountryCode?: string`\n - `inviteeUma?: string`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst umaInvitation = await client.invitations.retrieve('invitationCode');\n\nconsole.log(umaInvitation);\n```", + perLanguage: { + typescript: { + method: 'client.invitations.retrieve', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst umaInvitation = await client.invitations.retrieve('invitationCode');\n\nconsole.log(umaInvitation.code);", + }, + kotlin: { + method: 'invitations().retrieve', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.invitations.InvitationRetrieveParams\nimport com.lightspark.umaaas.models.invitations.UmaInvitation\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val umaInvitation: UmaInvitation = client.invitations().retrieve("invitationCode")\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/invitations/$INVITATION_CODE \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET"', + }, + }, + }, + { + name: 'claim', + endpoint: '/invitations/{invitationCode}/claim', + httpMethod: 'post', + summary: 'Claim an UMA invitation', + description: + 'Claim an UMA invitation by associating it with an invitee UMA address.\n\nWhen an invitation is successfully claimed:\n1. The invitation status changes from PENDING to CLAIMED\n2. The invitee UMA address is associated with the invitation\n3. An INVITATION_CLAIMED webhook is triggered to notify the platform that created the invitation\n\nThis endpoint allows users to accept invitations sent to them by other UMA users.\n', + stainlessPath: '(resource) invitations > (method) claim', + qualified: 'client.invitations.claim', + params: ['invitationCode: string;', 'inviteeUma: string;'], + response: + "{ code: string; createdAt: string; inviterUma: string; status: 'PENDING' | 'CLAIMED' | 'EXPIRED' | 'CANCELLED'; url: string; amountToSend?: { amount: number; currency: currency; }; claimedAt?: string; expiresAt?: string; firstName?: string; inviteeCountryCode?: string; inviteeUma?: string; }", + markdown: + "## claim\n\n`client.invitations.claim(invitationCode: string, inviteeUma: string): { code: string; createdAt: string; inviterUma: string; status: 'PENDING' | 'CLAIMED' | 'EXPIRED' | 'CANCELLED'; url: string; amountToSend?: currency_amount; claimedAt?: string; expiresAt?: string; firstName?: string; inviteeCountryCode?: string; inviteeUma?: string; }`\n\n**post** `/invitations/{invitationCode}/claim`\n\nClaim an UMA invitation by associating it with an invitee UMA address.\n\nWhen an invitation is successfully claimed:\n1. The invitation status changes from PENDING to CLAIMED\n2. The invitee UMA address is associated with the invitation\n3. An INVITATION_CLAIMED webhook is triggered to notify the platform that created the invitation\n\nThis endpoint allows users to accept invitations sent to them by other UMA users.\n\n\n### Parameters\n\n- `invitationCode: string`\n\n- `inviteeUma: string`\n The UMA address of the user claiming the invitation\n\n### Returns\n\n- `{ code: string; createdAt: string; inviterUma: string; status: 'PENDING' | 'CLAIMED' | 'EXPIRED' | 'CANCELLED'; url: string; amountToSend?: { amount: number; currency: currency; }; claimedAt?: string; expiresAt?: string; firstName?: string; inviteeCountryCode?: string; inviteeUma?: string; }`\n\n - `code: string`\n - `createdAt: string`\n - `inviterUma: string`\n - `status: 'PENDING' | 'CLAIMED' | 'EXPIRED' | 'CANCELLED'`\n - `url: string`\n - `amountToSend?: { amount: number; currency: { code?: string; decimals?: number; name?: string; symbol?: string; }; }`\n - `claimedAt?: string`\n - `expiresAt?: string`\n - `firstName?: string`\n - `inviteeCountryCode?: string`\n - `inviteeUma?: string`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst umaInvitation = await client.invitations.claim('invitationCode', { inviteeUma: '$invitee@uma.domain' });\n\nconsole.log(umaInvitation);\n```", + perLanguage: { + typescript: { + method: 'client.invitations.claim', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst umaInvitation = await client.invitations.claim('invitationCode', {\n inviteeUma: '$invitee@uma.domain',\n});\n\nconsole.log(umaInvitation.code);", + }, + kotlin: { + method: 'invitations().claim', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.invitations.InvitationClaimParams\nimport com.lightspark.umaaas.models.invitations.UmaInvitation\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val params: InvitationClaimParams = InvitationClaimParams.builder()\n .invitationCode("invitationCode")\n .inviteeUma("\\$invitee@uma.domain")\n .build()\n val umaInvitation: UmaInvitation = client.invitations().claim(params)\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/invitations/$INVITATION_CODE/claim \\\n -H \'Content-Type: application/json\' \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET" \\\n -d \'{\n "inviteeUma": "$invitee@uma.domain"\n }\'', + }, + }, + }, + { + name: 'cancel', + endpoint: '/invitations/{invitationCode}/cancel', + httpMethod: 'post', + summary: 'Cancel an UMA invitation', + description: + 'Cancel a pending UMA invitation. Only the inviter or platform can cancel an invitation.\n\nWhen an invitation is cancelled:\n1. The invitation status changes from PENDING to CANCELLED\n2. The invitation can no longer be claimed\n3. The invitation URL will show as cancelled when accessed\n\nOnly pending invitations can be cancelled. Attempting to cancel an invitation\nthat is already claimed, expired, or cancelled will result in an error.\n', + stainlessPath: '(resource) invitations > (method) cancel', + qualified: 'client.invitations.cancel', + params: ['invitationCode: string;'], + response: + "{ code: string; createdAt: string; inviterUma: string; status: 'PENDING' | 'CLAIMED' | 'EXPIRED' | 'CANCELLED'; url: string; amountToSend?: { amount: number; currency: currency; }; claimedAt?: string; expiresAt?: string; firstName?: string; inviteeCountryCode?: string; inviteeUma?: string; }", + markdown: + "## cancel\n\n`client.invitations.cancel(invitationCode: string): { code: string; createdAt: string; inviterUma: string; status: 'PENDING' | 'CLAIMED' | 'EXPIRED' | 'CANCELLED'; url: string; amountToSend?: currency_amount; claimedAt?: string; expiresAt?: string; firstName?: string; inviteeCountryCode?: string; inviteeUma?: string; }`\n\n**post** `/invitations/{invitationCode}/cancel`\n\nCancel a pending UMA invitation. Only the inviter or platform can cancel an invitation.\n\nWhen an invitation is cancelled:\n1. The invitation status changes from PENDING to CANCELLED\n2. The invitation can no longer be claimed\n3. The invitation URL will show as cancelled when accessed\n\nOnly pending invitations can be cancelled. Attempting to cancel an invitation\nthat is already claimed, expired, or cancelled will result in an error.\n\n\n### Parameters\n\n- `invitationCode: string`\n\n### Returns\n\n- `{ code: string; createdAt: string; inviterUma: string; status: 'PENDING' | 'CLAIMED' | 'EXPIRED' | 'CANCELLED'; url: string; amountToSend?: { amount: number; currency: currency; }; claimedAt?: string; expiresAt?: string; firstName?: string; inviteeCountryCode?: string; inviteeUma?: string; }`\n\n - `code: string`\n - `createdAt: string`\n - `inviterUma: string`\n - `status: 'PENDING' | 'CLAIMED' | 'EXPIRED' | 'CANCELLED'`\n - `url: string`\n - `amountToSend?: { amount: number; currency: { code?: string; decimals?: number; name?: string; symbol?: string; }; }`\n - `claimedAt?: string`\n - `expiresAt?: string`\n - `firstName?: string`\n - `inviteeCountryCode?: string`\n - `inviteeUma?: string`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst umaInvitation = await client.invitations.cancel('invitationCode');\n\nconsole.log(umaInvitation);\n```", + perLanguage: { + typescript: { + method: 'client.invitations.cancel', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst umaInvitation = await client.invitations.cancel('invitationCode');\n\nconsole.log(umaInvitation.code);", + }, + kotlin: { + method: 'invitations().cancel', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.invitations.InvitationCancelParams\nimport com.lightspark.umaaas.models.invitations.UmaInvitation\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val umaInvitation: UmaInvitation = client.invitations().cancel("invitationCode")\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/invitations/$INVITATION_CODE/cancel \\\n -X POST \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET"', + }, + }, + }, + { + name: 'send_funds', + endpoint: '/sandbox/send', + httpMethod: 'post', + summary: 'Simulate sending funds', + description: + 'Simulate sending funds to the bank account as instructed in the quote. \nThis endpoint is only for the sandbox environment and will fail for production platforms/keys.\n', + stainlessPath: '(resource) sandbox > (method) send_funds', + qualified: 'client.sandbox.sendFunds', + params: ['currencyAmount: number;', 'currencyCode: string;', 'reference: string;'], + response: + "{ id: string; platformUserId: string; receiverUmaAddress: string; senderUmaAddress: string; status: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED'; type: 'INCOMING' | 'OUTGOING'; userId: string; counterpartyInformation?: object; createdAt?: string; description?: string; settledAt?: string; }", + markdown: + "## send_funds\n\n`client.sandbox.sendFunds(currencyAmount: number, currencyCode: string, reference: string): object`\n\n**post** `/sandbox/send`\n\nSimulate sending funds to the bank account as instructed in the quote. \nThis endpoint is only for the sandbox environment and will fail for production platforms/keys.\n\n\n### Parameters\n\n- `currencyAmount: number`\n The amount to send in the smallest unit of the currency (eg. cents)\n\n- `currencyCode: string`\n Currency code for the funds to be sent\n\n- `reference: string`\n The unique reference code that was in the payment instructions\n\n### Returns\n\n- `{ id: string; platformUserId: string; receiverUmaAddress: string; senderUmaAddress: string; status: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED'; type: 'INCOMING' | 'OUTGOING'; userId: string; counterpartyInformation?: object; createdAt?: string; description?: string; settledAt?: string; }`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst outgoingTransaction = await client.sandbox.sendFunds({\n currencyAmount: 1000,\n currencyCode: 'USD',\n reference: 'UMA-Q12345-REF',\n});\n\nconsole.log(outgoingTransaction);\n```", + perLanguage: { + typescript: { + method: 'client.sandbox.sendFunds', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst outgoingTransaction = await client.sandbox.sendFunds({\n currencyAmount: 1000,\n currencyCode: 'USD',\n reference: 'UMA-Q12345-REF',\n});\n\nconsole.log(outgoingTransaction);", + }, + kotlin: { + method: 'sandbox().sendFunds', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.sandbox.SandboxSendFundsParams\nimport com.lightspark.umaaas.models.transactions.OutgoingTransaction\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val params: SandboxSendFundsParams = SandboxSendFundsParams.builder()\n .currencyAmount(1000L)\n .currencyCode("USD")\n .reference("UMA-Q12345-REF")\n .build()\n val outgoingTransaction: OutgoingTransaction = client.sandbox().sendFunds(params)\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/sandbox/send \\\n -H \'Content-Type: application/json\' \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET" \\\n -d \'{\n "currencyAmount": 1000,\n "currencyCode": "USD",\n "reference": "UMA-Q12345-REF"\n }\'', + }, + }, + }, + { + name: 'receive_payment', + endpoint: '/sandbox/receive', + httpMethod: 'post', + summary: 'Simulate payment send to test receiving a payment', + description: + 'Simulate sending payment from an sandbox uma address to a platform user to test payment receive.\nThis endpoint is only for the sandbox environment and will fail for production platforms/keys.\n', + stainlessPath: '(resource) sandbox > (method) receive_payment', + qualified: 'client.sandbox.receivePayment', + params: [ + 'receivingCurrencyAmount: number;', + 'receivingCurrencyCode: string;', + 'senderUmaAddress: string;', + 'receiverUmaAddress?: string;', + 'userId?: string;', + ], + response: + "{ id: string; platformUserId: string; receiverUmaAddress: string; senderUmaAddress: string; status: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED'; type: 'INCOMING' | 'OUTGOING'; userId: string; counterpartyInformation?: object; createdAt?: string; description?: string; settledAt?: string; }", + markdown: + "## receive_payment\n\n`client.sandbox.receivePayment(receivingCurrencyAmount: number, receivingCurrencyCode: string, senderUmaAddress: string, receiverUmaAddress?: string, userId?: string): object`\n\n**post** `/sandbox/receive`\n\nSimulate sending payment from an sandbox uma address to a platform user to test payment receive.\nThis endpoint is only for the sandbox environment and will fail for production platforms/keys.\n\n\n### Parameters\n\n- `receivingCurrencyAmount: number`\n The amount to be received in the smallest unit of the currency (eg. cents)\n\n- `receivingCurrencyCode: string`\n The currency code for the receiving amount\n\n- `senderUmaAddress: string`\n UMA address of the sender from the sandbox\n\n- `receiverUmaAddress?: string`\n UMA address of the receiver (optional if userId is provided)\n\n- `userId?: string`\n System ID of the receiver (optional if receiverUmaAddress is provided)\n\n### Returns\n\n- `{ id: string; platformUserId: string; receiverUmaAddress: string; senderUmaAddress: string; status: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED'; type: 'INCOMING' | 'OUTGOING'; userId: string; counterpartyInformation?: object; createdAt?: string; description?: string; settledAt?: string; }`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst incomingTransaction = await client.sandbox.receivePayment({\n receivingCurrencyAmount: 1000,\n receivingCurrencyCode: 'USD',\n senderUmaAddress: '$success.usd@sandbox.umaaas.uma.money',\n});\n\nconsole.log(incomingTransaction);\n```", + perLanguage: { + typescript: { + method: 'client.sandbox.receivePayment', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst incomingTransaction = await client.sandbox.receivePayment({\n receivingCurrencyAmount: 1000,\n receivingCurrencyCode: 'USD',\n senderUmaAddress: '$success.usd@sandbox.umaaas.uma.money',\n});\n\nconsole.log(incomingTransaction);", + }, + kotlin: { + method: 'sandbox().receivePayment', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.sandbox.SandboxReceivePaymentParams\nimport com.lightspark.umaaas.models.transactions.IncomingTransaction\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val params: SandboxReceivePaymentParams = SandboxReceivePaymentParams.builder()\n .receivingCurrencyAmount(1000L)\n .receivingCurrencyCode("USD")\n .senderUmaAddress("\\$success.usd@sandbox.umaaas.uma.money")\n .build()\n val incomingTransaction: IncomingTransaction = client.sandbox().receivePayment(params)\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/sandbox/receive \\\n -H \'Content-Type: application/json\' \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET" \\\n -d \'{\n "receivingCurrencyAmount": 1000,\n "receivingCurrencyCode": "USD",\n "senderUmaAddress": "$success.usd@sandbox.umaaas.uma.money",\n "receiverUmaAddress": "$receiver@uma.domain",\n "userId": "User:019542f5-b3e7-1d02-0000-000000000001"\n }\'', + }, + }, + }, + { + name: 'list', + endpoint: '/uma-providers', + httpMethod: 'get', + summary: 'This endpoint provides a list of counterparties that are available.', + description: + 'This endpoint provides a list of counterparties that are available.\n\nThe response includes basic information about each provider, such as its UMA address, name, and supported currencies.\nThis can be used to determine which providers are available for sending or receiving payments.\n', + stainlessPath: '(resource) uma_providers > (method) list', + qualified: 'client.umaProviders.list', + params: [ + 'countryCode?: string;', + 'currencyCode?: string;', + 'cursor?: string;', + 'hasBlockedProviders?: boolean;', + 'limit?: number;', + "sortOrder?: 'asc' | 'desc';", + ], + response: + '{ allowListStatus?: boolean; domain?: string; lei?: string; logoUrl?: string; name?: string; supportedCurrencies?: { code?: string; decimals?: number; name?: string; symbol?: string; }[]; supportedRegions?: string[]; }', + markdown: + "## list\n\n`client.umaProviders.list(countryCode?: string, currencyCode?: string, cursor?: string, hasBlockedProviders?: boolean, limit?: number, sortOrder?: 'asc' | 'desc'): { allowListStatus?: boolean; domain?: string; lei?: string; logoUrl?: string; name?: string; supportedCurrencies?: currency[]; supportedRegions?: string[]; }`\n\n**get** `/uma-providers`\n\nThis endpoint provides a list of counterparties that are available.\n\nThe response includes basic information about each provider, such as its UMA address, name, and supported currencies.\nThis can be used to determine which providers are available for sending or receiving payments.\n\n\n### Parameters\n\n- `countryCode?: string`\n The alpha-2 representation of a country, as defined by the ISO 3166-1 standard.\n\n- `currencyCode?: string`\n The ISO 4217 currency code to filter providers by supported currency.\n\n- `cursor?: string`\n Cursor for pagination (returned from previous request)\n\n- `hasBlockedProviders?: boolean`\n Whether to include providers which are not on your allowlist in the response. By default the response will include blocked providers.\n\n- `limit?: number`\n Maximum number of results to return (default 20, max 100)\n\n- `sortOrder?: 'asc' | 'desc'`\n Order to sort results in\n\n### Returns\n\n- `{ allowListStatus?: boolean; domain?: string; lei?: string; logoUrl?: string; name?: string; supportedCurrencies?: { code?: string; decimals?: number; name?: string; symbol?: string; }[]; supportedRegions?: string[]; }`\n\n - `allowListStatus?: boolean`\n - `domain?: string`\n - `lei?: string`\n - `logoUrl?: string`\n - `name?: string`\n - `supportedCurrencies?: { code?: string; decimals?: number; name?: string; symbol?: string; }[]`\n - `supportedRegions?: string[]`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\n// Automatically fetches more pages as needed.\nfor await (const umaProvider of client.umaProviders.list()) {\n console.log(umaProvider);\n}\n```", + perLanguage: { + typescript: { + method: 'client.umaProviders.list', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\n// Automatically fetches more pages as needed.\nfor await (const umaProvider of client.umaProviders.list()) {\n console.log(umaProvider.allowListStatus);\n}", + }, + kotlin: { + method: 'umaProviders().list', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.umaproviders.UmaProviderListPage\nimport com.lightspark.umaaas.models.umaproviders.UmaProviderListParams\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val page: UmaProviderListPage = client.umaProviders().list()\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/uma-providers \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET"', + }, + }, + }, + { + name: 'confirm_payment', + endpoint: '/fbo/confirm/{quoteId}', + httpMethod: 'post', + summary: 'Trigger payment from a FBO account', + description: + 'This endpoint should only be used for when your account is configured for FBO payments. It triggers funding a quote from your FBO account to initiate payment.\n', + stainlessPath: '(resource) fbo > (method) confirm_payment', + qualified: 'client.fbo.confirmPayment', + params: ['quoteId: string;'], + response: + "{ id: string; platformUserId: string; receiverUmaAddress: string; senderUmaAddress: string; status: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED'; type: 'INCOMING' | 'OUTGOING'; userId: string; counterpartyInformation?: object; createdAt?: string; description?: string; settledAt?: string; }", + markdown: + "## confirm_payment\n\n`client.fbo.confirmPayment(quoteId: string): { id: string; platformUserId: string; receiverUmaAddress: string; senderUmaAddress: string; status: transaction_status; type: transaction_type; userId: string; counterpartyInformation?: object; createdAt?: string; description?: string; settledAt?: string; }`\n\n**post** `/fbo/confirm/{quoteId}`\n\nThis endpoint should only be used for when your account is configured for FBO payments. It triggers funding a quote from your FBO account to initiate payment.\n\n\n### Parameters\n\n- `quoteId: string`\n\n### Returns\n\n- `{ id: string; platformUserId: string; receiverUmaAddress: string; senderUmaAddress: string; status: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED'; type: 'INCOMING' | 'OUTGOING'; userId: string; counterpartyInformation?: object; createdAt?: string; description?: string; settledAt?: string; }`\n\n - `id: string`\n - `platformUserId: string`\n - `receiverUmaAddress: string`\n - `senderUmaAddress: string`\n - `status: 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED'`\n - `type: 'INCOMING' | 'OUTGOING'`\n - `userId: string`\n - `counterpartyInformation?: object`\n - `createdAt?: string`\n - `description?: string`\n - `settledAt?: string`\n\n### Example\n\n```typescript\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas();\n\nconst transaction = await client.fbo.confirmPayment('quoteId');\n\nconsole.log(transaction);\n```", + perLanguage: { + typescript: { + method: 'client.fbo.confirmPayment', + example: + "import Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst transaction = await client.fbo.confirmPayment('quoteId');\n\nconsole.log(transaction.id);", + }, + kotlin: { + method: 'fbo().confirmPayment', + example: + 'package com.lightspark.umaaas.example\n\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.fbo.FboConfirmPaymentParams\nimport com.lightspark.umaaas.models.transactions.Transaction\n\nfun main() {\n val client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\n val transaction: Transaction = client.fbo().confirmPayment("quoteId")\n}', + }, + http: { + example: + 'curl https://api.uma.money/umaaas/2025-05-15/fbo/confirm/$QUOTE_ID \\\n -X POST \\\n -u "$UMAAAS_CLIENT_ID:UMAAAS_CLIENT_SECRET"', + }, + }, + }, +]; + +const EMBEDDED_READMES: { language: string; content: string }[] = [ + { + language: 'kotlin', + content: + '# Umaaas Kotlin API Library\n\n\n[![Maven Central](https://img.shields.io/maven-central/v/com.lightspark.umaaas/umaaas-kotlin)](https://central.sonatype.com/artifact/com.lightspark.umaaas/umaaas-kotlin/0.0.1)\n[![javadoc](https://javadoc.io/badge2/com.lightspark.umaaas/umaaas-kotlin/0.0.1/javadoc.svg)](https://javadoc.io/doc/com.lightspark.umaaas/umaaas-kotlin/0.0.1)\n\n\nThe Umaaas Kotlin SDK provides convenient access to the [Umaaas REST API](https://lightsparkdev.github.io/umaaas-api/) from applications written in Kotlin.\n\n\n\nIt is generated with [Stainless](https://www.stainless.com/).\n\n## MCP Server\n\nUse the Umaaas MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application.\n\n[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=umaaas_mcp&config=eyJuYW1lIjoidW1hYWFzX21jcCIsInRyYW5zcG9ydCI6Imh0dHAiLCJ1cmwiOiJodHRwczovL3VtYWFhcy5zdGxtY3AuY29tIiwiaGVhZGVycyI6eyJ4LXVtYWFhcy1jbGllbnQtaWQiOiJNeSBVc2VybmFtZSIsIngtdW1hYWFzLWNsaWVudC1zZWNyZXQiOiJNeSBQYXNzd29yZCJ9fQ)\n[![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22umaaas_mcp%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fumaaas.stlmcp.com%22%2C%22headers%22%3A%7B%22x-umaaas-client-id%22%3A%22My%20Username%22%2C%22x-umaaas-client-secret%22%3A%22My%20Password%22%7D%7D)\n\n> Note: You may need to set environment variables in your MCP client.\n\n\n\nThe REST API documentation can be found on [lightsparkdev.github.io](https://lightsparkdev.github.io/umaaas-api/). KDocs are available on [javadoc.io](https://javadoc.io/doc/com.lightspark.umaaas/umaaas-kotlin/0.0.1).\n\n\n\n## Installation\n\n\n\n### Gradle\n\n~~~kotlin\nimplementation("com.lightspark.umaaas:umaaas-kotlin:0.0.1")\n~~~\n\n### Maven\n\n~~~xml\n\n com.lightspark.umaaas\n umaaas-kotlin\n 0.0.1\n\n~~~\n\n\n\n## Requirements\n\nThis library requires Java 8 or later.\n\n## Usage\n\n```kotlin\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.users.BankAccountType\nimport com.lightspark.umaaas.models.users.BusinessUser\nimport com.lightspark.umaaas.models.users.IndividualUser\nimport com.lightspark.umaaas.models.users.UserBankAccountInfo\nimport com.lightspark.umaaas.models.users.UserCreateResponse\nimport com.lightspark.umaaas.models.users.UserType\n\n// Configures using the `umaaas.clientId`, `umaaas.clientSecret` and `umaaas.baseUrl` system properties\n// Or configures using the `UMAAAS_CLIENT_ID`, `UMAAAS_CLIENT_SECRET` and `UMAAAS_BASE_URL` environment variables\nval client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\nval params: IndividualUser = IndividualUser.builder()\n .platformUserId("7b3c5a89d2f1e0")\n .umaAddress("\\$jane.doe@uma.domain.com")\n .userType(UserType.INDIVIDUAL)\n .bankAccountInfo(UserBankAccountInfo.UserClabeAccountInfo.builder()\n .bankName("Chase Bank")\n .clabeNumber("123456789012345678")\n .accountType(BankAccountType.US_ACCOUNT)\n .build())\n .build()\nval user: UserCreateResponse = client.users().create(params)\n```\n\n## Client configuration\n\nConfigure the client using system properties or environment variables:\n\n```kotlin\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\n\n// Configures using the `umaaas.clientId`, `umaaas.clientSecret` and `umaaas.baseUrl` system properties\n// Or configures using the `UMAAAS_CLIENT_ID`, `UMAAAS_CLIENT_SECRET` and `UMAAAS_BASE_URL` environment variables\nval client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n```\n\nOr manually:\n\n```kotlin\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\n\nval client: UmaaasClient = UmaaasOkHttpClient.builder()\n .username("My Username")\n .password("My Password")\n .build()\n```\n\nOr using a combination of the two approaches:\n\n```kotlin\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\n\nval client: UmaaasClient = UmaaasOkHttpClient.builder()\n // Configures using the `umaaas.clientId`, `umaaas.clientSecret` and `umaaas.baseUrl` system properties\n // Or configures using the `UMAAAS_CLIENT_ID`, `UMAAAS_CLIENT_SECRET` and `UMAAAS_BASE_URL` environment variables\n .fromEnv()\n .username("My Username")\n .build()\n```\n\nSee this table for the available options:\n\n| Setter | System property | Environment variable | Required | Default value |\n| ---------- | --------------------- | ---------------------- | -------- | ------------------------------------------- |\n| `username` | `umaaas.clientId` | `UMAAAS_CLIENT_ID` | true | - |\n| `password` | `umaaas.clientSecret` | `UMAAAS_CLIENT_SECRET` | true | - |\n| `baseUrl` | `umaaas.baseUrl` | `UMAAAS_BASE_URL` | true | `"https://api.uma.money/umaaas/2025-05-15"` |\n\nSystem properties take precedence over environment variables.\n\n> [!TIP]\n> Don\'t create more than one client in the same application. Each client has a connection pool and\n> thread pools, which are more efficient to share between requests.\n\n### Modifying configuration\n\nTo temporarily use a modified client configuration, while reusing the same connection and thread pools, call `withOptions()` on any client or service:\n\n```kotlin\nimport com.lightspark.umaaas.client.UmaaasClient\n\nval clientWithOptions: UmaaasClient = client.withOptions {\n it.baseUrl("https://example.com")\n it.maxRetries(42)\n}\n```\n\nThe `withOptions()` method does not affect the original client or service.\n\n## Requests and responses\n\nTo send a request to the Umaaas API, build an instance of some `Params` class and pass it to the corresponding client method. When the response is received, it will be deserialized into an instance of a Kotlin class.\n\nFor example, `client.users().create(...)` should be called with an instance of `UserCreateParams`, and it will return an instance of `UserCreateResponse`.\n\n## Immutability\n\nEach class in the SDK has an associated [builder](https://blogs.oracle.com/javamagazine/post/exploring-joshua-blochs-builder-design-pattern-in-java) or factory method for constructing it.\n\nEach class is [immutable](https://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html) once constructed. If the class has an associated builder, then it has a `toBuilder()` method, which can be used to convert it back to a builder for making a modified copy.\n\nBecause each class is immutable, builder modification will _never_ affect already built class instances.\n\n## Asynchronous execution\n\nThe default client is synchronous. To switch to asynchronous execution, call the `async()` method:\n\n```kotlin\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.models.users.BankAccountType\nimport com.lightspark.umaaas.models.users.IndividualUser\nimport com.lightspark.umaaas.models.users.UserBankAccountInfo\nimport com.lightspark.umaaas.models.users.UserCreateResponse\nimport com.lightspark.umaaas.models.users.UserType\n\n// Configures using the `umaaas.clientId`, `umaaas.clientSecret` and `umaaas.baseUrl` system properties\n// Or configures using the `UMAAAS_CLIENT_ID`, `UMAAAS_CLIENT_SECRET` and `UMAAAS_BASE_URL` environment variables\nval client: UmaaasClient = UmaaasOkHttpClient.fromEnv()\n\nval params: IndividualUser = IndividualUser.builder()\n .platformUserId("7b3c5a89d2f1e0")\n .umaAddress("\\$jane.doe@uma.domain.com")\n .userType(UserType.INDIVIDUAL)\n .bankAccountInfo(UserBankAccountInfo.UserClabeAccountInfo.builder()\n .bankName("Chase Bank")\n .clabeNumber("123456789012345678")\n .accountType(BankAccountType.US_ACCOUNT)\n .build())\n .build()\nval user: UserCreateResponse = client.async().users().create(params)\n```\n\nOr create an asynchronous client from the beginning:\n\n```kotlin\nimport com.lightspark.umaaas.client.UmaaasClientAsync\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClientAsync\nimport com.lightspark.umaaas.models.users.BankAccountType\nimport com.lightspark.umaaas.models.users.IndividualUser\nimport com.lightspark.umaaas.models.users.UserBankAccountInfo\nimport com.lightspark.umaaas.models.users.UserCreateResponse\nimport com.lightspark.umaaas.models.users.UserType\n\n// Configures using the `umaaas.clientId`, `umaaas.clientSecret` and `umaaas.baseUrl` system properties\n// Or configures using the `UMAAAS_CLIENT_ID`, `UMAAAS_CLIENT_SECRET` and `UMAAAS_BASE_URL` environment variables\nval client: UmaaasClientAsync = UmaaasOkHttpClientAsync.fromEnv()\n\nval params: IndividualUser = IndividualUser.builder()\n .platformUserId("7b3c5a89d2f1e0")\n .umaAddress("\\$jane.doe@uma.domain.com")\n .userType(UserType.INDIVIDUAL)\n .bankAccountInfo(UserBankAccountInfo.UserClabeAccountInfo.builder()\n .bankName("Chase Bank")\n .clabeNumber("123456789012345678")\n .accountType(BankAccountType.US_ACCOUNT)\n .build())\n .build()\nval user: UserCreateResponse = client.users().create(params)\n```\n\nThe asynchronous client supports the same options as the synchronous one, except most methods are [suspending](https://kotlinlang.org/docs/coroutines-guide.html).\n\n\n\n## File uploads\n\nThe SDK defines methods that accept files.\n\nTo upload a file, pass a [`Path`](https://docs.oracle.com/javase/8/docs/api/java/nio/file/Path.html):\n\n```kotlin\nimport com.lightspark.umaaas.models.users.bulk.BulkUploadParams\nimport com.lightspark.umaaas.models.users.bulk.BulkUploadResponse\nimport java.nio.file.Paths\n\nval params: BulkUploadParams = BulkUploadParams.builder()\n .file(Paths.get("/path/to/file"))\n .build()\nval response: BulkUploadResponse = client.users().bulk().upload(params)\n```\n\nOr an arbitrary [`InputStream`](https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html):\n\n```kotlin\nimport com.lightspark.umaaas.models.users.bulk.BulkUploadParams\nimport com.lightspark.umaaas.models.users.bulk.BulkUploadResponse\nimport java.net.URL\n\nval params: BulkUploadParams = BulkUploadParams.builder()\n .file(URL("https://example.com//path/to/file").openStream())\n .build()\nval response: BulkUploadResponse = client.users().bulk().upload(params)\n```\n\nOr a `ByteArray`:\n\n```kotlin\nimport com.lightspark.umaaas.models.users.bulk.BulkUploadParams\nimport com.lightspark.umaaas.models.users.bulk.BulkUploadResponse\n\nval params: BulkUploadParams = BulkUploadParams.builder()\n .file("content".toByteArray())\n .build()\nval response: BulkUploadResponse = client.users().bulk().upload(params)\n```\n\nNote that when passing a non-`Path` its filename is unknown so it will not be included in the request. To manually set a filename, pass a [`MultipartField`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/core/Values.kt):\n\n```kotlin\nimport com.lightspark.umaaas.core.MultipartField\nimport com.lightspark.umaaas.models.users.bulk.BulkUploadParams\nimport com.lightspark.umaaas.models.users.bulk.BulkUploadResponse\nimport java.io.InputStream\nimport java.net.URL\n\nval params: BulkUploadParams = BulkUploadParams.builder()\n .file(MultipartField.builder()\n .value(URL("https://example.com//path/to/file").openStream())\n .filename("/path/to/file")\n .build())\n .build()\nval response: BulkUploadResponse = client.users().bulk().upload(params)\n```\n\n\n\n## Raw responses\n\nThe SDK defines methods that deserialize responses into instances of Kotlin classes. However, these methods don\'t provide access to the response headers, status code, or the raw response body.\n\nTo access this data, prefix any HTTP method call on a client or service with `withRawResponse()`:\n\n```kotlin\nimport com.lightspark.umaaas.core.http.Headers\nimport com.lightspark.umaaas.core.http.HttpResponseFor\nimport com.lightspark.umaaas.models.users.BankAccountType\nimport com.lightspark.umaaas.models.users.IndividualUser\nimport com.lightspark.umaaas.models.users.UserBankAccountInfo\nimport com.lightspark.umaaas.models.users.UserCreateResponse\nimport com.lightspark.umaaas.models.users.UserType\n\nval params: IndividualUser = IndividualUser.builder()\n .platformUserId("7b3c5a89d2f1e0")\n .umaAddress("\\$jane.doe@uma.domain.com")\n .userType(UserType.INDIVIDUAL)\n .bankAccountInfo(UserBankAccountInfo.UserClabeAccountInfo.builder()\n .bankName("Chase Bank")\n .clabeNumber("123456789012345678")\n .accountType(BankAccountType.US_ACCOUNT)\n .build())\n .build()\nval user: HttpResponseFor = client.users().withRawResponse().create(params)\n\nval statusCode: Int = user.statusCode()\nval headers: Headers = user.headers()\n```\n\nYou can still deserialize the response into an instance of a Kotlin class if needed:\n\n```kotlin\nimport com.lightspark.umaaas.models.users.UserCreateResponse\n\nval parsedUser: UserCreateResponse = user.parse()\n```\n\n## Error handling\n\nThe SDK throws custom unchecked exception types:\n\n- [`UmaaasServiceException`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/errors/UmaaasServiceException.kt): Base class for HTTP errors. See this table for which exception subclass is thrown for each HTTP status code:\n\n | Status | Exception |\n | ------ | -------------------------------------------------- |\n | 400 | [`BadRequestException`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/errors/BadRequestException.kt) |\n | 401 | [`UnauthorizedException`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/errors/UnauthorizedException.kt) |\n | 403 | [`PermissionDeniedException`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/errors/PermissionDeniedException.kt) |\n | 404 | [`NotFoundException`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/errors/NotFoundException.kt) |\n | 422 | [`UnprocessableEntityException`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/errors/UnprocessableEntityException.kt) |\n | 429 | [`RateLimitException`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/errors/RateLimitException.kt) |\n | 5xx | [`InternalServerException`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/errors/InternalServerException.kt) |\n | others | [`UnexpectedStatusCodeException`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/errors/UnexpectedStatusCodeException.kt) |\n\n- [`UmaaasIoException`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/errors/UmaaasIoException.kt): I/O networking errors.\n\n- [`UmaaasRetryableException`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/errors/UmaaasRetryableException.kt): Generic error indicating a failure that could be retried by the client.\n\n- [`UmaaasInvalidDataException`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/errors/UmaaasInvalidDataException.kt): Failure to interpret successfully parsed data. For example, when accessing a property that\'s supposed to be required, but the API unexpectedly omitted it from the response.\n\n- [`UmaaasException`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/errors/UmaaasException.kt): Base class for all exceptions. Most errors will result in one of the previously mentioned ones, but completely generic errors may be thrown using the base class.\n\n## Pagination\n\nThe SDK defines methods that return a paginated lists of results. It provides convenient ways to access the results either one page at a time or item-by-item across all pages.\n\n### Auto-pagination\n\nTo iterate through all results across all pages, use the `autoPager()` method, which automatically fetches more pages as needed.\n\nWhen using the synchronous client, the method returns a [`Sequence`](https://kotlinlang.org/docs/sequences.html)\n\n```kotlin\nimport com.lightspark.umaaas.models.users.UserListPage\n\nval page: UserListPage = client.users().list()\npage.autoPager()\n .take(50)\n .forEach { user -> println(user) }\n```\n\nWhen using the asynchronous client, the method returns a [`Flow`](https://kotlinlang.org/docs/flow.html):\n\n```kotlin\nimport com.lightspark.umaaas.models.users.UserListPageAsync\n\nval page: UserListPageAsync = client.async().users().list()\npage.autoPager()\n .take(50)\n .forEach { user -> println(user) }\n```\n\n### Manual pagination\n\nTo access individual page items and manually request the next page, use the `items()`,\n`hasNextPage()`, and `nextPage()` methods:\n\n```kotlin\nimport com.lightspark.umaaas.models.users.UserListPage\nimport com.lightspark.umaaas.models.users.UserListResponse\n\nval page: UserListPage = client.users().list()\nwhile (true) {\n for (user in page.items()) {\n println(user)\n }\n\n if (!page.hasNextPage()) {\n break\n }\n\n page = page.nextPage()\n}\n```\n\n## Logging\n\nEnable logging by setting the `UMAAAS_LOG` environment variable to `info`:\n\n```sh\nexport UMAAAS_LOG=info\n```\n\nOr to `debug` for more verbose logging:\n\n```sh\nexport UMAAAS_LOG=debug\n```\n\nOr configure the client manually using the `logLevel` method:\n\n```kotlin\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.core.LogLevel\n\nval client: UmaaasClient = UmaaasOkHttpClient.builder()\n .fromEnv()\n .logLevel(LogLevel.INFO)\n .build()\n```\n\n## ProGuard and R8\n\nAlthough the SDK uses reflection, it is still usable with [ProGuard](https://github.com/Guardsquare/proguard) and [R8](https://developer.android.com/topic/performance/app-optimization/enable-app-optimization) because `umaaas-kotlin-core` is published with a [configuration file](umaaas-kotlin-core/src/main/resources/META-INF/proguard/umaaas-kotlin-core.pro) containing [keep rules](https://www.guardsquare.com/manual/configuration/usage).\n\nProGuard and R8 should automatically detect and use the published rules, but you can also manually copy the keep rules if necessary.\n\n\n\n\n\n## Jackson\n\nThe SDK depends on [Jackson](https://github.com/FasterXML/jackson) for JSON serialization/deserialization. It is compatible with version 2.13.4 or higher, but depends on version 2.18.2 by default.\n\nThe SDK throws an exception if it detects an incompatible Jackson version at runtime (e.g. if the default version was overridden in your Maven or Gradle config).\n\nIf the SDK threw an exception, but you\'re _certain_ the version is compatible, then disable the version check using the `checkJacksonVersionCompatibility` on [`UmaaasOkHttpClient`](umaaas-kotlin-client-okhttp/src/main/kotlin/com/lightspark/umaaas/client/okhttp/UmaaasOkHttpClient.kt) or [`UmaaasOkHttpClientAsync`](umaaas-kotlin-client-okhttp/src/main/kotlin/com/lightspark/umaaas/client/okhttp/UmaaasOkHttpClientAsync.kt).\n\n> [!CAUTION]\n> We make no guarantee that the SDK works correctly when the Jackson version check is disabled.\n\nAlso note that there are bugs in older Jackson versions that can affect the SDK. We don\'t work around all Jackson bugs ([example](https://github.com/FasterXML/jackson-databind/issues/3240)) and expect users to upgrade Jackson for those instead.\n\n## Network options\n\n### Retries\n\nThe SDK automatically retries 2 times by default, with a short exponential backoff between requests.\n\nOnly the following error types are retried:\n- Connection errors (for example, due to a network connectivity problem)\n- 408 Request Timeout\n- 409 Conflict\n- 429 Rate Limit\n- 5xx Internal\n\nThe API may also explicitly instruct the SDK to retry or not retry a request.\n\nTo set a custom number of retries, configure the client using the `maxRetries` method:\n\n```kotlin\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\n\nval client: UmaaasClient = UmaaasOkHttpClient.builder()\n .fromEnv()\n .maxRetries(4)\n .build()\n```\n\n### Timeouts\n\nRequests time out after 1 minute by default.\n\nTo set a custom timeout, configure the method call using the `timeout` method:\n\n```kotlin\nimport com.lightspark.umaaas.models.users.UserCreateResponse\n\nval user: UserCreateResponse = client.users().create(\n params, RequestOptions.builder().timeout(Duration.ofSeconds(30)).build()\n)\n```\n\nOr configure the default for all method calls at the client level:\n\n```kotlin\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport java.time.Duration\n\nval client: UmaaasClient = UmaaasOkHttpClient.builder()\n .fromEnv()\n .timeout(Duration.ofSeconds(30))\n .build()\n```\n\n### Proxies\n\nTo route requests through a proxy, configure the client using the `proxy` method:\n\n```kotlin\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport java.net.InetSocketAddress\nimport java.net.Proxy\n\nval client: UmaaasClient = UmaaasOkHttpClient.builder()\n .fromEnv()\n .proxy(Proxy(\n Proxy.Type.HTTP, InetSocketAddress(\n "https://example.com", 8080\n )\n ))\n .build()\n```\n\nIf the proxy responds with `407 Proxy Authentication Required`, supply credentials by also configuring `proxyAuthenticator`:\n\n```kotlin\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport com.lightspark.umaaas.core.http.ProxyAuthenticator\n\nval client: UmaaasClient = UmaaasOkHttpClient.builder()\n .fromEnv()\n .proxy(...)\n // Or a custom implementation of `ProxyAuthenticator`.\n .proxyAuthenticator(ProxyAuthenticator.basic("username", "password"))\n .build()\n```\n\n### Connection pooling\n\nTo customize the underlying OkHttp connection pool, configure the client using the `maxIdleConnections` and `keepAliveDuration` methods:\n\n```kotlin\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\nimport java.time.Duration\n\nval client: UmaaasClient = UmaaasOkHttpClient.builder()\n .fromEnv()\n // If `maxIdleConnections` is set, then `keepAliveDuration` must be set, and vice versa.\n .maxIdleConnections(10)\n .keepAliveDuration(Duration.ofMinutes(2))\n .build()\n```\n\nIf both options are unset, OkHttp\'s default connection pool settings are used.\n\n### HTTPS\n\n> [!NOTE]\n> Most applications should not call these methods, and instead use the system defaults. The defaults include\n> special optimizations that can be lost if the implementations are modified.\n\nTo configure how HTTPS connections are secured, configure the client using the `sslSocketFactory`, `trustManager`, and `hostnameVerifier` methods:\n\n```kotlin\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\n\nval client: UmaaasClient = UmaaasOkHttpClient.builder()\n .fromEnv()\n // If `sslSocketFactory` is set, then `trustManager` must be set, and vice versa.\n .sslSocketFactory(yourSSLSocketFactory)\n .trustManager(yourTrustManager)\n .hostnameVerifier(yourHostnameVerifier)\n .build()\n```\n\n\n\n### Custom HTTP client\n\nThe SDK consists of three artifacts:\n- `umaaas-kotlin-core`\n - Contains core SDK logic\n - Does not depend on [OkHttp](https://square.github.io/okhttp)\n - Exposes [`UmaaasClient`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/client/UmaaasClient.kt), [`UmaaasClientAsync`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/client/UmaaasClientAsync.kt), [`UmaaasClientImpl`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/client/UmaaasClientImpl.kt), and [`UmaaasClientAsyncImpl`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/client/UmaaasClientAsyncImpl.kt), all of which can work with any HTTP client\n- `umaaas-kotlin-client-okhttp`\n - Depends on [OkHttp](https://square.github.io/okhttp)\n - Exposes [`UmaaasOkHttpClient`](umaaas-kotlin-client-okhttp/src/main/kotlin/com/lightspark/umaaas/client/okhttp/UmaaasOkHttpClient.kt) and [`UmaaasOkHttpClientAsync`](umaaas-kotlin-client-okhttp/src/main/kotlin/com/lightspark/umaaas/client/okhttp/UmaaasOkHttpClientAsync.kt), which provide a way to construct [`UmaaasClientImpl`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/client/UmaaasClientImpl.kt) and [`UmaaasClientAsyncImpl`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/client/UmaaasClientAsyncImpl.kt), respectively, using OkHttp\n- `umaaas-kotlin`\n - Depends on and exposes the APIs of both `umaaas-kotlin-core` and `umaaas-kotlin-client-okhttp`\n - Does not have its own logic\n\nThis structure allows replacing the SDK\'s default HTTP client without pulling in unnecessary dependencies.\n\n#### Customized [`OkHttpClient`](https://square.github.io/okhttp/3.x/okhttp/okhttp3/OkHttpClient.html)\n\n> [!TIP]\n> Try the available [network options](#network-options) before replacing the default client.\n\nTo use a customized `OkHttpClient`:\n\n1. Replace your [`umaaas-kotlin` dependency](#installation) with `umaaas-kotlin-core`\n2. Copy `umaaas-kotlin-client-okhttp`\'s [`OkHttpClient`](umaaas-kotlin-client-okhttp/src/main/kotlin/com/lightspark/umaaas/client/okhttp/OkHttpClient.kt) class into your code and customize it\n3. Construct [`UmaaasClientImpl`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/client/UmaaasClientImpl.kt) or [`UmaaasClientAsyncImpl`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/client/UmaaasClientAsyncImpl.kt), similarly to [`UmaaasOkHttpClient`](umaaas-kotlin-client-okhttp/src/main/kotlin/com/lightspark/umaaas/client/okhttp/UmaaasOkHttpClient.kt) or [`UmaaasOkHttpClientAsync`](umaaas-kotlin-client-okhttp/src/main/kotlin/com/lightspark/umaaas/client/okhttp/UmaaasOkHttpClientAsync.kt), using your customized client\n\n### Completely custom HTTP client\n\nTo use a completely custom HTTP client:\n\n1. Replace your [`umaaas-kotlin` dependency](#installation) with `umaaas-kotlin-core`\n2. Write a class that implements the [`HttpClient`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/core/http/HttpClient.kt) interface\n3. Construct [`UmaaasClientImpl`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/client/UmaaasClientImpl.kt) or [`UmaaasClientAsyncImpl`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/client/UmaaasClientAsyncImpl.kt), similarly to [`UmaaasOkHttpClient`](umaaas-kotlin-client-okhttp/src/main/kotlin/com/lightspark/umaaas/client/okhttp/UmaaasOkHttpClient.kt) or [`UmaaasOkHttpClientAsync`](umaaas-kotlin-client-okhttp/src/main/kotlin/com/lightspark/umaaas/client/okhttp/UmaaasOkHttpClientAsync.kt), using your new client class\n\n## Undocumented API functionality\n\nThe SDK is typed for convenient usage of the documented API. However, it also supports working with undocumented or not yet supported parts of the API.\n\n### Parameters\n\nTo set undocumented parameters, call the `putAdditionalHeader`, `putAdditionalQueryParam`, or `putAdditionalBodyProperty` methods on any `Params` class:\n\n```kotlin\nimport com.lightspark.umaaas.core.JsonValue\nimport com.lightspark.umaaas.models.users.UserCreateParams\n\nval params: UserCreateParams = UserCreateParams.builder()\n .putAdditionalHeader("Secret-Header", "42")\n .putAdditionalQueryParam("secret_query_param", "42")\n .putAdditionalBodyProperty("secretProperty", JsonValue.from("42"))\n .build()\n```\n\nThese can be accessed on the built object later using the `_additionalHeaders()`, `_additionalQueryParams()`, and `_additionalBodyProperties()` methods.\n\nTo set a documented parameter or property to an undocumented or not yet supported _value_, pass a [`JsonValue`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/core/Values.kt) object to its setter:\n\n```kotlin\nimport com.lightspark.umaaas.core.JsonValue\nimport com.lightspark.umaaas.models.users.UserCreateParams\n\nval params: UserCreateParams = UserCreateParams.builder()\n .body(JsonValue.from(42))\n .build()\n```\n\nThe most straightforward way to create a [`JsonValue`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/core/Values.kt) is using its `from(...)` method:\n\n```kotlin\nimport com.lightspark.umaaas.core.JsonValue\n\n// Create primitive JSON values\nval nullValue: JsonValue = JsonValue.from(null)\nval booleanValue: JsonValue = JsonValue.from(true)\nval numberValue: JsonValue = JsonValue.from(42)\nval stringValue: JsonValue = JsonValue.from("Hello World!")\n\n// Create a JSON array value equivalent to `["Hello", "World"]`\nval arrayValue: JsonValue = JsonValue.from(listOf(\n "Hello", "World"\n))\n\n// Create a JSON object value equivalent to `{ "a": 1, "b": 2 }`\nval objectValue: JsonValue = JsonValue.from(mapOf(\n "a" to 1, "b" to 2\n))\n\n// Create an arbitrarily nested JSON equivalent to:\n// {\n// "a": [1, 2],\n// "b": [3, 4]\n// }\nval complexValue: JsonValue = JsonValue.from(mapOf(\n "a" to listOf(\n 1, 2\n ), "b" to listOf(\n 3, 4\n )\n))\n```\n\nNormally a `Builder` class\'s `build` method will throw [`IllegalStateException`](https://docs.oracle.com/javase/8/docs/api/java/lang/IllegalStateException.html) if any required parameter or property is unset.\n\nTo forcibly omit a required parameter or property, pass [`JsonMissing`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/core/Values.kt):\n\n```kotlin\nimport com.lightspark.umaaas.core.JsonMissing\nimport com.lightspark.umaaas.models.users.UserCreateParams\nimport com.lightspark.umaaas.models.users.UserRetrieveParams\n\nval params: UserCreateParams = UserRetrieveParams.builder()\n .userId(JsonMissing.of())\n .build()\n```\n\n### Response properties\n\nTo access undocumented response properties, call the `_additionalProperties()` method:\n\n```kotlin\nimport com.lightspark.umaaas.core.JsonBoolean\nimport com.lightspark.umaaas.core.JsonNull\nimport com.lightspark.umaaas.core.JsonNumber\nimport com.lightspark.umaaas.core.JsonValue\n\nval additionalProperties: Map = client.users().bulk().getJobStatus(params)._additionalProperties()\nval secretPropertyValue: JsonValue = additionalProperties.get("secretProperty")\n\nval result = when (secretPropertyValue) {\n is JsonNull -> "It\'s null!"\n is JsonBoolean -> "It\'s a boolean!"\n is JsonNumber -> "It\'s a number!"\n // Other types include `JsonMissing`, `JsonString`, `JsonArray`, and `JsonObject`\n else -> "It\'s something else!"\n}\n```\n\nTo access a property\'s raw JSON value, which may be undocumented, call its `_` prefixed method:\n\n```kotlin\nimport com.lightspark.umaaas.core.JsonField\n\nval field: JsonField = client.users().bulk().getJobStatus(params)._field()\n\nif (field.isMissing()) {\n // The property is absent from the JSON response\n} else if (field.isNull()) {\n // The property was set to literal null\n} else {\n // Check if value was provided as a string\n // Other methods include `asNumber()`, `asBoolean()`, etc.\n val jsonString: String? = field.asString();\n\n // Try to deserialize into a custom type\n val myObject: MyClass = field.asUnknown()!!.convert(MyClass::class.java)\n}\n```\n\n### Response validation\n\nIn rare cases, the API may return a response that doesn\'t match the expected type. For example, the SDK may expect a property to contain a `String`, but the API could return something else.\n\nBy default, the SDK will not throw an exception in this case. It will throw [`UmaaasInvalidDataException`](umaaas-kotlin-core/src/main/kotlin/com/lightspark/umaaas/errors/UmaaasInvalidDataException.kt) only if you directly access the property.\n\nValidating the response is _not_ forwards compatible with new types from the API for existing fields.\n\nIf you would still prefer to check that the response is completely well-typed upfront, then either call `validate()`:\n\n```kotlin\nimport com.lightspark.umaaas.models.users.bulk.BulkGetJobStatusResponse\n\nval response: BulkGetJobStatusResponse = client.users().bulk().getJobStatus(params).validate()\n```\n\nOr configure the method call to validate the response using the `responseValidation` method:\n\n```kotlin\nimport com.lightspark.umaaas.models.users.UserCreateResponse\n\nval user: UserCreateResponse = client.users().create(\n params, RequestOptions.builder().responseValidation(true).build()\n)\n```\n\nOr configure the default for all method calls at the client level:\n\n```kotlin\nimport com.lightspark.umaaas.client.UmaaasClient\nimport com.lightspark.umaaas.client.okhttp.UmaaasOkHttpClient\n\nval client: UmaaasClient = UmaaasOkHttpClient.builder()\n .fromEnv()\n .responseValidation(true)\n .build()\n```\n\n## FAQ\n\n### Why don\'t you use plain `enum` classes?\n\nKotlin `enum` classes are not trivially [forwards compatible](https://www.stainless.com/blog/making-java-enums-forwards-compatible). Using them in the SDK could cause runtime exceptions if the API is updated to respond with a new enum value.\n\n### Why do you represent fields using `JsonField` instead of just plain `T`?\n\nUsing `JsonField` enables a few features:\n\n- Allowing usage of [undocumented API functionality](#undocumented-api-functionality)\n- Lazily [validating the API response against the expected shape](#response-validation)\n- Representing absent vs explicitly null values\n\n### Why don\'t you use [`data` classes](https://kotlinlang.org/docs/data-classes.html)?\n\nIt is not [backwards compatible to add new fields to a data class](https://kotlinlang.org/docs/api-guidelines-backward-compatibility.html#avoid-using-data-classes-in-your-api) and we don\'t want to introduce a breaking change every time we add a field to a class.\n\n### Why don\'t you use checked exceptions?\n\nChecked exceptions are widely considered a mistake in the Java programming language. In fact, they were omitted from Kotlin for this reason.\n\nChecked exceptions:\n\n- Are verbose to handle\n- Encourage error handling at the wrong level of abstraction, where nothing can be done about the error\n- Are tedious to propagate due to the [function coloring problem](https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function)\n- Don\'t play well with lambdas (also due to the function coloring problem)\n\n## Semantic versioning\n\nThis package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:\n\n1. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_\n2. Changes that we do not expect to impact the vast majority of users in practice.\n\nWe take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.\n\nWe are keen for your feedback; please open an [issue](https://www.github.com/lightsparkdev/umaaas-kotlin-sdk/issues) with questions, bugs, or suggestions.\n', + }, + { + language: 'typescript', + content: + "# Umaaas TypeScript API Library\n\n[![NPM version](https://img.shields.io/npm/v/umaaas.svg?label=npm%20(stable))](https://npmjs.org/package/umaaas) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/umaaas)\n\nThis library provides convenient access to the Umaaas REST API from server-side TypeScript or JavaScript.\n\n\n\nThe REST API documentation can be found on [lightsparkdev.github.io](https://lightsparkdev.github.io/umaaas-api/). The full API of this library can be found in [api.md](api.md).\n\nIt is generated with [Stainless](https://www.stainless.com/).\n\n## MCP Server\n\nUse the Umaaas MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application.\n\n[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=umaaas_mcp&config=eyJuYW1lIjoidW1hYWFzX21jcCIsInRyYW5zcG9ydCI6Imh0dHAiLCJ1cmwiOiJodHRwczovL3VtYWFhcy5zdGxtY3AuY29tIiwiaGVhZGVycyI6eyJ4LXVtYWFhcy1jbGllbnQtaWQiOiJNeSBVc2VybmFtZSIsIngtdW1hYWFzLWNsaWVudC1zZWNyZXQiOiJNeSBQYXNzd29yZCJ9fQ)\n[![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22umaaas_mcp%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fumaaas.stlmcp.com%22%2C%22headers%22%3A%7B%22x-umaaas-client-id%22%3A%22My%20Username%22%2C%22x-umaaas-client-secret%22%3A%22My%20Password%22%7D%7D)\n\n> Note: You may need to set environment variables in your MCP client.\n\n## Installation\n\n```sh\nnpm install git+ssh://git@github.com:stainless-sdks/umaaas-typescript.git\n```\n> [!NOTE]\n> Once this package is [published to npm](https://www.stainless.com/docs/guides/publish), this will become: `npm install umaaas`\n\n\n\n## Usage\n\nThe full API of this library can be found in [api.md](api.md).\n\n\n```js\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst user = await client.users.create({\n bankAccountInfo: {\n bankName: 'BBVA Mexico',\n clabeNumber: '123456789012345678',\n accountType: 'CLABE',\n },\n platformUserId: '9f84e0c2a72c4fa',\n umaAddress: '$john.doe@uma.domain.com',\n userType: 'INDIVIDUAL',\n});\n```\n\n\n\n### Request & Response types\n\nThis library includes TypeScript definitions for all request params and response fields. You may import and use them like so:\n\n\n```ts\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n username: process.env['UMAAAS_CLIENT_ID'], // This is the default and can be omitted\n password: process.env['UMAAAS_CLIENT_SECRET'], // This is the default and can be omitted\n});\n\nconst params: Umaaas.UserCreateParams = {\n bankAccountInfo: {\n bankName: 'BBVA Mexico',\n clabeNumber: '123456789012345678',\n accountType: 'CLABE',\n },\n platformUserId: '9f84e0c2a72c4fa',\n umaAddress: '$john.doe@uma.domain.com',\n userType: 'INDIVIDUAL',\n};\nconst user: Umaaas.UserCreateResponse = await client.users.create(params);\n```\n\nDocumentation for each method, request param, and response field are available in docstrings and will appear on hover in most modern editors.\n\n## File uploads\n\nRequest parameters that correspond to file uploads can be passed in many different forms:\n- `File` (or an object with the same structure)\n- a `fetch` `Response` (or an object with the same structure)\n- an `fs.ReadStream`\n- the return value of our `toFile` helper\n\n```ts\nimport fs from 'fs';\nimport Umaaas, { toFile } from 'umaaas';\n\nconst client = new Umaaas();\n\n// If you have access to Node `fs` we recommend using `fs.createReadStream()`:\nawait client.users.bulk.upload({ file: fs.createReadStream('/path/to/file') });\n\n// Or if you have the web `File` API you can pass a `File` instance:\nawait client.users.bulk.upload({ file: new File(['my bytes'], 'file') });\n\n// You can also pass a `fetch` `Response`:\nawait client.users.bulk.upload({ file: await fetch('https://somesite/file') });\n\n// Finally, if none of the above are convenient, you can use our `toFile` helper:\nawait client.users.bulk.upload({ file: await toFile(Buffer.from('my bytes'), 'file') });\nawait client.users.bulk.upload({ file: await toFile(new Uint8Array([0, 1, 2]), 'file') });\n```\n\n\n\n## Handling errors\n\nWhen the library is unable to connect to the API,\nor if the API returns a non-success status code (i.e., 4xx or 5xx response),\na subclass of `APIError` will be thrown:\n\n\n```ts\nconst user = await client.users\n .create({\n bankAccountInfo: {\n bankName: 'BBVA Mexico',\n clabeNumber: '123456789012345678',\n accountType: 'CLABE',\n },\n platformUserId: '9f84e0c2a72c4fa',\n umaAddress: '$john.doe@uma.domain.com',\n userType: 'INDIVIDUAL',\n })\n .catch(async (err) => {\n if (err instanceof Umaaas.APIError) {\n console.log(err.status); // 400\n console.log(err.name); // BadRequestError\n console.log(err.headers); // {server: 'nginx', ...}\n } else {\n throw err;\n }\n });\n```\n\nError codes are as follows:\n\n| Status Code | Error Type |\n| ----------- | -------------------------- |\n| 400 | `BadRequestError` |\n| 401 | `AuthenticationError` |\n| 403 | `PermissionDeniedError` |\n| 404 | `NotFoundError` |\n| 422 | `UnprocessableEntityError` |\n| 429 | `RateLimitError` |\n| >=500 | `InternalServerError` |\n| N/A | `APIConnectionError` |\n\n### Retries\n\nCertain errors will be automatically retried 2 times by default, with a short exponential backoff.\nConnection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict,\n429 Rate Limit, and >=500 Internal errors will all be retried by default.\n\nYou can use the `maxRetries` option to configure or disable this:\n\n\n```js\n// Configure the default for all requests:\nconst client = new Umaaas({\n maxRetries: 0, // default is 2\n});\n\n// Or, configure per-request:\nawait client.users.create({\n bankAccountInfo: {\n bankName: 'BBVA Mexico',\n clabeNumber: '123456789012345678',\n accountType: 'CLABE',\n},\n platformUserId: '9f84e0c2a72c4fa',\n umaAddress: '$john.doe@uma.domain.com',\n userType: 'INDIVIDUAL',\n}, {\n maxRetries: 5,\n});\n```\n\n### Timeouts\n\nRequests time out after 1 minute by default. You can configure this with a `timeout` option:\n\n\n```ts\n// Configure the default for all requests:\nconst client = new Umaaas({\n timeout: 20 * 1000, // 20 seconds (default is 1 minute)\n});\n\n// Override per-request:\nawait client.users.create({\n bankAccountInfo: {\n bankName: 'BBVA Mexico',\n clabeNumber: '123456789012345678',\n accountType: 'CLABE',\n},\n platformUserId: '9f84e0c2a72c4fa',\n umaAddress: '$john.doe@uma.domain.com',\n userType: 'INDIVIDUAL',\n}, {\n timeout: 5 * 1000,\n});\n```\n\nOn timeout, an `APIConnectionTimeoutError` is thrown.\n\nNote that requests which time out will be [retried twice by default](#retries).\n\n## Auto-pagination\n\nList methods in the Umaaas API are paginated.\nYou can use the `for await … of` syntax to iterate through items across all pages:\n\n```ts\nasync function fetchAllUserListResponses(params) {\n const allUserListResponses = [];\n // Automatically fetches more pages as needed.\n for await (const userListResponse of client.users.list()) {\n allUserListResponses.push(userListResponse);\n }\n return allUserListResponses;\n}\n```\n\nAlternatively, you can request a single page at a time:\n\n```ts\nlet page = await client.users.list();\nfor (const userListResponse of page.data) {\n console.log(userListResponse);\n}\n\n// Convenience methods are provided for manually paginating:\nwhile (page.hasNextPage()) {\n page = await page.getNextPage();\n // ...\n}\n```\n\n\n\n## Advanced Usage\n\n### Accessing raw Response data (e.g., headers)\n\nThe \"raw\" `Response` returned by `fetch()` can be accessed through the `.asResponse()` method on the `APIPromise` type that all methods return.\nThis method returns as soon as the headers for a successful response are received and does not consume the response body, so you are free to write custom parsing or streaming logic.\n\nYou can also use the `.withResponse()` method to get the raw `Response` along with the parsed data.\nUnlike `.asResponse()` this method consumes the body, returning once it is parsed.\n\n\n```ts\nconst client = new Umaaas();\n\nconst response = await client.users\n .create({\n bankAccountInfo: {\n bankName: 'BBVA Mexico',\n clabeNumber: '123456789012345678',\n accountType: 'CLABE',\n },\n platformUserId: '9f84e0c2a72c4fa',\n umaAddress: '$john.doe@uma.domain.com',\n userType: 'INDIVIDUAL',\n })\n .asResponse();\nconsole.log(response.headers.get('X-My-Header'));\nconsole.log(response.statusText); // access the underlying Response object\n\nconst { data: user, response: raw } = await client.users\n .create({\n bankAccountInfo: {\n bankName: 'BBVA Mexico',\n clabeNumber: '123456789012345678',\n accountType: 'CLABE',\n },\n platformUserId: '9f84e0c2a72c4fa',\n umaAddress: '$john.doe@uma.domain.com',\n userType: 'INDIVIDUAL',\n })\n .withResponse();\nconsole.log(raw.headers.get('X-My-Header'));\nconsole.log(user);\n```\n\n### Logging\n\n> [!IMPORTANT]\n> All log messages are intended for debugging only. The format and content of log messages\n> may change between releases.\n\n#### Log levels\n\nThe log level can be configured in two ways:\n\n1. Via the `UMAAAS_LOG` environment variable\n2. Using the `logLevel` client option (overrides the environment variable if set)\n\n```ts\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n logLevel: 'debug', // Show all log messages\n});\n```\n\nAvailable log levels, from most to least verbose:\n\n- `'debug'` - Show debug messages, info, warnings, and errors\n- `'info'` - Show info messages, warnings, and errors\n- `'warn'` - Show warnings and errors (default)\n- `'error'` - Show only errors\n- `'off'` - Disable all logging\n\nAt the `'debug'` level, all HTTP requests and responses are logged, including headers and bodies.\nSome authentication-related headers are redacted, but sensitive data in request and response bodies\nmay still be visible.\n\n#### Custom logger\n\nBy default, this library logs to `globalThis.console`. You can also provide a custom logger.\nMost logging libraries are supported, including [pino](https://www.npmjs.com/package/pino), [winston](https://www.npmjs.com/package/winston), [bunyan](https://www.npmjs.com/package/bunyan), [consola](https://www.npmjs.com/package/consola), [signale](https://www.npmjs.com/package/signale), and [@std/log](https://jsr.io/@std/log). If your logger doesn't work, please open an issue.\n\nWhen providing a custom logger, the `logLevel` option still controls which messages are emitted, messages\nbelow the configured level will not be sent to your logger.\n\n```ts\nimport Umaaas from 'umaaas';\nimport pino from 'pino';\n\nconst logger = pino();\n\nconst client = new Umaaas({\n logger: logger.child({ name: 'Umaaas' }),\n logLevel: 'debug', // Send all messages to pino, allowing it to filter\n});\n```\n\n### Making custom/undocumented requests\n\nThis library is typed for convenient access to the documented API. If you need to access undocumented\nendpoints, params, or response properties, the library can still be used.\n\n#### Undocumented endpoints\n\nTo make requests to undocumented endpoints, you can use `client.get`, `client.post`, and other HTTP verbs.\nOptions on the client, such as retries, will be respected when making these requests.\n\n```ts\nawait client.post('/some/path', {\n body: { some_prop: 'foo' },\n query: { some_query_arg: 'bar' },\n});\n```\n\n#### Undocumented request params\n\nTo make requests using undocumented parameters, you may use `// @ts-expect-error` on the undocumented\nparameter. This library doesn't validate at runtime that the request matches the type, so any extra values you\nsend will be sent as-is.\n\n```ts\nclient.users.create({\n // ...\n // @ts-expect-error baz is not yet public\n baz: 'undocumented option',\n});\n```\n\nFor requests with the `GET` verb, any extra params will be in the query, all other requests will send the\nextra param in the body.\n\nIf you want to explicitly send an extra argument, you can do so with the `query`, `body`, and `headers` request\noptions.\n\n#### Undocumented response properties\n\nTo access undocumented response properties, you may access the response object with `// @ts-expect-error` on\nthe response object, or cast the response object to the requisite type. Like the request params, we do not\nvalidate or strip extra properties from the response from the API.\n\n### Customizing the fetch client\n\nBy default, this library expects a global `fetch` function is defined.\n\nIf you want to use a different `fetch` function, you can either polyfill the global:\n\n```ts\nimport fetch from 'my-fetch';\n\nglobalThis.fetch = fetch;\n```\n\nOr pass it to the client:\n\n```ts\nimport Umaaas from 'umaaas';\nimport fetch from 'my-fetch';\n\nconst client = new Umaaas({ fetch });\n```\n\n### Fetch options\n\nIf you want to set custom `fetch` options without overriding the `fetch` function, you can provide a `fetchOptions` object when instantiating the client or making a request. (Request-specific options override client options.)\n\n```ts\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n fetchOptions: {\n // `RequestInit` options\n },\n});\n```\n\n#### Configuring proxies\n\nTo modify proxy behavior, you can provide custom `fetchOptions` that add runtime-specific proxy\noptions to requests:\n\n **Node** [[docs](https://github.com/nodejs/undici/blob/main/docs/docs/api/ProxyAgent.md#example---proxyagent-with-fetch)]\n\n```ts\nimport Umaaas from 'umaaas';\nimport * as undici from 'undici';\n\nconst proxyAgent = new undici.ProxyAgent('http://localhost:8888');\nconst client = new Umaaas({\n fetchOptions: {\n dispatcher: proxyAgent,\n },\n});\n```\n\n **Bun** [[docs](https://bun.sh/guides/http/proxy)]\n\n```ts\nimport Umaaas from 'umaaas';\n\nconst client = new Umaaas({\n fetchOptions: {\n proxy: 'http://localhost:8888',\n },\n});\n```\n\n **Deno** [[docs](https://docs.deno.com/api/deno/~/Deno.createHttpClient)]\n\n```ts\nimport Umaaas from 'npm:umaaas';\n\nconst httpClient = Deno.createHttpClient({ proxy: { url: 'http://localhost:8888' } });\nconst client = new Umaaas({\n fetchOptions: {\n client: httpClient,\n },\n});\n```\n\n## Frequently Asked Questions\n\n## Semantic versioning\n\nThis package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:\n\n1. Changes that only affect static types, without breaking runtime behavior.\n2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_\n3. Changes that we do not expect to impact the vast majority of users in practice.\n\nWe take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.\n\nWe are keen for your feedback; please open an [issue](https://www.github.com/stainless-sdks/umaaas-typescript/issues) with questions, bugs, or suggestions.\n\n## Requirements\n\nTypeScript >= 4.9 is supported.\n\nThe following runtimes are supported:\n\n- Web browsers (Up-to-date Chrome, Firefox, Safari, Edge, and more)\n- Node.js 20 LTS or later ([non-EOL](https://endoflife.date/nodejs)) versions.\n- Deno v1.28.0 or higher.\n- Bun 1.0 or later.\n- Cloudflare Workers.\n- Vercel Edge Runtime.\n- Jest 28 or greater with the `\"node\"` environment (`\"jsdom\"` is not supported at this time).\n- Nitro v2.6 or greater.\n\nNote that React Native is not supported at this time.\n\nIf you are interested in other runtime environments, please open or upvote an issue on GitHub.\n\n## Contributing\n\nSee [the contributing documentation](./CONTRIBUTING.md).\n", + }, +]; + +const INDEX_OPTIONS = { + fields: [ + 'name', + 'endpoint', + 'summary', + 'description', + 'qualified', + 'stainlessPath', + 'content', + 'sectionContext', + ], + storeFields: ['kind', '_original'], + searchOptions: { + prefix: true, + fuzzy: 0.1, + boost: { + name: 5, + stainlessPath: 3, + endpoint: 3, + qualified: 3, + summary: 2, + content: 1, + description: 1, + } as Record, + }, +}; + +/** + * Self-contained local search engine backed by MiniSearch. + * Method data is embedded at SDK build time; prose documents + * can be loaded from an optional docs directory at runtime. + */ +export class LocalDocsSearch { + private methodIndex: MiniSearch; + private proseIndex: MiniSearch; + + private constructor() { + this.methodIndex = new MiniSearch(INDEX_OPTIONS); + this.proseIndex = new MiniSearch(INDEX_OPTIONS); + } + + static async create(opts?: { docsDir?: string }): Promise { + const instance = new LocalDocsSearch(); + instance.indexMethods(EMBEDDED_METHODS); + for (const readme of EMBEDDED_READMES) { + instance.indexProse(readme.content, `readme:${readme.language}`); + } + if (opts?.docsDir) { + await instance.loadDocsDirectory(opts.docsDir); + } + return instance; + } + + search(props: { + query: string; + language?: string; + detail?: string; + maxResults?: number; + maxLength?: number; + }): SearchResult { + const { query, language = 'typescript', detail = 'default', maxResults = 5, maxLength = 100_000 } = props; + + const useMarkdown = detail === 'verbose' || detail === 'high'; + + // Search both indices and merge results by score. + // Filter prose hits so language-tagged content (READMEs and docs with + // frontmatter) only matches the requested language. + const methodHits = this.methodIndex + .search(query) + .map((hit) => ({ ...hit, _kind: 'http_method' as const })); + const proseHits = this.proseIndex + .search(query) + .filter((hit) => { + const source = ((hit as Record)['_original'] as ProseChunk | undefined)?.source; + if (!source) return true; + // Check for language-tagged sources: "readme:" or "lang::" + let taggedLang: string | undefined; + if (source.startsWith('readme:')) taggedLang = source.slice('readme:'.length); + else if (source.startsWith('lang:')) taggedLang = source.split(':')[1]; + if (!taggedLang) return true; + return taggedLang === language || (language === 'javascript' && taggedLang === 'typescript'); + }) + .map((hit) => ({ ...hit, _kind: 'prose' as const })); + const merged = [...methodHits, ...proseHits].sort((a, b) => b.score - a.score); + const top = merged.slice(0, maxResults); + + const fullResults: (string | Record)[] = []; + + for (const hit of top) { + const original = (hit as Record)['_original']; + if (hit._kind === 'http_method') { + const m = original as MethodEntry; + if (useMarkdown && m.markdown) { + fullResults.push(m.markdown); + } else { + // Use per-language data when available, falling back to the + // top-level fields (which are TypeScript-specific in the + // legacy codepath). + const langData = m.perLanguage?.[language]; + fullResults.push({ + method: langData?.method ?? m.qualified, + summary: m.summary, + description: m.description, + endpoint: `${m.httpMethod.toUpperCase()} ${m.endpoint}`, + ...(langData?.example ? { example: langData.example } : {}), + ...(m.params ? { params: m.params } : {}), + ...(m.response ? { response: m.response } : {}), + }); + } + } else { + const c = original as ProseChunk; + fullResults.push({ + content: c.content, + ...(c.source ? { source: c.source } : {}), + }); + } + } + + let totalLength = 0; + const results: (string | Record)[] = []; + for (const result of fullResults) { + const len = typeof result === 'string' ? result.length : JSON.stringify(result).length; + totalLength += len; + if (totalLength > maxLength) break; + results.push(result); + } + + if (results.length < fullResults.length) { + results.unshift(`Truncated; showing ${results.length} of ${fullResults.length} results.`); + } + + return { results }; + } + + private indexMethods(methods: MethodEntry[]): void { + const docs: MiniSearchDocument[] = methods.map((m, i) => ({ + id: `method-${i}`, + kind: 'http_method' as const, + name: m.name, + endpoint: m.endpoint, + summary: m.summary, + description: m.description, + qualified: m.qualified, + stainlessPath: m.stainlessPath, + _original: m as unknown as Record, + })); + if (docs.length > 0) { + this.methodIndex.addAll(docs); + } + } + + private async loadDocsDirectory(docsDir: string): Promise { + let entries; + try { + entries = await fs.readdir(docsDir, { withFileTypes: true }); + } catch (err) { + getLogger().warn({ err, docsDir }, 'Could not read docs directory'); + return; + } + + const files = entries + .filter((e) => e.isFile()) + .filter((e) => e.name.endsWith('.md') || e.name.endsWith('.markdown') || e.name.endsWith('.json')); + + for (const file of files) { + try { + const filePath = path.join(docsDir, file.name); + const content = await fs.readFile(filePath, 'utf-8'); + + if (file.name.endsWith('.json')) { + const texts = extractTexts(JSON.parse(content)); + if (texts.length > 0) { + this.indexProse(texts.join('\n\n'), file.name); + } + } else { + // Parse optional YAML frontmatter for language tagging. + // Files with a "language" field in frontmatter will only + // surface in searches for that language. + // + // Example: + // --- + // language: python + // --- + // # Error handling in Python + // ... + const frontmatter = parseFrontmatter(content); + const source = frontmatter.language ? `lang:${frontmatter.language}:${file.name}` : file.name; + this.indexProse(content, source); + } + } catch (err) { + getLogger().warn({ err, file: file.name }, 'Failed to index docs file'); + } + } + } + + private indexProse(markdown: string, source: string): void { + const chunks = chunkMarkdown(markdown); + const baseId = this.proseIndex.documentCount; + + const docs: MiniSearchDocument[] = chunks.map((chunk, i) => ({ + id: `prose-${baseId + i}`, + kind: 'prose' as const, + content: chunk.content, + ...(chunk.sectionContext != null ? { sectionContext: chunk.sectionContext } : {}), + _original: { ...chunk, source } as unknown as Record, + })); + + if (docs.length > 0) { + this.proseIndex.addAll(docs); + } + } +} + +/** Lightweight markdown chunker — splits on headers, chunks by word count. */ +function chunkMarkdown(markdown: string): { content: string; tag: string; sectionContext?: string }[] { + // Strip YAML frontmatter + const stripped = markdown.replace(/^---\n[\s\S]*?\n---\n?/, ''); + const lines = stripped.split('\n'); + + const chunks: { content: string; tag: string; sectionContext?: string }[] = []; + const headers: string[] = []; + let current: string[] = []; + + const flush = () => { + const text = current.join('\n').trim(); + if (!text) return; + const sectionContext = headers.length > 0 ? headers.join(' > ') : undefined; + // Split into ~200-word chunks + const words = text.split(/\s+/); + for (let i = 0; i < words.length; i += 200) { + const slice = words.slice(i, i + 200).join(' '); + if (slice) { + chunks.push({ content: slice, tag: 'p', ...(sectionContext != null ? { sectionContext } : {}) }); + } + } + current = []; + }; + + for (const line of lines) { + const headerMatch = line.match(/^(#{1,6})\s+(.+)/); + if (headerMatch) { + flush(); + const level = headerMatch[1]!.length; + const text = headerMatch[2]!.trim(); + while (headers.length >= level) headers.pop(); + headers.push(text); + } else { + current.push(line); + } + } + flush(); + + return chunks; +} + +/** Recursively extracts string values from a JSON structure. */ +function extractTexts(data: unknown, depth = 0): string[] { + if (depth > 10) return []; + if (typeof data === 'string') return data.trim() ? [data] : []; + if (Array.isArray(data)) return data.flatMap((item) => extractTexts(item, depth + 1)); + if (typeof data === 'object' && data !== null) { + return Object.values(data).flatMap((v) => extractTexts(v, depth + 1)); + } + return []; +} + +/** Parses YAML frontmatter from a markdown string, extracting the language field if present. */ +function parseFrontmatter(markdown: string): { language?: string } { + const match = markdown.match(/^---\n([\s\S]*?)\n---/); + if (!match) return {}; + const body = match[1] ?? ''; + const langMatch = body.match(/^language:\s*(.+)$/m); + return langMatch ? { language: langMatch[1]!.trim() } : {}; +} diff --git a/mcp-server/src/logger.ts b/mcp-server/src/logger.ts new file mode 100644 index 00000000..29dab11c --- /dev/null +++ b/mcp-server/src/logger.ts @@ -0,0 +1,28 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { pino, type Level, type Logger } from 'pino'; +import pretty from 'pino-pretty'; + +let _logger: Logger | undefined; + +export function configureLogger({ level, pretty: usePretty }: { level: Level; pretty: boolean }): void { + _logger = pino( + { + level, + timestamp: pino.stdTimeFunctions.isoTime, + formatters: { + level(label) { + return { level: label }; + }, + }, + }, + usePretty ? pretty({ colorize: true, levelFirst: true, destination: 2 }) : process.stderr, + ); +} + +export function getLogger(): Logger { + if (!_logger) { + throw new Error('Logger has not been configured. Call configureLogger() before using the logger.'); + } + return _logger; +} diff --git a/mcp-server/src/methods.ts b/mcp-server/src/methods.ts new file mode 100644 index 00000000..dead87b8 --- /dev/null +++ b/mcp-server/src/methods.ts @@ -0,0 +1,266 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { McpOptions } from './options'; + +export type SdkMethod = { + clientCallName: string; + fullyQualifiedName: string; + httpMethod?: 'get' | 'post' | 'put' | 'patch' | 'delete' | 'query'; + httpPath?: string; +}; + +export const sdkMethods: SdkMethod[] = [ + { + clientCallName: 'client.users.create', + fullyQualifiedName: 'users.create', + httpMethod: 'post', + httpPath: '/users', + }, + { + clientCallName: 'client.users.retrieve', + fullyQualifiedName: 'users.retrieve', + httpMethod: 'get', + httpPath: '/users/{userId}', + }, + { + clientCallName: 'client.users.update', + fullyQualifiedName: 'users.update', + httpMethod: 'patch', + httpPath: '/users/{userId}', + }, + { + clientCallName: 'client.users.list', + fullyQualifiedName: 'users.list', + httpMethod: 'get', + httpPath: '/users', + }, + { + clientCallName: 'client.users.delete', + fullyQualifiedName: 'users.delete', + httpMethod: 'delete', + httpPath: '/users/{userId}', + }, + { + clientCallName: 'client.users.bulk.getJobStatus', + fullyQualifiedName: 'users.bulk.getJobStatus', + httpMethod: 'get', + httpPath: '/users/bulk/jobs/{jobId}', + }, + { + clientCallName: 'client.users.bulk.upload', + fullyQualifiedName: 'users.bulk.upload', + httpMethod: 'post', + httpPath: '/users/bulk/csv', + }, + { + clientCallName: 'client.tokens.create', + fullyQualifiedName: 'tokens.create', + httpMethod: 'post', + httpPath: '/tokens', + }, + { + clientCallName: 'client.tokens.retrieve', + fullyQualifiedName: 'tokens.retrieve', + httpMethod: 'get', + httpPath: '/tokens/{tokenId}', + }, + { + clientCallName: 'client.tokens.list', + fullyQualifiedName: 'tokens.list', + httpMethod: 'get', + httpPath: '/tokens', + }, + { + clientCallName: 'client.tokens.delete', + fullyQualifiedName: 'tokens.delete', + httpMethod: 'delete', + httpPath: '/tokens/{tokenId}', + }, + { + clientCallName: 'client.config.retrieve', + fullyQualifiedName: 'config.retrieve', + httpMethod: 'get', + httpPath: '/config', + }, + { + clientCallName: 'client.config.update', + fullyQualifiedName: 'config.update', + httpMethod: 'patch', + httpPath: '/config', + }, + { + clientCallName: 'client.webhooks.sendTest', + fullyQualifiedName: 'webhooks.sendTest', + httpMethod: 'post', + httpPath: '/webhooks/test', + }, + { + clientCallName: 'client.transactions.retrieve', + fullyQualifiedName: 'transactions.retrieve', + httpMethod: 'get', + httpPath: '/transactions/{transactionId}', + }, + { + clientCallName: 'client.transactions.list', + fullyQualifiedName: 'transactions.list', + httpMethod: 'get', + httpPath: '/transactions', + }, + { + clientCallName: 'client.transactions.approve', + fullyQualifiedName: 'transactions.approve', + httpMethod: 'post', + httpPath: '/transactions/{transactionId}/approve', + }, + { + clientCallName: 'client.transactions.reject', + fullyQualifiedName: 'transactions.reject', + httpMethod: 'post', + httpPath: '/transactions/{transactionId}/reject', + }, + { + clientCallName: 'client.receiver.lookup', + fullyQualifiedName: 'receiver.lookup', + httpMethod: 'get', + httpPath: '/receiver/{receiverUmaAddress}', + }, + { + clientCallName: 'client.quotes.create', + fullyQualifiedName: 'quotes.create', + httpMethod: 'post', + httpPath: '/quotes', + }, + { + clientCallName: 'client.quotes.retrieve', + fullyQualifiedName: 'quotes.retrieve', + httpMethod: 'get', + httpPath: '/quotes/{quoteId}', + }, + { + clientCallName: 'client.quotes.retry', + fullyQualifiedName: 'quotes.retry', + httpMethod: 'post', + httpPath: '/quotes/{quoteId}/retry', + }, + { + clientCallName: 'client.invitations.create', + fullyQualifiedName: 'invitations.create', + httpMethod: 'post', + httpPath: '/invitations', + }, + { + clientCallName: 'client.invitations.retrieve', + fullyQualifiedName: 'invitations.retrieve', + httpMethod: 'get', + httpPath: '/invitations/{invitationCode}', + }, + { + clientCallName: 'client.invitations.cancel', + fullyQualifiedName: 'invitations.cancel', + httpMethod: 'post', + httpPath: '/invitations/{invitationCode}/cancel', + }, + { + clientCallName: 'client.invitations.claim', + fullyQualifiedName: 'invitations.claim', + httpMethod: 'post', + httpPath: '/invitations/{invitationCode}/claim', + }, + { + clientCallName: 'client.sandbox.receivePayment', + fullyQualifiedName: 'sandbox.receivePayment', + httpMethod: 'post', + httpPath: '/sandbox/receive', + }, + { + clientCallName: 'client.sandbox.sendFunds', + fullyQualifiedName: 'sandbox.sendFunds', + httpMethod: 'post', + httpPath: '/sandbox/send', + }, + { + clientCallName: 'client.umaProviders.list', + fullyQualifiedName: 'umaProviders.list', + httpMethod: 'get', + httpPath: '/uma-providers', + }, + { + clientCallName: 'client.fbo.confirmPayment', + fullyQualifiedName: 'fbo.confirmPayment', + httpMethod: 'post', + httpPath: '/fbo/confirm/{quoteId}', + }, +]; + +function allowedMethodsForCodeTool(options: McpOptions | undefined): SdkMethod[] | undefined { + if (!options) { + return undefined; + } + + let allowedMethods: SdkMethod[]; + + if (options.codeAllowHttpGets || options.codeAllowedMethods) { + // Start with nothing allowed and then add into it from options + let allowedMethodsSet = new Set(); + + if (options.codeAllowHttpGets) { + // Add all methods that map to an HTTP GET + sdkMethods + .filter((method) => method.httpMethod === 'get') + .forEach((method) => allowedMethodsSet.add(method)); + } + + if (options.codeAllowedMethods) { + // Add all methods that match any of the allowed regexps + const allowedRegexps = options.codeAllowedMethods.map((pattern) => { + try { + return new RegExp(pattern); + } catch (e) { + throw new Error( + `Invalid regex pattern for allowed method: "${pattern}": ${e instanceof Error ? e.message : e}`, + ); + } + }); + + sdkMethods + .filter((method) => allowedRegexps.some((regexp) => regexp.test(method.fullyQualifiedName))) + .forEach((method) => allowedMethodsSet.add(method)); + } + + allowedMethods = Array.from(allowedMethodsSet); + } else { + // Start with everything allowed + allowedMethods = [...sdkMethods]; + } + + if (options.codeBlockedMethods) { + // Filter down based on blocked regexps + const blockedRegexps = options.codeBlockedMethods.map((pattern) => { + try { + return new RegExp(pattern); + } catch (e) { + throw new Error( + `Invalid regex pattern for blocked method: "${pattern}": ${e instanceof Error ? e.message : e}`, + ); + } + }); + + allowedMethods = allowedMethods.filter( + (method) => !blockedRegexps.some((regexp) => regexp.test(method.fullyQualifiedName)), + ); + } + + return allowedMethods; +} + +export function blockedMethodsForCodeTool(options: McpOptions | undefined): SdkMethod[] | undefined { + const allowedMethods = allowedMethodsForCodeTool(options); + if (!allowedMethods) { + return undefined; + } + + const allowedSet = new Set(allowedMethods.map((method) => method.fullyQualifiedName)); + + // Return any methods that are not explicitly allowed + return sdkMethods.filter((method) => !allowedSet.has(method.fullyQualifiedName)); +} diff --git a/mcp-server/src/options.ts b/mcp-server/src/options.ts new file mode 100644 index 00000000..f1518764 --- /dev/null +++ b/mcp-server/src/options.ts @@ -0,0 +1,185 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import qs from 'qs'; +import yargs from 'yargs'; +import { hideBin } from 'yargs/helpers'; +import z from 'zod'; +import { readEnv } from './util'; + +export type CLIOptions = McpOptions & { + debug: boolean; + logFormat: 'json' | 'pretty'; + transport: 'stdio' | 'http'; + port: number | undefined; + socket: string | undefined; +}; + +export type McpOptions = { + includeCodeTool?: boolean | undefined; + includeDocsTools?: boolean | undefined; + stainlessApiKey?: string | undefined; + docsSearchMode?: 'stainless-api' | 'local' | undefined; + docsDir?: string | undefined; + codeAllowHttpGets?: boolean | undefined; + codeAllowedMethods?: string[] | undefined; + codeBlockedMethods?: string[] | undefined; + codeExecutionMode: McpCodeExecutionMode; + customInstructionsPath?: string | undefined; +}; + +export type McpCodeExecutionMode = 'stainless-sandbox' | 'local'; + +export function parseCLIOptions(): CLIOptions { + const opts = yargs(hideBin(process.argv)) + .option('code-allow-http-gets', { + type: 'boolean', + description: + 'Allow all code tool methods that map to HTTP GET operations. If all code-allow-* flags are unset, then everything is allowed.', + }) + .option('code-allowed-methods', { + type: 'string', + array: true, + description: + 'Methods to explicitly allow for code tool. Evaluated as regular expressions against method fully qualified names. If all code-allow-* flags are unset, then everything is allowed.', + }) + .option('code-blocked-methods', { + type: 'string', + array: true, + description: + 'Methods to explicitly block for code tool. Evaluated as regular expressions against method fully qualified names. If all code-allow-* flags are unset, then everything is allowed.', + }) + .option('code-execution-mode', { + type: 'string', + choices: ['stainless-sandbox', 'local'], + default: 'stainless-sandbox', + description: + "Where to run code execution in code tool; 'stainless-sandbox' will execute code in Stainless-hosted sandboxes whereas 'local' will execute code locally on the MCP server machine.", + }) + .option('custom-instructions-path', { + type: 'string', + description: 'Path to custom instructions for the MCP server', + }) + .option('debug', { type: 'boolean', description: 'Enable debug logging' }) + .option('docs-dir', { + type: 'string', + description: + 'Path to a directory of local documentation files (markdown/JSON) to include in local docs search.', + }) + .option('docs-search-mode', { + type: 'string', + choices: ['stainless-api', 'local'], + default: 'stainless-api', + description: + "Where to search documentation; 'stainless-api' uses the Stainless-hosted search API whereas 'local' uses an in-memory search index built from embedded SDK method data and optional local docs files.", + }) + .option('log-format', { + type: 'string', + choices: ['json', 'pretty'], + description: 'Format for log output; defaults to json unless tty is detected', + }) + .option('no-tools', { + type: 'string', + array: true, + choices: ['code', 'docs'], + description: 'Tools to explicitly disable', + }) + .option('port', { + type: 'number', + default: 3000, + description: 'Port to serve on if using http transport', + }) + .option('socket', { type: 'string', description: 'Unix socket to serve on if using http transport' }) + .option('stainless-api-key', { + type: 'string', + default: readEnv('STAINLESS_API_KEY'), + description: + 'API key for Stainless. Used to authenticate requests to Stainless-hosted tools endpoints.', + }) + .option('tools', { + type: 'string', + array: true, + choices: ['code', 'docs'], + description: 'Tools to explicitly enable', + }) + .option('transport', { + type: 'string', + choices: ['stdio', 'http'], + default: 'stdio', + description: 'What transport to use; stdio for local servers or http for remote servers', + }) + .env('MCP_SERVER') + .version(true) + .help(); + + const argv = opts.parseSync(); + + const shouldIncludeToolType = (toolType: 'code' | 'docs') => + argv.noTools?.includes(toolType) ? false + : argv.tools?.includes(toolType) ? true + : undefined; + + const includeCodeTool = shouldIncludeToolType('code'); + const includeDocsTools = shouldIncludeToolType('docs'); + + const transport = argv.transport as 'stdio' | 'http'; + const logFormat = + argv.logFormat ? (argv.logFormat as 'json' | 'pretty') + : process.stderr.isTTY ? 'pretty' + : 'json'; + + return { + ...(includeCodeTool !== undefined && { includeCodeTool }), + ...(includeDocsTools !== undefined && { includeDocsTools }), + debug: !!argv.debug, + stainlessApiKey: argv.stainlessApiKey, + docsSearchMode: argv.docsSearchMode as 'stainless-api' | 'local' | undefined, + docsDir: argv.docsDir, + codeAllowHttpGets: argv.codeAllowHttpGets, + codeAllowedMethods: argv.codeAllowedMethods, + codeBlockedMethods: argv.codeBlockedMethods, + codeExecutionMode: argv.codeExecutionMode as McpCodeExecutionMode, + customInstructionsPath: argv.customInstructionsPath, + transport, + logFormat, + port: argv.port, + socket: argv.socket, + }; +} + +const coerceArray = (zodType: T) => + z.preprocess( + (val) => + Array.isArray(val) ? val + : val ? [val] + : val, + z.array(zodType).optional(), + ); + +const QueryOptions = z.object({ + tools: coerceArray(z.enum(['code', 'docs'])).describe('Specify which MCP tools to use'), + no_tools: coerceArray(z.enum(['code', 'docs'])).describe('Specify which MCP tools to not use.'), + tool: coerceArray(z.string()).describe('Include tools matching the specified names'), +}); + +export function parseQueryOptions(defaultOptions: McpOptions, query: unknown): McpOptions { + const queryObject = typeof query === 'string' ? qs.parse(query) : query; + const queryOptions = QueryOptions.parse(queryObject); + + let codeTool: boolean | undefined = + queryOptions.no_tools && queryOptions.no_tools?.includes('code') ? false + : queryOptions.tools?.includes('code') ? true + : defaultOptions.includeCodeTool; + + let docsTools: boolean | undefined = + queryOptions.no_tools && queryOptions.no_tools?.includes('docs') ? false + : queryOptions.tools?.includes('docs') ? true + : defaultOptions.includeDocsTools; + + return { + ...(codeTool !== undefined && { includeCodeTool: codeTool }), + ...(docsTools !== undefined && { includeDocsTools: docsTools }), + codeExecutionMode: defaultOptions.codeExecutionMode, + docsSearchMode: defaultOptions.docsSearchMode, + docsDir: defaultOptions.docsDir, + }; +} diff --git a/mcp-server/src/server.ts b/mcp-server/src/server.ts new file mode 100644 index 00000000..4c686165 --- /dev/null +++ b/mcp-server/src/server.ts @@ -0,0 +1,208 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { Server } from '@modelcontextprotocol/sdk/server/index.js'; +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import { + CallToolRequestSchema, + ListToolsRequestSchema, + SetLevelRequestSchema, +} from '@modelcontextprotocol/sdk/types.js'; +import { ClientOptions } from 'umaaas'; +import Umaaas from 'umaaas'; +import { codeTool } from './code-tool'; +import docsSearchTool from './docs-search-tool'; +import { setLocalSearch } from './docs-search-tool'; +import { LocalDocsSearch } from './local-docs-search'; +import { getInstructions } from './instructions'; +import { McpOptions } from './options'; +import { blockedMethodsForCodeTool } from './methods'; +import { HandlerFunction, McpRequestContext, ToolCallResult, McpTool } from './types'; + +export const newMcpServer = async ({ + stainlessApiKey, + customInstructionsPath, +}: { + stainlessApiKey?: string | undefined; + customInstructionsPath?: string | undefined; +}) => + new McpServer( + { + name: 'umaaas_api', + version: '0.0.1-alpha.0', + }, + { + instructions: await getInstructions({ stainlessApiKey, customInstructionsPath }), + capabilities: { tools: {}, logging: {} }, + }, + ); + +/** + * Initializes the provided MCP Server with the given tools and handlers. + * If not provided, the default client, tools and handlers will be used. + */ +export async function initMcpServer(params: { + server: Server | McpServer; + clientOptions?: ClientOptions; + mcpOptions?: McpOptions; + stainlessApiKey?: string | undefined; + upstreamClientEnvs?: Record | undefined; + mcpSessionId?: string | undefined; + mcpClientInfo?: { name: string; version: string } | undefined; +}) { + const server = params.server instanceof McpServer ? params.server.server : params.server; + + const logAtLevel = + (level: 'debug' | 'info' | 'warning' | 'error') => + (message: string, ...rest: unknown[]) => { + void server.sendLoggingMessage({ + level, + data: { message, rest }, + }); + }; + const logger = { + debug: logAtLevel('debug'), + info: logAtLevel('info'), + warn: logAtLevel('warning'), + error: logAtLevel('error'), + }; + + if (params.mcpOptions?.docsSearchMode === 'local') { + const docsDir = params.mcpOptions?.docsDir; + const localSearch = await LocalDocsSearch.create(docsDir ? { docsDir } : undefined); + setLocalSearch(localSearch); + } + + let _client: Umaaas | undefined; + let _clientError: Error | undefined; + let _logLevel: 'debug' | 'info' | 'warn' | 'error' | 'off' | undefined; + + const getClient = (): Umaaas => { + if (_clientError) throw _clientError; + if (!_client) { + try { + _client = new Umaaas({ + logger, + ...params.clientOptions, + defaultHeaders: { + ...params.clientOptions?.defaultHeaders, + 'X-Stainless-MCP': 'true', + }, + }); + if (_logLevel) { + _client = _client.withOptions({ logLevel: _logLevel }); + } + } catch (e) { + _clientError = e instanceof Error ? e : new Error(String(e)); + throw _clientError; + } + } + return _client; + }; + + const providedTools = selectTools(params.mcpOptions); + const toolMap = Object.fromEntries(providedTools.map((mcpTool) => [mcpTool.tool.name, mcpTool])); + + server.setRequestHandler(ListToolsRequestSchema, async () => { + return { + tools: providedTools.map((mcpTool) => mcpTool.tool), + }; + }); + + server.setRequestHandler(CallToolRequestSchema, async (request) => { + const { name, arguments: args } = request.params; + const mcpTool = toolMap[name]; + if (!mcpTool) { + throw new Error(`Unknown tool: ${name}`); + } + + let client: Umaaas; + try { + client = getClient(); + } catch (error) { + return { + content: [ + { + type: 'text' as const, + text: `Failed to initialize client: ${error instanceof Error ? error.message : String(error)}`, + }, + ], + isError: true, + }; + } + + return executeHandler({ + handler: mcpTool.handler, + reqContext: { + client, + stainlessApiKey: params.stainlessApiKey ?? params.mcpOptions?.stainlessApiKey, + upstreamClientEnvs: params.upstreamClientEnvs, + mcpSessionId: params.mcpSessionId, + mcpClientInfo: params.mcpClientInfo, + }, + args, + }); + }); + + server.setRequestHandler(SetLevelRequestSchema, async (request) => { + const { level } = request.params; + let logLevel: 'debug' | 'info' | 'warn' | 'error' | 'off'; + switch (level) { + case 'debug': + logLevel = 'debug'; + break; + case 'info': + logLevel = 'info'; + break; + case 'notice': + case 'warning': + logLevel = 'warn'; + break; + case 'error': + logLevel = 'error'; + break; + default: + logLevel = 'off'; + break; + } + _logLevel = logLevel; + if (_client) { + _client = _client.withOptions({ logLevel }); + } + return {}; + }); +} + +/** + * Selects the tools to include in the MCP Server based on the provided options. + */ +export function selectTools(options?: McpOptions): McpTool[] { + const includedTools = []; + + if (options?.includeCodeTool ?? true) { + includedTools.push( + codeTool({ + blockedMethods: blockedMethodsForCodeTool(options), + codeExecutionMode: options?.codeExecutionMode ?? 'stainless-sandbox', + }), + ); + } + if (options?.includeDocsTools ?? true) { + includedTools.push(docsSearchTool); + } + return includedTools; +} + +/** + * Runs the provided handler with the given client and arguments. + */ +export async function executeHandler({ + handler, + reqContext, + args, +}: { + handler: HandlerFunction; + reqContext: McpRequestContext; + args: Record | undefined; +}): Promise { + return await handler({ reqContext, args: args || {} }); +} diff --git a/mcp-server/src/stdio.ts b/mcp-server/src/stdio.ts new file mode 100644 index 00000000..b04a5441 --- /dev/null +++ b/mcp-server/src/stdio.ts @@ -0,0 +1,17 @@ +import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; +import { McpOptions } from './options'; +import { initMcpServer, newMcpServer } from './server'; +import { getLogger } from './logger'; + +export const launchStdioServer = async (mcpOptions: McpOptions) => { + const server = await newMcpServer({ + stainlessApiKey: mcpOptions.stainlessApiKey, + customInstructionsPath: mcpOptions.customInstructionsPath, + }); + + await initMcpServer({ server, mcpOptions, stainlessApiKey: mcpOptions.stainlessApiKey }); + + const transport = new StdioServerTransport(); + await server.connect(transport); + getLogger().info('MCP Server running on stdio'); +}; diff --git a/mcp-server/src/types.ts b/mcp-server/src/types.ts new file mode 100644 index 00000000..fe41a358 --- /dev/null +++ b/mcp-server/src/types.ts @@ -0,0 +1,126 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import Umaaas from 'umaaas'; +import { Tool } from '@modelcontextprotocol/sdk/types.js'; + +type TextContentBlock = { + type: 'text'; + text: string; +}; + +type ImageContentBlock = { + type: 'image'; + data: string; + mimeType: string; +}; + +type AudioContentBlock = { + type: 'audio'; + data: string; + mimeType: string; +}; + +type ResourceContentBlock = { + type: 'resource'; + resource: + | { + uri: string; + mimeType: string; + text: string; + } + | { + uri: string; + mimeType: string; + blob: string; + }; +}; + +export type ContentBlock = TextContentBlock | ImageContentBlock | AudioContentBlock | ResourceContentBlock; + +export type ToolCallResult = { + content: ContentBlock[]; + isError?: boolean; +}; + +export type McpRequestContext = { + client: Umaaas; + stainlessApiKey?: string | undefined; + upstreamClientEnvs?: Record | undefined; + mcpSessionId?: string | undefined; + mcpClientInfo?: { name: string; version: string } | undefined; +}; + +export type HandlerFunction = ({ + reqContext, + args, +}: { + reqContext: McpRequestContext; + args: Record | undefined; +}) => Promise; + +export function asTextContentResult(result: unknown): ToolCallResult { + return { + content: [ + { + type: 'text', + text: JSON.stringify(result, null, 2), + }, + ], + }; +} + +export async function asBinaryContentResult(response: Response): Promise { + const blob = await response.blob(); + const mimeType = blob.type; + const data = Buffer.from(await blob.arrayBuffer()).toString('base64'); + if (mimeType.startsWith('image/')) { + return { + content: [{ type: 'image', mimeType, data }], + }; + } else if (mimeType.startsWith('audio/')) { + return { + content: [{ type: 'audio', mimeType, data }], + }; + } else { + return { + content: [ + { + type: 'resource', + resource: { + // We must give a URI, even though this isn't actually an MCP resource. + uri: 'resource://tool-response', + mimeType, + blob: data, + }, + }, + ], + }; + } +} + +export function asErrorResult(message: string): ToolCallResult { + return { + content: [ + { + type: 'text', + text: message, + }, + ], + isError: true, + }; +} + +export type Metadata = { + resource: string; + operation: 'read' | 'write'; + tags: string[]; + httpMethod?: string; + httpPath?: string; + operationId?: string; +}; + +export type McpTool = { + metadata: Metadata; + tool: Tool; + handler: HandlerFunction; +}; diff --git a/mcp-server/src/util.ts b/mcp-server/src/util.ts new file mode 100644 index 00000000..069a2b47 --- /dev/null +++ b/mcp-server/src/util.ts @@ -0,0 +1,25 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +export const readEnv = (env: string): string | undefined => { + if (typeof (globalThis as any).process !== 'undefined') { + return (globalThis as any).process.env?.[env]?.trim() || undefined; + } else if (typeof (globalThis as any).Deno !== 'undefined') { + return (globalThis as any).Deno.env?.get?.(env)?.trim() || undefined; + } + return; +}; + +export const readEnvOrError = (env: string): string => { + let envValue = readEnv(env); + if (envValue === undefined) { + throw new Error(`Environment variable ${env} is not set`); + } + return envValue; +}; + +export const requireValue = (value: T | undefined, description: string): T => { + if (value === undefined) { + throw new Error(`Missing required value: ${description}`); + } + return value; +}; diff --git a/mcp-server/tests/options.test.ts b/mcp-server/tests/options.test.ts new file mode 100644 index 00000000..17306295 --- /dev/null +++ b/mcp-server/tests/options.test.ts @@ -0,0 +1,32 @@ +import { parseCLIOptions } from '../src/options'; + +// Mock process.argv +const mockArgv = (args: string[]) => { + const originalArgv = process.argv; + process.argv = ['node', 'test.js', ...args]; + return () => { + process.argv = originalArgv; + }; +}; + +describe('parseCLIOptions', () => { + it('default parsing should be stdio', () => { + const cleanup = mockArgv([]); + + const result = parseCLIOptions(); + + expect(result.transport).toBe('stdio'); + + cleanup(); + }); + + it('using http transport with a port', () => { + const cleanup = mockArgv(['--transport=http', '--port=2222']); + + const result = parseCLIOptions(); + + expect(result.transport).toBe('http'); + expect(result.port).toBe(2222); + cleanup(); + }); +}); diff --git a/mcp-server/tsc-multi.json b/mcp-server/tsc-multi.json new file mode 100644 index 00000000..4facad5a --- /dev/null +++ b/mcp-server/tsc-multi.json @@ -0,0 +1,7 @@ +{ + "targets": [ + { "extname": ".js", "module": "commonjs" }, + { "extname": ".mjs", "module": "esnext" } + ], + "projects": ["tsconfig.build.json"] +} diff --git a/mcp-server/tsconfig.build.json b/mcp-server/tsconfig.build.json new file mode 100644 index 00000000..5dae55e9 --- /dev/null +++ b/mcp-server/tsconfig.build.json @@ -0,0 +1,18 @@ +{ + "extends": "./tsconfig.json", + "include": ["dist/src"], + "exclude": [], + "compilerOptions": { + "rootDir": "./dist/src", + "paths": { + "umaaas_mcp/*": ["./dist/src/*"], + "umaaas_mcp": ["./dist/src/index.ts"] + }, + "noEmit": false, + "declaration": true, + "declarationMap": true, + "outDir": "dist", + "pretty": true, + "sourceMap": true + } +} diff --git a/mcp-server/tsconfig.dist-src.json b/mcp-server/tsconfig.dist-src.json new file mode 100644 index 00000000..e9f2d70b --- /dev/null +++ b/mcp-server/tsconfig.dist-src.json @@ -0,0 +1,11 @@ +{ + // this config is included in the published src directory to prevent TS errors + // from appearing when users go to source, and VSCode opens the source .ts file + // via declaration maps + "include": ["index.ts"], + "compilerOptions": { + "target": "es2015", + "lib": ["DOM"], + "moduleResolution": "node" + } +} diff --git a/mcp-server/tsconfig.json b/mcp-server/tsconfig.json new file mode 100644 index 00000000..725af2f9 --- /dev/null +++ b/mcp-server/tsconfig.json @@ -0,0 +1,36 @@ +{ + "include": ["src", "tests", "examples"], + "exclude": [], + "compilerOptions": { + "target": "es2022", + "lib": ["es2022"], + "module": "commonjs", + "moduleResolution": "node", + "esModuleInterop": true, + "paths": { + "umaaas_mcp/*": ["./src/*"], + "umaaas_mcp": ["./src/index.ts"] + }, + "noEmit": true, + + "resolveJsonModule": true, + + "forceConsistentCasingInFileNames": true, + + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "strictBindCallApply": true, + "strictPropertyInitialization": true, + "noImplicitThis": true, + "noImplicitReturns": true, + "alwaysStrict": true, + "exactOptionalPropertyTypes": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + + "skipLibCheck": true + } +} diff --git a/mcp-server/umaaas_api.mcpb b/mcp-server/umaaas_api.mcpb new file mode 100644 index 00000000..bd7314ae Binary files /dev/null and b/mcp-server/umaaas_api.mcpb differ diff --git a/mcp-server/yarn.lock b/mcp-server/yarn.lock new file mode 100644 index 00000000..c7e37692 --- /dev/null +++ b/mcp-server/yarn.lock @@ -0,0 +1,4169 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@anthropic-ai/mcpb@^2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@anthropic-ai/mcpb/-/mcpb-2.1.2.tgz#cf02801929734b8810961f22e2eb72758c27d527" + integrity sha512-goRbBC8ySo7SWb7tRzr+tL6FxDc4JPTRCdgfD2omba7freofvjq5rom1lBnYHZHo6Mizs1jAHJeN53aZbDoy8A== + dependencies: + "@inquirer/prompts" "^6.0.1" + commander "^13.1.0" + fflate "^0.8.2" + galactus "^1.0.0" + ignore "^7.0.5" + node-forge "^1.3.2" + pretty-bytes "^5.6.0" + zod "^3.25.67" + zod-to-json-schema "^3.24.6" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.28.6.tgz#72499312ec58b1e2245ba4a4f550c132be4982f7" + integrity sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q== + dependencies: + "@babel/helper-validator-identifier" "^7.28.5" + js-tokens "^4.0.0" + picocolors "^1.1.1" + +"@babel/compat-data@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.6.tgz#103f466803fa0f059e82ccac271475470570d74c" + integrity sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg== + +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.6.tgz#531bf883a1126e53501ba46eb3bb414047af507f" + integrity sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw== + dependencies: + "@babel/code-frame" "^7.28.6" + "@babel/generator" "^7.28.6" + "@babel/helper-compilation-targets" "^7.28.6" + "@babel/helper-module-transforms" "^7.28.6" + "@babel/helpers" "^7.28.6" + "@babel/parser" "^7.28.6" + "@babel/template" "^7.28.6" + "@babel/traverse" "^7.28.6" + "@babel/types" "^7.28.6" + "@jridgewell/remapping" "^2.3.5" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.28.6", "@babel/generator@^7.7.2": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.6.tgz#48dcc65d98fcc8626a48f72b62e263d25fc3c3f1" + integrity sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw== + dependencies: + "@babel/parser" "^7.28.6" + "@babel/types" "^7.28.6" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" + jsesc "^3.0.2" + +"@babel/helper-compilation-targets@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz#32c4a3f41f12ed1532179b108a4d746e105c2b25" + integrity sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA== + dependencies: + "@babel/compat-data" "^7.28.6" + "@babel/helper-validator-option" "^7.27.1" + browserslist "^4.24.0" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-globals@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz#b9430df2aa4e17bc28665eadeae8aa1d985e6674" + integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== + +"@babel/helper-module-imports@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz#60632cbd6ffb70b22823187201116762a03e2d5c" + integrity sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw== + dependencies: + "@babel/traverse" "^7.28.6" + "@babel/types" "^7.28.6" + +"@babel/helper-module-transforms@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz#9312d9d9e56edc35aeb6e95c25d4106b50b9eb1e" + integrity sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA== + dependencies: + "@babel/helper-module-imports" "^7.28.6" + "@babel/helper-validator-identifier" "^7.28.5" + "@babel/traverse" "^7.28.6" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.28.6", "@babel/helper-plugin-utils@^7.8.0": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz#6f13ea251b68c8532e985fd532f28741a8af9ac8" + integrity sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug== + +"@babel/helper-string-parser@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" + integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== + +"@babel/helper-validator-identifier@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4" + integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q== + +"@babel/helper-validator-option@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f" + integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== + +"@babel/helpers@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.6.tgz#fca903a313ae675617936e8998b814c415cbf5d7" + integrity sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw== + dependencies: + "@babel/template" "^7.28.6" + "@babel/types" "^7.28.6" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.6.tgz#f01a8885b7fa1e56dd8a155130226cd698ef13fd" + integrity sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ== + dependencies: + "@babel/types" "^7.28.6" + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-import-attributes@^7.24.7": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz#b71d5914665f60124e133696f17cd7669062c503" + integrity sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-syntax-import-meta@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.7.2": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz#f8ca28bbd84883b5fea0e447c635b81ba73997ee" + integrity sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-top-level-await@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz#c7b2ddf1d0a811145b1de800d1abd146af92e3a2" + integrity sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/template@^7.28.6", "@babel/template@^7.3.3": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.28.6.tgz#0e7e56ecedb78aeef66ce7972b082fce76a23e57" + integrity sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ== + dependencies: + "@babel/code-frame" "^7.28.6" + "@babel/parser" "^7.28.6" + "@babel/types" "^7.28.6" + +"@babel/traverse@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.6.tgz#871ddc79a80599a5030c53b1cc48cbe3a5583c2e" + integrity sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg== + dependencies: + "@babel/code-frame" "^7.28.6" + "@babel/generator" "^7.28.6" + "@babel/helper-globals" "^7.28.0" + "@babel/parser" "^7.28.6" + "@babel/template" "^7.28.6" + "@babel/types" "^7.28.6" + debug "^4.3.1" + +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.28.2", "@babel/types@^7.28.6", "@babel/types@^7.3.3": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.6.tgz#c3e9377f1b155005bcc4c46020e7e394e13089df" + integrity sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + +"@cloudflare/cabidela@^0.2.4": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@cloudflare/cabidela/-/cabidela-0.2.4.tgz#9a3e9212e636a24d796a8f16741c24885b326a1a" + integrity sha512-u/1OwwqfcMvjmUFOcb6QtFzVVGpncHJxwl254wjzp0JC5CUlBkV6r5BbRrHI5ZYJEAgu8NeeorirxngmMFPZjQ== + +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + +"@eslint-community/eslint-utils@^4.4.0", "@eslint-community/eslint-utils@^4.8.0": + version "4.9.1" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz#4e90af67bc51ddee6cdef5284edf572ec376b595" + integrity sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ== + dependencies: + eslint-visitor-keys "^3.4.3" + +"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.12.1": + version "4.12.2" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz#bccdf615bcf7b6e8db830ec0b8d21c9a25de597b" + integrity sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew== + +"@eslint/config-array@^0.21.2": + version "0.21.2" + resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.21.2.tgz#f29e22057ad5316cf23836cee9a34c81fffcb7e6" + integrity sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw== + dependencies: + "@eslint/object-schema" "^2.1.7" + debug "^4.3.1" + minimatch "^3.1.5" + +"@eslint/config-helpers@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.4.2.tgz#1bd006ceeb7e2e55b2b773ab318d300e1a66aeda" + integrity sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw== + dependencies: + "@eslint/core" "^0.17.0" + +"@eslint/core@^0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.17.0.tgz#77225820413d9617509da9342190a2019e78761c" + integrity sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ== + dependencies: + "@types/json-schema" "^7.0.15" + +"@eslint/eslintrc@^3.3.5": + version "3.3.5" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.3.5.tgz#c131793cfc1a7b96f24a83e0a8bbd4b881558c60" + integrity sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg== + dependencies: + ajv "^6.14.0" + debug "^4.3.2" + espree "^10.0.1" + globals "^14.0.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.1" + minimatch "^3.1.5" + strip-json-comments "^3.1.1" + +"@eslint/js@9.39.4": + version "9.39.4" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.39.4.tgz#a3f83bfc6fd9bf33a853dfacd0b49b398eb596c1" + integrity sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw== + +"@eslint/object-schema@^2.1.7": + version "2.1.7" + resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.7.tgz#6e2126a1347e86a4dedf8706ec67ff8e107ebbad" + integrity sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA== + +"@eslint/plugin-kit@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz#9779e3fd9b7ee33571a57435cf4335a1794a6cb2" + integrity sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA== + dependencies: + "@eslint/core" "^0.17.0" + levn "^0.4.1" + +"@hono/node-server@^1.19.10", "@hono/node-server@^1.19.9": + version "1.19.11" + resolved "https://registry.yarnpkg.com/@hono/node-server/-/node-server-1.19.11.tgz#dc419f0826dd2504e9fc86ad289d5636a0444e2f" + integrity sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g== + +"@humanfs/core@^0.19.1": + version "0.19.1" + resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77" + integrity sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA== + +"@humanfs/node@^0.16.6": + version "0.16.7" + resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.7.tgz#822cb7b3a12c5a240a24f621b5a2413e27a45f26" + integrity sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ== + dependencies: + "@humanfs/core" "^0.19.1" + "@humanwhocodes/retry" "^0.4.0" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/retry@^0.4.0", "@humanwhocodes/retry@^0.4.2": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.3.tgz#c2b9d2e374ee62c586d3adbea87199b1d7a7a6ba" + integrity sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ== + +"@inquirer/checkbox@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@inquirer/checkbox/-/checkbox-3.0.1.tgz#0a57f704265f78c36e17f07e421b98efb4b9867b" + integrity sha512-0hm2nrToWUdD6/UHnel/UKGdk1//ke5zGUpHIvk5ZWmaKezlGxZkOJXNSWsdxO/rEqTkbB3lNC2J6nBElV2aAQ== + dependencies: + "@inquirer/core" "^9.2.1" + "@inquirer/figures" "^1.0.6" + "@inquirer/type" "^2.0.0" + ansi-escapes "^4.3.2" + yoctocolors-cjs "^2.1.2" + +"@inquirer/confirm@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-4.0.1.tgz#9106d6bffa0b2fdd0e4f60319b6f04f2e06e6e25" + integrity sha512-46yL28o2NJ9doViqOy0VDcoTzng7rAb6yPQKU7VDLqkmbCaH4JqK4yk4XqlzNWy9PVC5pG1ZUXPBQv+VqnYs2w== + dependencies: + "@inquirer/core" "^9.2.1" + "@inquirer/type" "^2.0.0" + +"@inquirer/core@^9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-9.2.1.tgz#677c49dee399c9063f31e0c93f0f37bddc67add1" + integrity sha512-F2VBt7W/mwqEU4bL0RnHNZmC/OxzNx9cOYxHqnXX3MP6ruYvZUZAW9imgN9+h/uBT/oP8Gh888J2OZSbjSeWcg== + dependencies: + "@inquirer/figures" "^1.0.6" + "@inquirer/type" "^2.0.0" + "@types/mute-stream" "^0.0.4" + "@types/node" "^22.5.5" + "@types/wrap-ansi" "^3.0.0" + ansi-escapes "^4.3.2" + cli-width "^4.1.0" + mute-stream "^1.0.0" + signal-exit "^4.1.0" + strip-ansi "^6.0.1" + wrap-ansi "^6.2.0" + yoctocolors-cjs "^2.1.2" + +"@inquirer/editor@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@inquirer/editor/-/editor-3.0.1.tgz#d109f21e050af6b960725388cb1c04214ed7c7bc" + integrity sha512-VA96GPFaSOVudjKFraokEEmUQg/Lub6OXvbIEZU1SDCmBzRkHGhxoFAVaF30nyiB4m5cEbDgiI2QRacXZ2hw9Q== + dependencies: + "@inquirer/core" "^9.2.1" + "@inquirer/type" "^2.0.0" + external-editor "^3.1.0" + +"@inquirer/expand@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@inquirer/expand/-/expand-3.0.1.tgz#aed9183cac4d12811be47a4a895ea8e82a17e22c" + integrity sha512-ToG8d6RIbnVpbdPdiN7BCxZGiHOTomOX94C2FaT5KOHupV40tKEDozp12res6cMIfRKrXLJyexAZhWVHgbALSQ== + dependencies: + "@inquirer/core" "^9.2.1" + "@inquirer/type" "^2.0.0" + yoctocolors-cjs "^2.1.2" + +"@inquirer/figures@^1.0.6": + version "1.0.15" + resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.15.tgz#dbb49ed80df11df74268023b496ac5d9acd22b3a" + integrity sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g== + +"@inquirer/input@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@inquirer/input/-/input-3.0.1.tgz#de63d49e516487388508d42049deb70f2cb5f28e" + integrity sha512-BDuPBmpvi8eMCxqC5iacloWqv+5tQSJlUafYWUe31ow1BVXjW2a5qe3dh4X/Z25Wp22RwvcaLCc2siHobEOfzg== + dependencies: + "@inquirer/core" "^9.2.1" + "@inquirer/type" "^2.0.0" + +"@inquirer/number@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@inquirer/number/-/number-2.0.1.tgz#b9863080d02ab7dc2e56e16433d83abea0f2a980" + integrity sha512-QpR8jPhRjSmlr/mD2cw3IR8HRO7lSVOnqUvQa8scv1Lsr3xoAMMworcYW3J13z3ppjBFBD2ef1Ci6AE5Qn8goQ== + dependencies: + "@inquirer/core" "^9.2.1" + "@inquirer/type" "^2.0.0" + +"@inquirer/password@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@inquirer/password/-/password-3.0.1.tgz#2a9a9143591088336bbd573bcb05d5bf080dbf87" + integrity sha512-haoeEPUisD1NeE2IanLOiFr4wcTXGWrBOyAyPZi1FfLJuXOzNmxCJPgUrGYKVh+Y8hfGJenIfz5Wb/DkE9KkMQ== + dependencies: + "@inquirer/core" "^9.2.1" + "@inquirer/type" "^2.0.0" + ansi-escapes "^4.3.2" + +"@inquirer/prompts@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@inquirer/prompts/-/prompts-6.0.1.tgz#43f5c0ed35c5ebfe52f1d43d46da2d363d950071" + integrity sha512-yl43JD/86CIj3Mz5mvvLJqAOfIup7ncxfJ0Btnl0/v5TouVUyeEdcpknfgc+yMevS/48oH9WAkkw93m7otLb/A== + dependencies: + "@inquirer/checkbox" "^3.0.1" + "@inquirer/confirm" "^4.0.1" + "@inquirer/editor" "^3.0.1" + "@inquirer/expand" "^3.0.1" + "@inquirer/input" "^3.0.1" + "@inquirer/number" "^2.0.1" + "@inquirer/password" "^3.0.1" + "@inquirer/rawlist" "^3.0.1" + "@inquirer/search" "^2.0.1" + "@inquirer/select" "^3.0.1" + +"@inquirer/rawlist@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@inquirer/rawlist/-/rawlist-3.0.1.tgz#729def358419cc929045f264131878ed379e0af3" + integrity sha512-VgRtFIwZInUzTiPLSfDXK5jLrnpkuSOh1ctfaoygKAdPqjcjKYmGh6sCY1pb0aGnCGsmhUxoqLDUAU0ud+lGXQ== + dependencies: + "@inquirer/core" "^9.2.1" + "@inquirer/type" "^2.0.0" + yoctocolors-cjs "^2.1.2" + +"@inquirer/search@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@inquirer/search/-/search-2.0.1.tgz#69b774a0a826de2e27b48981d01bc5ad81e73721" + integrity sha512-r5hBKZk3g5MkIzLVoSgE4evypGqtOannnB3PKTG9NRZxyFRKcfzrdxXXPcoJQsxJPzvdSU2Rn7pB7lw0GCmGAg== + dependencies: + "@inquirer/core" "^9.2.1" + "@inquirer/figures" "^1.0.6" + "@inquirer/type" "^2.0.0" + yoctocolors-cjs "^2.1.2" + +"@inquirer/select@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@inquirer/select/-/select-3.0.1.tgz#1df9ed27fb85a5f526d559ac5ce7cc4e9dc4e7ec" + integrity sha512-lUDGUxPhdWMkN/fHy1Lk7pF3nK1fh/gqeyWXmctefhxLYxlDsc7vsPBEpxrfVGDsVdyYJsiJoD4bJ1b623cV1Q== + dependencies: + "@inquirer/core" "^9.2.1" + "@inquirer/figures" "^1.0.6" + "@inquirer/type" "^2.0.0" + ansi-escapes "^4.3.2" + yoctocolors-cjs "^2.1.2" + +"@inquirer/type@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-2.0.0.tgz#08fa513dca2cb6264fe1b0a2fabade051444e3f6" + integrity sha512-XvJRx+2KR3YXyYtPUUy+qd9i7p+GO9Ko6VIIpWlBrpWwXDv8WLFeHTxz35CfQFUiBMLXlGHhGzys7lqit9gWag== + dependencies: + mute-stream "^1.0.0" + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc" + integrity sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + slash "^3.0.0" + +"@jest/core@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f" + integrity sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg== + dependencies: + "@jest/console" "^29.7.0" + "@jest/reporters" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + ci-info "^3.2.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^29.7.0" + jest-config "^29.7.0" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-resolve-dependencies "^29.7.0" + jest-runner "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + jest-watcher "^29.7.0" + micromatch "^4.0.4" + pretty-format "^29.7.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" + integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw== + dependencies: + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + jest-mock "^29.7.0" + +"@jest/expect-utils@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" + integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== + dependencies: + jest-get-type "^29.6.3" + +"@jest/expect@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.7.0.tgz#76a3edb0cb753b70dfbfe23283510d3d45432bf2" + integrity sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ== + dependencies: + expect "^29.7.0" + jest-snapshot "^29.7.0" + +"@jest/fake-timers@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565" + integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== + dependencies: + "@jest/types" "^29.6.3" + "@sinonjs/fake-timers" "^10.0.2" + "@types/node" "*" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-util "^29.7.0" + +"@jest/globals@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d" + integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" + "@jest/types" "^29.6.3" + jest-mock "^29.7.0" + +"@jest/reporters@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7" + integrity sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@jridgewell/trace-mapping" "^0.3.18" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^6.0.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + jest-worker "^29.7.0" + slash "^3.0.0" + string-length "^4.0.1" + strip-ansi "^6.0.0" + v8-to-istanbul "^9.0.1" + +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== + dependencies: + "@sinclair/typebox" "^0.27.8" + +"@jest/source-map@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.3.tgz#d90ba772095cf37a34a5eb9413f1b562a08554c4" + integrity sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw== + dependencies: + "@jridgewell/trace-mapping" "^0.3.18" + callsites "^3.0.0" + graceful-fs "^4.2.9" + +"@jest/test-result@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.7.0.tgz#8db9a80aa1a097bb2262572686734baed9b1657c" + integrity sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA== + dependencies: + "@jest/console" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz#6cef977ce1d39834a3aea887a1726628a6f072ce" + integrity sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw== + dependencies: + "@jest/test-result" "^29.7.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + slash "^3.0.0" + +"@jest/transform@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c" + integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^29.6.3" + "@jridgewell/trace-mapping" "^0.3.18" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^2.0.0" + fast-json-stable-stringify "^2.1.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-regex-util "^29.6.3" + jest-util "^29.7.0" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.2" + +"@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== + dependencies: + "@jest/schemas" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.3.12", "@jridgewell/gen-mapping@^0.3.5": + version "0.3.13" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f" + integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/remapping@^2.3.5": + version "2.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/remapping/-/remapping-2.3.5.tgz#375c476d1972947851ba1e15ae8f123047445aa1" + integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" + integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== + +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.28": + version "0.3.31" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0" + integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@modelcontextprotocol/sdk@^1.27.1": + version "1.27.1" + resolved "https://registry.yarnpkg.com/@modelcontextprotocol/sdk/-/sdk-1.27.1.tgz#a602cf823bf8a68e13e7112f50aeb02b09fb83b9" + integrity sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA== + dependencies: + "@hono/node-server" "^1.19.9" + ajv "^8.17.1" + ajv-formats "^3.0.1" + content-type "^1.0.5" + cors "^2.8.5" + cross-spawn "^7.0.5" + eventsource "^3.0.2" + eventsource-parser "^3.0.0" + express "^5.2.1" + express-rate-limit "^8.2.1" + hono "^4.11.4" + jose "^6.1.3" + json-schema-typed "^8.0.2" + pkce-challenge "^5.0.0" + raw-body "^3.0.0" + zod "^3.25 || ^4.0" + zod-to-json-schema "^3.25.1" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@pinojs/redact@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@pinojs/redact/-/redact-0.4.0.tgz#c3de060dd12640dcc838516aa2a6803cc7b2e9d6" + integrity sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg== + +"@pkgr/core@^0.2.9": + version "0.2.9" + resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.2.9.tgz#d229a7b7f9dac167a156992ef23c7f023653f53b" + integrity sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA== + +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== + +"@sinonjs/commons@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd" + integrity sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^10.0.2": + version "10.3.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66" + integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== + dependencies: + "@sinonjs/commons" "^3.0.0" + +"@ts-morph/common@~0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.20.0.tgz#3f161996b085ba4519731e4d24c35f6cba5b80af" + integrity sha512-7uKjByfbPpwuzkstL3L5MQyuXPSKdoNG93Fmi2JoDcTf3pEP731JdRFAduRVkOs8oqxPsXKA+ScrWkdQ8t/I+Q== + dependencies: + fast-glob "^3.2.12" + minimatch "^7.4.3" + mkdirp "^2.1.6" + path-browserify "^1.0.1" + +"@tsconfig/node10@^1.0.7": + version "1.0.12" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.12.tgz#be57ceac1e4692b41be9de6be8c32a106636dba4" + integrity sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + +"@types/babel__core@^7.1.14": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== + dependencies: + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.27.0" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.27.0.tgz#b5819294c51179957afaec341442f9341e4108a9" + integrity sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.28.0.tgz#07d713d6cce0d265c9849db0cbe62d3f61f36f74" + integrity sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q== + dependencies: + "@babel/types" "^7.28.2" + +"@types/body-parser@*": + version "1.19.6" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.6.tgz#1859bebb8fd7dac9918a45d54c1971ab8b5af474" + integrity sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.38" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== + dependencies: + "@types/node" "*" + +"@types/cookie-parser@^1.4.10": + version "1.4.10" + resolved "https://registry.yarnpkg.com/@types/cookie-parser/-/cookie-parser-1.4.10.tgz#a045272a383a30597a01955d4f9c790018f214e4" + integrity sha512-B4xqkqfZ8Wek+rCOeRxsjMS9OgvzebEzzLYw7NHYuvzb7IdxOkI0ZHGgeEBX4PUM7QGVvNSK60T3OvWj3YfBRg== + +"@types/cors@^2.8.19": + version "2.8.19" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.19.tgz#d93ea2673fd8c9f697367f5eeefc2bbfa94f0342" + integrity sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg== + dependencies: + "@types/node" "*" + +"@types/estree@^1.0.6": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" + integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== + +"@types/express-serve-static-core@^5.0.0": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-5.1.1.tgz#1a77faffee9572d39124933259be2523837d7eaa" + integrity sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/express@^5.0.3": + version "5.0.6" + resolved "https://registry.yarnpkg.com/@types/express/-/express-5.0.6.tgz#2d724b2c990dcb8c8444063f3580a903f6d500cc" + integrity sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^5.0.0" + "@types/serve-static" "^2" + +"@types/graceful-fs@^4.1.3": + version "4.1.9" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" + integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== + dependencies: + "@types/node" "*" + +"@types/http-errors@*": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.5.tgz#5b749ab2b16ba113423feb1a64a95dcd30398472" + integrity sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg== + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" + integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== + +"@types/istanbul-lib-report@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" + integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" + integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@^29.4.0": + version "29.5.14" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.14.tgz#2b910912fa1d6856cadcd0c1f95af7df1d6049e5" + integrity sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ== + dependencies: + expect "^29.0.0" + pretty-format "^29.0.0" + +"@types/json-schema@^7.0.15": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + +"@types/mute-stream@^0.0.4": + version "0.0.4" + resolved "https://registry.yarnpkg.com/@types/mute-stream/-/mute-stream-0.0.4.tgz#77208e56a08767af6c5e1237be8888e2f255c478" + integrity sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow== + dependencies: + "@types/node" "*" + +"@types/node@*": + version "25.0.8" + resolved "https://registry.yarnpkg.com/@types/node/-/node-25.0.8.tgz#e54e00f94fe1db2497b3e42d292b8376a2678c8d" + integrity sha512-powIePYMmC3ibL0UJ2i2s0WIbq6cg6UyVFQxSCpaPxxzAaziRfimGivjdF943sSGV6RADVbk0Nvlm5P/FB44Zg== + dependencies: + undici-types "~7.16.0" + +"@types/node@^22.5.5": + version "22.19.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.19.6.tgz#0e9d80ebcd2dfce03265768c17a1212d4eb07e82" + integrity sha512-qm+G8HuG6hOHQigsi7VGuLjUVu6TtBo/F05zvX04Mw2uCg9Dv0Qxy3Qw7j41SidlTcl5D/5yg0SEZqOB+EqZnQ== + dependencies: + undici-types "~6.21.0" + +"@types/qs@*", "@types/qs@^6.14.0": + version "6.14.0" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.14.0.tgz#d8b60cecf62f2db0fb68e5e006077b9178b85de5" + integrity sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ== + +"@types/range-parser@*": + version "1.2.7" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" + integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== + +"@types/send@*": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@types/send/-/send-1.2.1.tgz#6a784e45543c18c774c049bff6d3dbaf045c9c74" + integrity sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ== + dependencies: + "@types/node" "*" + +"@types/serve-static@^2": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-2.2.0.tgz#d4a447503ead0d1671132d1ab6bd58b805d8de6a" + integrity sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ== + dependencies: + "@types/http-errors" "*" + "@types/node" "*" + +"@types/stack-utils@^2.0.0": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" + integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== + +"@types/wrap-ansi@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz#18b97a972f94f60a679fd5c796d96421b9abb9fd" + integrity sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g== + +"@types/yargs-parser@*": + version "21.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" + integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== + +"@types/yargs@^17.0.8": + version "17.0.35" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.35.tgz#07013e46aa4d7d7d50a49e15604c1c5340d4eb24" + integrity sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg== + dependencies: + "@types/yargs-parser" "*" + +"@typescript-eslint/eslint-plugin@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.31.1.tgz#62f1befe59647524994e89de4516d8dcba7a850a" + integrity sha512-oUlH4h1ABavI4F0Xnl8/fOtML/eu8nI2A1nYd+f+55XI0BLu+RIqKoCiZKNo6DtqZBEQm5aNKA20G3Z5w3R6GQ== + dependencies: + "@eslint-community/regexpp" "^4.10.0" + "@typescript-eslint/scope-manager" "8.31.1" + "@typescript-eslint/type-utils" "8.31.1" + "@typescript-eslint/utils" "8.31.1" + "@typescript-eslint/visitor-keys" "8.31.1" + graphemer "^1.4.0" + ignore "^5.3.1" + natural-compare "^1.4.0" + ts-api-utils "^2.0.1" + +"@typescript-eslint/parser@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.31.1.tgz#e9b0ccf30d37dde724ee4d15f4dbc195995cce1b" + integrity sha512-oU/OtYVydhXnumd0BobL9rkJg7wFJ9bFFPmSmB/bf/XWN85hlViji59ko6bSKBXyseT9V8l+CN1nwmlbiN0G7Q== + dependencies: + "@typescript-eslint/scope-manager" "8.31.1" + "@typescript-eslint/types" "8.31.1" + "@typescript-eslint/typescript-estree" "8.31.1" + "@typescript-eslint/visitor-keys" "8.31.1" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.31.1.tgz#1eb52e76878f545e4add142e0d8e3e97e7aa443b" + integrity sha512-BMNLOElPxrtNQMIsFHE+3P0Yf1z0dJqV9zLdDxN/xLlWMlXK/ApEsVEKzpizg9oal8bAT5Sc7+ocal7AC1HCVw== + dependencies: + "@typescript-eslint/types" "8.31.1" + "@typescript-eslint/visitor-keys" "8.31.1" + +"@typescript-eslint/type-utils@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.31.1.tgz#be0f438fb24b03568e282a0aed85f776409f970c" + integrity sha512-fNaT/m9n0+dpSp8G/iOQ05GoHYXbxw81x+yvr7TArTuZuCA6VVKbqWYVZrV5dVagpDTtj/O8k5HBEE/p/HM5LA== + dependencies: + "@typescript-eslint/typescript-estree" "8.31.1" + "@typescript-eslint/utils" "8.31.1" + debug "^4.3.4" + ts-api-utils "^2.0.1" + +"@typescript-eslint/types@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.31.1.tgz#478ed6f7e8aee1be7b63a60212b6bffe1423b5d4" + integrity sha512-SfepaEFUDQYRoA70DD9GtytljBePSj17qPxFHA/h3eg6lPTqGJ5mWOtbXCk1YrVU1cTJRd14nhaXWFu0l2troQ== + +"@typescript-eslint/typescript-estree@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.31.1.tgz#37792fe7ef4d3021c7580067c8f1ae66daabacdf" + integrity sha512-kaA0ueLe2v7KunYOyWYtlf/QhhZb7+qh4Yw6Ni5kgukMIG+iP773tjgBiLWIXYumWCwEq3nLW+TUywEp8uEeag== + dependencies: + "@typescript-eslint/types" "8.31.1" + "@typescript-eslint/visitor-keys" "8.31.1" + debug "^4.3.4" + fast-glob "^3.3.2" + is-glob "^4.0.3" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^2.0.1" + +"@typescript-eslint/utils@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.31.1.tgz#5628ea0393598a0b2f143d0fc6d019f0dee9dd14" + integrity sha512-2DSI4SNfF5T4oRveQ4nUrSjUqjMND0nLq9rEkz0gfGr3tg0S5KB6DhwR+WZPCjzkZl3cH+4x2ce3EsL50FubjQ== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@typescript-eslint/scope-manager" "8.31.1" + "@typescript-eslint/types" "8.31.1" + "@typescript-eslint/typescript-estree" "8.31.1" + +"@typescript-eslint/visitor-keys@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.31.1.tgz#6742b0e3ba1e0c1e35bdaf78c03e759eb8dd8e75" + integrity sha512-I+/rgqOVBn6f0o7NDTmAPWWC6NuqhV174lfYvAm9fUaWeiefLdux9/YI3/nLugEn9L8fcSi0XmpKi/r5u0nmpw== + dependencies: + "@typescript-eslint/types" "8.31.1" + eslint-visitor-keys "^4.2.0" + +"@valtown/deno-http-worker@^0.0.21": + version "0.0.21" + resolved "https://registry.yarnpkg.com/@valtown/deno-http-worker/-/deno-http-worker-0.0.21.tgz#9ce3b5c1d0db211fe7ea8297881fe551838474ad" + integrity sha512-16kFuUykann75lNytnXXIQlmpzreZjzdyT27ebT3yNGCS3kKaS1iZYWHc3Si9An54Cphwr4qEcviChQkEeJBlA== + +accepts@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-2.0.0.tgz#bbcf4ba5075467f3f2131eab3cffc73c2f5d7895" + integrity sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng== + dependencies: + mime-types "^3.0.0" + negotiator "^1.0.0" + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn-walk@^8.1.1: + version "8.3.4" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.4.tgz#794dd169c3977edf4ba4ea47583587c5866236b7" + integrity sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g== + dependencies: + acorn "^8.11.0" + +acorn@^8.11.0, acorn@^8.4.1: + version "8.15.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" + integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== + +acorn@^8.15.0: + version "8.16.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.16.0.tgz#4ce79c89be40afe7afe8f3adb902a1f1ce9ac08a" + integrity sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw== + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv-formats@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-3.0.1.tgz#3d5dc762bca17679c3c2ea7e90ad6b7532309578" + integrity sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ== + dependencies: + ajv "^8.0.0" + +ajv@^6.14.0: + version "6.14.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.14.0.tgz#fd067713e228210636ebb08c60bd3765d6dbe73a" + integrity sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.0, ajv@^8.17.1: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" + integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== + dependencies: + fast-deep-equal "^3.1.3" + fast-uri "^3.0.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + +ajv@^8.18.0: + version "8.18.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.18.0.tgz#8864186b6738d003eb3a933172bb3833e10cefbc" + integrity sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A== + dependencies: + fast-deep-equal "^3.1.3" + fast-uri "^3.0.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + +ansi-escapes@^4.2.1, ansi-escapes@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +anymatch@^3.0.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +atomic-sleep@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" + integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== + +babel-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" + integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== + dependencies: + "@jest/transform" "^29.7.0" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^29.6.3" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz#aadbe943464182a8922c3c927c3067ff40d24626" + integrity sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" + +babel-preset-current-node-syntax@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz#20730d6cdc7dda5d89401cab10ac6a32067acde6" + integrity sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-import-attributes" "^7.24.7" + "@babel/plugin-syntax-import-meta" "^7.10.4" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + +babel-preset-jest@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c" + integrity sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA== + dependencies: + babel-plugin-jest-hoist "^29.6.3" + babel-preset-current-node-syntax "^1.0.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +baseline-browser-mapping@^2.9.0: + version "2.9.14" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.14.tgz#3b6af0bc032445bca04de58caa9a87cfe921cbb3" + integrity sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg== + +body-parser@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-2.2.2.tgz#1a32cdb966beaf68de50a9dfbe5b58f83cb8890c" + integrity sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA== + dependencies: + bytes "^3.1.2" + content-type "^1.0.5" + debug "^4.4.3" + http-errors "^2.0.0" + iconv-lite "^0.7.0" + on-finished "^2.4.1" + qs "^6.14.1" + raw-body "^3.0.1" + type-is "^2.0.1" + +brace-expansion@^1.1.7: + version "1.1.12" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.12.tgz#ab9b454466e5a8cc3a187beaad580412a9c5b843" + integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.2.tgz#54fc53237a613d854c7bd37463aad17df87214e7" + integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + +browserslist@^4.24.0: + version "4.28.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.1.tgz#7f534594628c53c63101079e27e40de490456a95" + integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== + dependencies: + baseline-browser-mapping "^2.9.0" + caniuse-lite "^1.0.30001759" + electron-to-chromium "^1.5.263" + node-releases "^2.0.27" + update-browserslist-db "^1.2.0" + +bs-logger@^0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +bytes@^3.1.2, bytes@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" + integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + +call-bound@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a" + integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== + dependencies: + call-bind-apply-helpers "^1.0.2" + get-intrinsic "^1.3.0" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001759: + version "1.0.30001764" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001764.tgz#03206c56469f236103b90f9ae10bcb8b9e1f6005" + integrity sha512-9JGuzl2M+vPL+pz70gtMF9sHdMFbY9FJaQBi186cHKH3pSzDvzoUJUPV6fqiKIMyXbud9ZLg4F3Yza1vJ1+93g== + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +ci-info@^3.2.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== + +cjs-module-lexer@^1.0.0: + version "1.4.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz#0f79731eb8cfe1ec72acd4066efac9d61991b00d" + integrity sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q== + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-width@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5" + integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ== + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + 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" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== + +code-block-writer@^12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-12.0.0.tgz#4dd58946eb4234105aff7f0035977b2afdc2a770" + integrity sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w== + +collect-v8-coverage@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz#cc1f01eb8d02298cbc9a437c74c70ab4e5210b80" + integrity sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw== + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colorette@^2.0.7: + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + +commander@^13.1.0: + version "13.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-13.1.0.tgz#776167db68c78f38dcce1f9b8d7b8b9a488abf46" + integrity sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +content-disposition@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-1.0.1.tgz#a8b7bbeb2904befdfb6787e5c0c086959f605f9b" + integrity sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q== + +content-type@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +cookie-parser@^1.4.6: + version "1.4.7" + resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.7.tgz#e2125635dfd766888ffe90d60c286404fa0e7b26" + integrity sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw== + dependencies: + cookie "0.7.2" + cookie-signature "1.0.6" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie-signature@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.2.2.tgz#57c7fc3cc293acab9fec54d73e15690ebe4a1793" + integrity sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg== + +cookie@0.7.2, cookie@^0.7.1: + version "0.7.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" + integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== + +cors@^2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +create-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320" + integrity sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q== + dependencies: + "@jest/types" "^29.6.3" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-config "^29.7.0" + jest-util "^29.7.0" + prompts "^2.0.1" + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-spawn@^7.0.3, cross-spawn@^7.0.5, cross-spawn@^7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +dateformat@^4.6.3: + version "4.6.3" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.6.3.tgz#556fa6497e5217fedb78821424f8a1c22fa3f4b5" + integrity sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA== + +debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.7, debug@^4.4.0, debug@^4.4.3: + version "4.4.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + +dedent@^1.0.0: + version "1.7.1" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.7.1.tgz#364661eea3d73f3faba7089214420ec2f8f13e15" + integrity sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg== + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + +depd@^2.0.0, depd@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +diff-sequences@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" + integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +dunder-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" + integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== + dependencies: + call-bind-apply-helpers "^1.0.1" + es-errors "^1.3.0" + gopd "^1.2.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.5.263: + version "1.5.267" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz#5d84f2df8cdb6bfe7e873706bb21bd4bfb574dc7" + integrity sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw== + +emittery@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" + integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encodeurl@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" + integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== + +end-of-stream@^1.1.0: + version "1.4.5" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.5.tgz#7344d711dea40e0b74abc2ed49778743ccedb08c" + integrity sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg== + dependencies: + once "^1.4.0" + +error-ex@^1.3.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.4.tgz#b3a8d8bb6f92eecc1629e3e27d3c8607a8a32414" + integrity sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ== + dependencies: + is-arrayish "^0.2.1" + +es-define-property@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" + integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1" + integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== + dependencies: + es-errors "^1.3.0" + +escalade@^3.1.1, escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + +escape-html@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-plugin-prettier@^5.4.1: + version "5.5.5" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.5.tgz#9eae11593faa108859c26f9a9c367d619a0769c0" + integrity sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw== + dependencies: + prettier-linter-helpers "^1.0.1" + synckit "^0.11.12" + +eslint-plugin-unused-imports@^4.1.4: + version "4.4.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.4.1.tgz#a831f0a2937d7631eba30cb87091ab7d3a5da0e1" + integrity sha512-oZGYUz1X3sRMGUB+0cZyK2VcvRX5lm/vB56PgNNcU+7ficUCKm66oZWKUubXWnOuPjQ8PvmXtCViXBMONPe7tQ== + +eslint-scope@^8.4.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.4.0.tgz#88e646a207fad61436ffa39eb505147200655c82" + integrity sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + +eslint-visitor-keys@^4.2.0, eslint-visitor-keys@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz#4cfea60fe7dd0ad8e816e1ed026c1d5251b512c1" + integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ== + +eslint@^9.39.1: + version "9.39.4" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.39.4.tgz#855da1b2e2ad66dc5991195f35e262bcec8117b5" + integrity sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ== + dependencies: + "@eslint-community/eslint-utils" "^4.8.0" + "@eslint-community/regexpp" "^4.12.1" + "@eslint/config-array" "^0.21.2" + "@eslint/config-helpers" "^0.4.2" + "@eslint/core" "^0.17.0" + "@eslint/eslintrc" "^3.3.5" + "@eslint/js" "9.39.4" + "@eslint/plugin-kit" "^0.4.1" + "@humanfs/node" "^0.16.6" + "@humanwhocodes/module-importer" "^1.0.1" + "@humanwhocodes/retry" "^0.4.2" + "@types/estree" "^1.0.6" + ajv "^6.14.0" + chalk "^4.0.0" + cross-spawn "^7.0.6" + debug "^4.3.2" + escape-string-regexp "^4.0.0" + eslint-scope "^8.4.0" + eslint-visitor-keys "^4.2.1" + espree "^10.4.0" + esquery "^1.5.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^8.0.0" + find-up "^5.0.0" + glob-parent "^6.0.2" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + json-stable-stringify-without-jsonify "^1.0.1" + lodash.merge "^4.6.2" + minimatch "^3.1.5" + natural-compare "^1.4.0" + optionator "^0.9.3" + +espree@^10.0.1, espree@^10.4.0: + version "10.4.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-10.4.0.tgz#d54f4949d4629005a1fa168d937c3ff1f7e2a837" + integrity sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ== + dependencies: + acorn "^8.15.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^4.2.1" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.5.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.7.0.tgz#08d048f261f0ddedb5bae95f46809463d9c9496d" + integrity sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +eventsource-parser@^3.0.0, eventsource-parser@^3.0.1: + version "3.0.6" + resolved "https://registry.yarnpkg.com/eventsource-parser/-/eventsource-parser-3.0.6.tgz#292e165e34cacbc936c3c92719ef326d4aeb4e90" + integrity sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg== + +eventsource@^3.0.2: + version "3.0.7" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-3.0.7.tgz#1157622e2f5377bb6aef2114372728ba0c156989" + integrity sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA== + dependencies: + eventsource-parser "^3.0.1" + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== + +expect@^29.0.0, expect@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" + integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== + dependencies: + "@jest/expect-utils" "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + +express-rate-limit@^8.2.1: + version "8.3.1" + resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-8.3.1.tgz#0aaba098eadd40f6737f30a98e6b16fa1a29edfb" + integrity sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw== + dependencies: + ip-address "10.1.0" + +express@^5.1.0, express@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/express/-/express-5.2.1.tgz#8f21d15b6d327f92b4794ecf8cb08a72f956ac04" + integrity sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw== + dependencies: + accepts "^2.0.0" + body-parser "^2.2.1" + content-disposition "^1.0.0" + content-type "^1.0.5" + cookie "^0.7.1" + cookie-signature "^1.2.1" + debug "^4.4.0" + depd "^2.0.0" + encodeurl "^2.0.0" + escape-html "^1.0.3" + etag "^1.8.1" + finalhandler "^2.1.0" + fresh "^2.0.0" + http-errors "^2.0.0" + merge-descriptors "^2.0.0" + mime-types "^3.0.0" + on-finished "^2.4.1" + once "^1.4.0" + parseurl "^1.3.3" + proxy-addr "^2.0.7" + qs "^6.14.0" + range-parser "^1.2.1" + router "^2.2.0" + send "^1.1.0" + serve-static "^2.2.0" + statuses "^2.0.1" + type-is "^2.0.1" + vary "^1.1.2" + +external-editor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +fast-copy@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/fast-copy/-/fast-copy-4.0.2.tgz#57f14115e1edbec274f69090072a480aa29cbedd" + integrity sha512-ybA6PDXIXOXivLJK/z9e+Otk7ve13I4ckBvGO5I2RRmBU1gMHLVDJYEuJYhGwez7YNlYji2M2DvVU+a9mSFDlw== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-diff@^1.1.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== + +fast-glob@^3.2.12, fast-glob@^3.3.2: + version "3.3.3" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818" + integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.8" + +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fast-safe-stringify@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" + integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== + +fast-uri@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.0.tgz#66eecff6c764c0df9b762e62ca7edcfb53b4edfa" + integrity sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA== + +fastq@^1.6.0: + version "1.20.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.20.1.tgz#ca750a10dc925bc8b18839fd203e3ef4b3ced675" + integrity sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw== + dependencies: + reusify "^1.0.4" + +fb-watchman@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== + dependencies: + bser "2.1.1" + +fflate@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.2.tgz#fc8631f5347812ad6028bbe4a2308b2792aa1dea" + integrity sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A== + +file-entry-cache@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f" + integrity sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ== + dependencies: + flat-cache "^4.0.0" + +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-2.1.1.tgz#a2c517a6559852bcdb06d1f8bd7f51b68fad8099" + integrity sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA== + dependencies: + debug "^4.4.0" + encodeurl "^2.0.0" + escape-html "^1.0.3" + on-finished "^2.4.1" + parseurl "^1.3.3" + statuses "^2.0.1" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat-cache@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c" + integrity sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw== + dependencies: + flatted "^3.2.9" + keyv "^4.5.4" + +flatted@^3.2.9: + version "3.3.3" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.3.tgz#67c8fad95454a7c7abebf74bb78ee74a44023358" + integrity sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg== + +flora-colossus@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/flora-colossus/-/flora-colossus-2.0.0.tgz#af1e85db0a8256ef05f3fb531c1235236c97220a" + integrity sha512-dz4HxH6pOvbUzZpZ/yXhafjbR2I8cenK5xL0KtBFb7U2ADsR+OwXifnxZjij/pZWF775uSCMzWVd+jDik2H2IA== + dependencies: + debug "^4.3.4" + fs-extra "^10.1.0" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-2.0.0.tgz#8dd7df6a1b3a1b3a5cf186c05a5dd267622635a4" + integrity sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A== + +fs-extra@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@^2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +fuse.js@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-7.1.0.tgz#306228b4befeee11e05b027087c2744158527d09" + integrity sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ== + +galactus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/galactus/-/galactus-1.0.0.tgz#c2615182afa0c6d0859b92e56ae36d052827db7e" + integrity sha512-R1fam6D4CyKQGNlvJne4dkNF+PvUUl7TAJInvTGa9fti9qAv95quQz29GXapA4d8Ec266mJJxFVh82M4GIIGDQ== + dependencies: + debug "^4.3.4" + flora-colossus "^2.0.0" + fs-extra "^10.1.0" + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.2.5, get-intrinsic@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" + integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== + dependencies: + call-bind-apply-helpers "^1.0.2" + es-define-property "^1.0.1" + es-errors "^1.3.0" + es-object-atoms "^1.1.1" + function-bind "^1.1.2" + get-proto "^1.0.1" + gopd "^1.2.0" + has-symbols "^1.1.0" + hasown "^2.0.2" + math-intrinsics "^1.1.0" + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" + integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== + dependencies: + dunder-proto "^1.0.1" + es-object-atoms "^1.0.0" + +get-stdin@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53" + integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg== + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@^7.1.3, glob@^7.1.4: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e" + integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== + +gopd@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" + integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== + +graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + +handlebars@^4.7.8: + version "4.7.8" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" + integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.2" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" + integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== + +hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + +help-me@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/help-me/-/help-me-5.0.0.tgz#b1ebe63b967b74060027c2ac61f9be12d354a6f6" + integrity sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg== + +hono@^4.11.4, hono@^4.12.4: + version "4.12.7" + resolved "https://registry.yarnpkg.com/hono/-/hono-4.12.7.tgz#ca000956e965c2b3d791e43540498e616d6c6442" + integrity sha512-jq9l1DM0zVIvsm3lv9Nw9nlJnMNPOcAtsbsgiUhWcFzPE99Gvo6yRTlszSLLYacMeQ6quHD6hMfId8crVHvexw== + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +http-errors@^2.0.0, http-errors@^2.0.1, http-errors@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.1.tgz#36d2f65bc909c8790018dd36fb4d93da6caae06b" + integrity sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ== + dependencies: + depd "~2.0.0" + inherits "~2.0.4" + setprototypeof "~1.2.0" + statuses "~2.0.2" + toidentifier "~1.0.1" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@^0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.7.0, iconv-lite@~0.7.0: + version "0.7.2" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.7.2.tgz#d0bdeac3f12b4835b7359c2ad89c422a4d1cc72e" + integrity sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +ignore@^5.2.0, ignore@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" + integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== + +ignore@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-7.0.5.tgz#4cb5f6cd7d4c7ab0365738c7aea888baa6d7efd9" + integrity sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg== + +import-fresh@^3.2.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.1.tgz#9cecb56503c0ada1f2741dbbd6546e4b13b57ccf" + integrity sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-local@^3.0.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.2.0.tgz#c3d5c745798c02a6f8b897726aba5100186ee260" + integrity sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.3, inherits@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ip-address@10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-10.1.0.tgz#d8dcffb34d0e02eb241427444a6e23f5b0595aa4" + integrity sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-core-module@^2.16.1: + version "2.16.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" + integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== + dependencies: + hasown "^2.0.2" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-promise@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-4.0.0.tgz#42ff9f84206c1991d26debf520dd5c01042dd2f3" + integrity sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== + +istanbul-lib-instrument@^5.0.4: + version "5.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +istanbul-lib-instrument@^6.0.0: + version "6.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz#fa15401df6c15874bcb2105f773325d78c666765" + integrity sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q== + dependencies: + "@babel/core" "^7.23.9" + "@babel/parser" "^7.23.9" + "@istanbuljs/schema" "^0.1.3" + istanbul-lib-coverage "^3.2.0" + semver "^7.5.4" + +istanbul-lib-report@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^4.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.2.0.tgz#cb4535162b5784aa623cee21a7252cf2c807ac93" + integrity sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jest-changed-files@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" + integrity sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w== + dependencies: + execa "^5.0.0" + jest-util "^29.7.0" + p-limit "^3.1.0" + +jest-circus@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.7.0.tgz#b6817a45fcc835d8b16d5962d0c026473ee3668a" + integrity sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^1.0.0" + is-generator-fn "^2.0.0" + jest-each "^29.7.0" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + p-limit "^3.1.0" + pretty-format "^29.7.0" + pure-rand "^6.0.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-cli@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995" + integrity sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg== + dependencies: + "@jest/core" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + chalk "^4.0.0" + create-jest "^29.7.0" + exit "^0.1.2" + import-local "^3.0.2" + jest-config "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + yargs "^17.3.1" + +jest-config@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f" + integrity sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ== + dependencies: + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^29.7.0" + "@jest/types" "^29.6.3" + babel-jest "^29.7.0" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^29.7.0" + jest-environment-node "^29.7.0" + jest-get-type "^29.6.3" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-runner "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^29.7.0" + slash "^3.0.0" + strip-json-comments "^3.1.1" + +jest-diff@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" + integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.6.3" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-docblock@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.7.0.tgz#8fddb6adc3cdc955c93e2a87f61cfd350d5d119a" + integrity sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g== + dependencies: + detect-newline "^3.0.0" + +jest-each@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1" + integrity sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ== + dependencies: + "@jest/types" "^29.6.3" + chalk "^4.0.0" + jest-get-type "^29.6.3" + jest-util "^29.7.0" + pretty-format "^29.7.0" + +jest-environment-node@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" + integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + jest-mock "^29.7.0" + jest-util "^29.7.0" + +jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== + +jest-haste-map@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.7.0.tgz#3c2396524482f5a0506376e6c858c3bbcc17b104" + integrity sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA== + dependencies: + "@jest/types" "^29.6.3" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^29.6.3" + jest-util "^29.7.0" + jest-worker "^29.7.0" + micromatch "^4.0.4" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.2" + +jest-leak-detector@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728" + integrity sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw== + dependencies: + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-matcher-utils@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" + integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== + dependencies: + chalk "^4.0.0" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-message-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" + integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.6.3" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.7.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" + integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + jest-util "^29.7.0" + +jest-pnp-resolver@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" + integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== + +jest-regex-util@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52" + integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== + +jest-resolve-dependencies@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz#1b04f2c095f37fc776ff40803dc92921b1e88428" + integrity sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA== + dependencies: + jest-regex-util "^29.6.3" + jest-snapshot "^29.7.0" + +jest-resolve@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.7.0.tgz#64d6a8992dd26f635ab0c01e5eef4399c6bcbc30" + integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-pnp-resolver "^1.2.2" + jest-util "^29.7.0" + jest-validate "^29.7.0" + resolve "^1.20.0" + resolve.exports "^2.0.0" + slash "^3.0.0" + +jest-runner@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e" + integrity sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ== + dependencies: + "@jest/console" "^29.7.0" + "@jest/environment" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.13.1" + graceful-fs "^4.2.9" + jest-docblock "^29.7.0" + jest-environment-node "^29.7.0" + jest-haste-map "^29.7.0" + jest-leak-detector "^29.7.0" + jest-message-util "^29.7.0" + jest-resolve "^29.7.0" + jest-runtime "^29.7.0" + jest-util "^29.7.0" + jest-watcher "^29.7.0" + jest-worker "^29.7.0" + p-limit "^3.1.0" + source-map-support "0.5.13" + +jest-runtime@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817" + integrity sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/globals" "^29.7.0" + "@jest/source-map" "^29.6.3" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + slash "^3.0.0" + strip-bom "^4.0.0" + +jest-snapshot@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5" + integrity sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw== + dependencies: + "@babel/core" "^7.11.6" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-jsx" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^29.7.0" + graceful-fs "^4.2.9" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + natural-compare "^1.4.0" + pretty-format "^29.7.0" + semver "^7.5.3" + +jest-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" + integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" + integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== + dependencies: + "@jest/types" "^29.6.3" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^29.6.3" + leven "^3.1.0" + pretty-format "^29.7.0" + +jest-watcher@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.7.0.tgz#7810d30d619c3a62093223ce6bb359ca1b28a2f2" + integrity sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g== + dependencies: + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.13.1" + jest-util "^29.7.0" + string-length "^4.0.1" + +jest-worker@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" + integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== + dependencies: + "@types/node" "*" + jest-util "^29.7.0" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@^29.4.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613" + integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== + dependencies: + "@jest/core" "^29.7.0" + "@jest/types" "^29.6.3" + import-local "^3.0.2" + jest-cli "^29.7.0" + +jose@^6.1.3: + version "6.2.1" + resolved "https://registry.yarnpkg.com/jose/-/jose-6.2.1.tgz#7a6b1de83816deaee9055a558e1278a7b2b9ea1b" + integrity sha512-jUaKr1yrbfaImV7R2TN/b3IcZzsw38/chqMpo2XJ7i2F8AfM/lA4G1goC3JVEwg0H7UldTmSt3P68nt31W7/mw== + +joycon@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/joycon/-/joycon-3.1.1.tgz#bce8596d6ae808f8b68168f5fc69280996894f03" + integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw== + +"jq-web@https://github.com/stainless-api/jq-web/releases/download/v0.8.8/jq-web.tar.gz": + version "0.8.8" + resolved "https://github.com/stainless-api/jq-web/releases/download/v0.8.8/jq-web.tar.gz#7849ef64bdfc28f70cbfc9888f886860e96da10d" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.2" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.2.tgz#77485ce1dd7f33c061fd1b16ecea23b55fcb04b0" + integrity sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b" + integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== + dependencies: + argparse "^2.0.1" + +jsesc@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" + integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-schema-typed@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/json-schema-typed/-/json-schema-typed-8.0.2.tgz#e98ee7b1899ff4a184534d1f167c288c66bbeff4" + integrity sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +json5@^2.2.2, json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +jsonfile@^6.0.1: + version "6.2.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.2.0.tgz#7c265bd1b65de6977478300087c99f1c84383f62" + integrity sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +keyv@^4.5.4: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== + dependencies: + semver "^7.5.3" + +make-error@^1.1.1, make-error@^1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + +math-intrinsics@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" + integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== + +media-typer@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-1.1.0.tgz#6ab74b8f2d3320f2064b2a87a38e7931ff3a5561" + integrity sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw== + +merge-descriptors@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-2.0.0.tgz#ea922f660635a2249ee565e0449f951e6b603808" + integrity sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4, micromatch@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== + dependencies: + braces "^3.0.3" + picomatch "^2.3.1" + +mime-db@^1.54.0: + version "1.54.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.54.0.tgz#cddb3ee4f9c64530dff640236661d42cb6a314f5" + integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== + +mime-types@^3.0.0, mime-types@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-3.0.2.tgz#39002d4182575d5af036ffa118100f2524b2e2ab" + integrity sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A== + dependencies: + mime-db "^1.54.0" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.5.tgz#580c88f8d5445f2bd6aa8f3cadefa0de79fbd69e" + integrity sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^7.4.3: + version "7.4.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-7.4.6.tgz#845d6f254d8f4a5e4fd6baf44d5f10c8448365fb" + integrity sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.2.5, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +mkdirp@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.6.tgz#964fbcb12b2d8c5d6fbc62a963ac95a273e2cc19" + integrity sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A== + +ms@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +mute-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" + integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +negotiator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.0.0.tgz#b6c91bb47172d69f93cfd7c357bbb529019b5f6a" + integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +node-forge@^1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.3.tgz#0ad80f6333b3a0045e827ac20b7f735f93716751" + integrity sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg== + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== + +node-releases@^2.0.27: + version "2.0.27" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" + integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +object-assign@^4: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-inspect@^1.13.3: + version "1.13.4" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" + integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== + +on-exit-leak-free@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz#fed195c9ebddb7d9e4c3842f93f281ac8dadd3b8" + integrity sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA== + +on-finished@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +optionator@^0.9.3: + version "0.9.4" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" + integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.5" + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== + +p-all@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-all/-/p-all-3.0.0.tgz#077c023c37e75e760193badab2bad3ccd5782bfb" + integrity sha512-qUZbvbBFVXm6uJ7U/WDiO0fv6waBMbjlCm4E66oZdRR+egswICarIdHyVSZZHudH8T5SF8x/JG0q0duFzPnlBw== + dependencies: + p-map "^4.0.0" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2, p-limit@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parseurl@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-browserify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@^8.0.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-8.3.0.tgz#aa818a6981f99321003a08987d3cec9c3474cd1f" + integrity sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA== + +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + +picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pino-abstract-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-3.0.0.tgz#b21e5f33a297e8c4c915c62b3ce5dd4a87a52c23" + integrity sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg== + dependencies: + split2 "^4.0.0" + +pino-http@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/pino-http/-/pino-http-11.0.0.tgz#ebadef4694fc59aadab9be7e5939aea625b4615f" + integrity sha512-wqg5XIAGRRIWtTk8qPGxkbrfiwEWz1lgedVLvhLALudKXvg1/L2lTFgTGPJ4Z2e3qcRmxoFxDuSdMdMGNM6I1g== + dependencies: + get-caller-file "^2.0.5" + pino "^10.0.0" + pino-std-serializers "^7.0.0" + process-warning "^5.0.0" + +pino-pretty@^13.1.3: + version "13.1.3" + resolved "https://registry.yarnpkg.com/pino-pretty/-/pino-pretty-13.1.3.tgz#2274cccda925dd355c104079a5029f6598d0381b" + integrity sha512-ttXRkkOz6WWC95KeY9+xxWL6AtImwbyMHrL1mSwqwW9u+vLp/WIElvHvCSDg0xO/Dzrggz1zv3rN5ovTRVowKg== + dependencies: + colorette "^2.0.7" + dateformat "^4.6.3" + fast-copy "^4.0.0" + fast-safe-stringify "^2.1.1" + help-me "^5.0.0" + joycon "^3.1.1" + minimist "^1.2.6" + on-exit-leak-free "^2.1.0" + pino-abstract-transport "^3.0.0" + pump "^3.0.0" + secure-json-parse "^4.0.0" + sonic-boom "^4.0.1" + strip-json-comments "^5.0.2" + +pino-std-serializers@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-7.1.0.tgz#a7b0cd65225f29e92540e7853bd73b07479893fc" + integrity sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw== + +pino@^10.0.0, pino@^10.3.1: + version "10.3.1" + resolved "https://registry.yarnpkg.com/pino/-/pino-10.3.1.tgz#6552c8f8d8481844c9e452e7bf0be90bff1939ce" + integrity sha512-r34yH/GlQpKZbU1BvFFqOjhISRo1MNx1tWYsYvmj6KIRHSPMT2+yHOEb1SG6NMvRoHRF0a07kCOox/9yakl1vg== + dependencies: + "@pinojs/redact" "^0.4.0" + atomic-sleep "^1.0.0" + on-exit-leak-free "^2.1.0" + pino-abstract-transport "^3.0.0" + pino-std-serializers "^7.0.0" + process-warning "^5.0.0" + quick-format-unescaped "^4.0.3" + real-require "^0.2.0" + safe-stable-stringify "^2.3.1" + sonic-boom "^4.0.1" + thread-stream "^4.0.0" + +pirates@^4.0.4: + version "4.0.7" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.7.tgz#643b4a18c4257c8a65104b73f3049ce9a0a15e22" + integrity sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA== + +pkce-challenge@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/pkce-challenge/-/pkce-challenge-5.0.1.tgz#3b4446865b17b1745e9ace2016a31f48ddf6230d" + integrity sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prettier-linter-helpers@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz#6a31f88a4bad6c7adda253de12ba4edaea80ebcd" + integrity sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg== + dependencies: + fast-diff "^1.1.2" + +prettier@^3.0.0: + version "3.7.4" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.7.4.tgz#d2f8335d4b1cec47e1c8098645411b0c9dff9c0f" + integrity sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA== + +pretty-bytes@^5.6.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" + integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== + +pretty-format@^29.0.0, pretty-format@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" + integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== + dependencies: + "@jest/schemas" "^29.6.3" + ansi-styles "^5.0.0" + react-is "^18.0.0" + +process-warning@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-5.0.0.tgz#566e0bf79d1dff30a72d8bbbe9e8ecefe8d378d7" + integrity sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA== + +prompts@^2.0.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +proxy-addr@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +pump@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.4.tgz#1f313430527fa8b905622ebd22fe1444e757ab3c" + integrity sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +pure-rand@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2" + integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA== + +qs@^6.14.0, qs@^6.14.1: + version "6.14.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.1.tgz#a41d85b9d3902f31d27861790506294881871159" + integrity sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ== + dependencies: + side-channel "^1.1.0" + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +quick-format-unescaped@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" + integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== + +range-parser@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@^3.0.0, raw-body@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-3.0.2.tgz#3e3ada5ae5568f9095d84376fd3a49b8fb000a51" + integrity sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA== + dependencies: + bytes "~3.1.2" + http-errors "~2.0.1" + iconv-lite "~0.7.0" + unpipe "~1.0.0" + +react-is@^18.0.0: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" + integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== + +readable-stream@^3.4.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +real-require@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.2.0.tgz#209632dea1810be2ae063a6ac084fee7e33fba78" + integrity sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg== + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve.exports@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.3.tgz#41955e6f1b4013b7586f873749a635dea07ebe3f" + integrity sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A== + +resolve@^1.20.0: + version "1.22.11" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.11.tgz#aad857ce1ffb8bfa9b0b1ac29f1156383f68c262" + integrity sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ== + dependencies: + is-core-module "^2.16.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +reusify@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.1.0.tgz#0fe13b9522e1473f51b558ee796e08f11f9b489f" + integrity sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw== + +router@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/router/-/router-2.2.0.tgz#019be620b711c87641167cc79b99090f00b146ef" + integrity sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ== + dependencies: + debug "^4.4.0" + depd "^2.0.0" + is-promise "^4.0.0" + parseurl "^1.3.3" + path-to-regexp "^8.0.0" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-stable-stringify@^2.3.1: + version "2.5.0" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz#4ca2f8e385f2831c432a719b108a3bf7af42a1dd" + integrity sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA== + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +secure-json-parse@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-4.1.0.tgz#4f1ab41c67a13497ea1b9131bb4183a22865477c" + integrity sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA== + +semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.7.3: + version "7.7.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.3.tgz#4b5f4143d007633a8dc671cd0a6ef9147b8bb946" + integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== + +send@^1.1.0, send@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/send/-/send-1.2.1.tgz#9eab743b874f3550f40a26867bf286ad60d3f3ed" + integrity sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ== + dependencies: + debug "^4.4.3" + encodeurl "^2.0.0" + escape-html "^1.0.3" + etag "^1.8.1" + fresh "^2.0.0" + http-errors "^2.0.1" + mime-types "^3.0.2" + ms "^2.1.3" + on-finished "^2.4.1" + range-parser "^1.2.1" + statuses "^2.0.2" + +serve-static@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-2.2.1.tgz#7f186a4a4e5f5b663ad7a4294ff1bf37cf0e98a9" + integrity sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw== + dependencies: + encodeurl "^2.0.0" + escape-html "^1.0.3" + parseurl "^1.3.3" + send "^1.2.0" + +setprototypeof@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel-list@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" + integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== + dependencies: + es-errors "^1.3.0" + object-inspect "^1.13.3" + +side-channel-map@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42" + integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + +side-channel-weakmap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea" + integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + side-channel-map "^1.0.1" + +side-channel@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" + integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== + dependencies: + es-errors "^1.3.0" + object-inspect "^1.13.3" + side-channel-list "^1.0.0" + side-channel-map "^1.0.1" + side-channel-weakmap "^1.0.2" + +signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +signal-exit@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +sonic-boom@^4.0.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-4.2.1.tgz#28598250df4899c0ac572d7e2f0460690ba6a030" + integrity sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q== + dependencies: + atomic-sleep "^1.0.0" + +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +split2@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +stack-utils@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== + dependencies: + escape-string-regexp "^2.0.0" + +statuses@^2.0.1, statuses@^2.0.2, statuses@~2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.2.tgz#8f75eecef765b5e1cfcdc080da59409ed424e382" + integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== + +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + +string-to-stream@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/string-to-stream/-/string-to-stream-3.0.1.tgz#480e6fb4d5476d31cb2221f75307a5dcb6638a42" + integrity sha512-Hl092MV3USJuUCC6mfl9sPzGloA3K5VwdIeJjYIkXY/8K+mUvaeEabWJgArp+xXrsWxCajeT2pc4axbVhIZJyg== + dependencies: + readable-stream "^3.4.0" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + 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_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +strip-json-comments@^5.0.2: + version "5.0.3" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-5.0.3.tgz#b7304249dd402ee67fd518ada993ab3593458bcf" + integrity sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw== + +superstruct@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-1.0.4.tgz#0adb99a7578bd2f1c526220da6571b2d485d91ca" + integrity sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ== + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +synckit@^0.11.12: + version "0.11.12" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.11.12.tgz#abe74124264fbc00a48011b0d98bdc1cffb64a7b" + integrity sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ== + dependencies: + "@pkgr/core" "^0.2.9" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +thread-stream@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-4.0.0.tgz#732f007c24da7084f729d6e3a7e3f5934a7380b7" + integrity sha512-4iMVL6HAINXWf1ZKZjIPcz5wYaOdPhtO8ATvZ+Xqp3BTdaqtAwQkNmKORqcIo5YkQqGXq5cwfswDwMqqQNrpJA== + dependencies: + real-require "^0.2.0" + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +ts-api-utils@^2.0.1: + version "2.4.0" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.4.0.tgz#2690579f96d2790253bdcf1ca35d569ad78f9ad8" + integrity sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA== + +ts-jest@^29.1.0: + version "29.4.6" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.4.6.tgz#51cb7c133f227396818b71297ad7409bb77106e9" + integrity sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA== + dependencies: + bs-logger "^0.2.6" + fast-json-stable-stringify "^2.1.0" + handlebars "^4.7.8" + json5 "^2.2.3" + lodash.memoize "^4.1.2" + make-error "^1.3.6" + semver "^7.7.3" + type-fest "^4.41.0" + yargs-parser "^21.1.1" + +ts-morph@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-19.0.0.tgz#43e95fb0156c3fe3c77c814ac26b7d0be2f93169" + integrity sha512-D6qcpiJdn46tUqV45vr5UGM2dnIEuTGNxVhg0sk5NX11orcouwj6i1bMqZIz2mZTZB1Hcgy7C3oEVhAT+f6mbQ== + dependencies: + "@ts-morph/common" "~0.20.0" + code-block-writer "^12.0.0" + +ts-node@^10.5.0: + version "10.9.2" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" + integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + +"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz": + version "1.1.9" + resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz#777f6f5d9e26bf0e94e5170990dd3a841d6707cd" + dependencies: + debug "^4.3.7" + fast-glob "^3.3.2" + get-stdin "^8.0.0" + p-all "^3.0.0" + picocolors "^1.1.1" + signal-exit "^3.0.7" + string-to-stream "^3.0.1" + superstruct "^1.0.4" + tslib "^2.8.1" + yargs "^17.7.2" + +tsconfig-paths@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" + integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== + dependencies: + json5 "^2.2.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + +tslib@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-fest@^4.41.0: + version "4.41.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.41.0.tgz#6ae1c8e5731273c2bf1f58ad39cbae2c91a46c58" + integrity sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA== + +type-is@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-2.0.1.tgz#64f6cf03f92fce4015c2b224793f6bdd4b068c97" + integrity sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw== + dependencies: + content-type "^1.0.5" + media-typer "^1.1.0" + mime-types "^3.0.0" + +typescript@5.8.3: + version "5.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e" + integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ== + +uglify-js@^3.1.4: + version "3.19.3" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.19.3.tgz#82315e9bbc6f2b25888858acd1fff8441035b77f" + integrity sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ== + +undici-types@~6.21.0: + version "6.21.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" + integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== + +undici-types@~7.16.0: + version "7.16.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.16.0.tgz#ffccdff36aea4884cbfce9a750a0580224f58a46" + integrity sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw== + +universalify@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== + +unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +update-browserslist-db@^1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d" + integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w== + dependencies: + escalade "^3.2.0" + picocolors "^1.1.1" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + +v8-to-istanbul@^9.0.1: + version "9.3.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz#b9572abfa62bd556c16d75fdebc1a411d5ff3175" + integrity sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^2.0.0" + +vary@^1, vary@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +walker@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== + +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +write-file-atomic@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" + integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^3.0.7" + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^17.3.1, yargs@^17.7.2: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + 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" + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +yoctocolors-cjs@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz#7e4964ea8ec422b7a40ac917d3a344cfd2304baa" + integrity sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw== + +zod-to-json-schema@^3.24.5, zod-to-json-schema@^3.24.6, zod-to-json-schema@^3.25.1: + version "3.25.1" + resolved "https://registry.yarnpkg.com/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz#7f24962101a439ddade2bf1aeab3c3bfec7d84ba" + integrity sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA== + +zod-validation-error@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/zod-validation-error/-/zod-validation-error-4.0.2.tgz#bc605eba49ce0fcd598c127fee1c236be3f22918" + integrity sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ== + +"zod@^3.25 || ^4.0": + version "4.3.5" + resolved "https://registry.yarnpkg.com/zod/-/zod-4.3.5.tgz#aeb269a6f9fc259b1212c348c7c5432aaa474d2a" + integrity sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g== + +zod@^3.25.20, zod@^3.25.67: + version "3.25.76" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.25.76.tgz#26841c3f6fd22a6a2760e7ccb719179768471e34" + integrity sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==