pull/715/head
Travis Fischer 2025-05-19 18:22:49 +07:00
rodzic 1ec6e5e04b
commit c034c9eef3
7 zmienionych plików z 361 dodań i 45 usunięć

Wyświetl plik

@ -44,6 +44,7 @@
"@hono/zod-openapi": "^0.19.6",
"@hono/zod-validator": "^0.5.0",
"@paralleldrive/cuid2": "^2.2.2",
"@redocly/openapi-core": "^1.34.3",
"@sentry/node": "^9.19.0",
"bcryptjs": "^3.0.2",
"eventid": "^2.0.1",
@ -52,6 +53,7 @@
"hono": "^4.7.9",
"jsonwebtoken": "^9.0.2",
"p-all": "^5.0.0",
"parse-json": "^8.3.0",
"postgres": "^3.4.5",
"restore-cursor": "catalog:",
"semver": "^7.7.2",
@ -64,6 +66,7 @@
"@types/jsonwebtoken": "^9.0.9",
"@types/semver": "^7.7.0",
"drizzle-kit": "^0.31.1",
"drizzle-orm": "^0.43.1"
"drizzle-orm": "^0.43.1",
"openapi-typescript": "^7.8.0"
}
}

Wyświetl plik

@ -59,6 +59,7 @@ export function registerV1DeploymentsCreateDeployment(
const { publish } = c.req.valid('query')
const body = c.req.valid('json')
const teamMember = c.get('teamMember')
const logger = c.get('logger')
const { projectId } = body
// validatePricingPlans(ctx, pricingPlans)
@ -86,7 +87,7 @@ export function registerV1DeploymentsCreateDeployment(
assert(
version,
400,
`Deployment version is required to publish deployment "${deploymentId}"`
`Deployment "version" field is required to publish deployment "${deploymentId}"`
)
}
@ -101,7 +102,8 @@ export function registerV1DeploymentsCreateDeployment(
// Validate OpenAPI originUrl and originAdapter
await validateDeploymentOriginAdapter({
...pick(body, 'originUrl', 'originAdapter'),
deploymentId
deploymentId,
logger
})
let [[deployment]] = await db.transaction(async (tx) => {

Wyświetl plik

@ -1,4 +1,5 @@
import { z } from '@hono/zod-openapi'
import parseJson from 'parse-json'
export const authProviderTypeSchema = z
.enum(['github', 'google', 'spotify', 'twitter', 'linkedin', 'stripe'])
@ -452,19 +453,6 @@ export const commonDeploymentOriginAdapterSchema = z.object({
// internalType: deploymentOriginAdapterInternalTypeSchema.optional()
})
const jsonLiteralSchema = z.union([
z.string(),
z.number(),
z.boolean(),
z.null()
])
type JsonLiteral = z.infer<typeof jsonLiteralSchema>
type Json = JsonLiteral | { [key: string]: Json } | Json[]
const jsonSchema: z.ZodType<Json> = z.lazy(() =>
z.union([jsonLiteralSchema, z.array(jsonSchema), z.record(jsonSchema)])
)
const jsonObjectSchema = z.record(jsonSchema)
// TODO: add future support for:
// - external mcp
// - internal docker
@ -476,11 +464,36 @@ export const deploymentOriginAdapterSchema = z
z
.object({
type: z.literal('openapi'),
version: z.enum(['3.0', '3.1']),
// TODO: Make sure origin API servers are hidden in this embedded OpenAPI spec
spec: jsonObjectSchema.describe(
'JSON OpenAPI spec for the origin API server.'
)
// NOTE: The origin API servers should be hidden in the embedded
// OpenAPI spec, because clients should only be aware of the upstream
// Agentic API gateway.
spec: z
.string()
.refine(
(spec) => {
try {
parseJson(spec)
} catch {
return false
}
},
(data) => {
try {
parseJson(data)
} catch (err: any) {
return {
message: `Invalid OpenAPI spec: ${err.message}`
}
}
return {
message: 'Invalid OpenAPI spec'
}
}
)
.describe(
'JSON stringified OpenAPI spec describing the origin API server.'
)
})
.merge(commonDeploymentOriginAdapterSchema),

Wyświetl plik

@ -1,14 +1,23 @@
import type { DeploymentOriginAdapter } from '@/db/schema'
import type { Logger } from '@/lib/logger'
import { assert } from '@/lib/utils'
import { validateOpenAPISpec } from '@/lib/validate-openapi-spec'
/**
* Validates and normalizes the origin adapter config for a deployment.
*
* NOTE: This method may mutate `originAdapter.spec`.
*/
export async function validateDeploymentOriginAdapter({
deploymentId,
originUrl,
originAdapter
originAdapter,
logger
}: {
deploymentId: string
originUrl: string
originAdapter: DeploymentOriginAdapter
logger: Logger
}): Promise<void> {
assert(
originUrl,
@ -17,17 +26,29 @@ export async function validateDeploymentOriginAdapter({
)
if (originAdapter.type === 'openapi') {
// TODO: Validate OpenAPI spec
assert(
originAdapter.spec,
400,
`OpenAPI spec is required for deployment "${deploymentId}"`
`OpenAPI spec is required for deployment "${deploymentId}" with origin adapter type set to "openapi"`
)
// TODO: Validate OpenAPI spec version is the same as `originAdapter.version`
// Validate and normalize the OpenAPI spec
const openapiSpec = await validateOpenAPISpec(originAdapter.spec, {
logger
})
// TODO: Remove origin servers from the OpenAPI spec and if they exist, ensure
// that `originUrl` matches.
// Remove origin servers from the OpenAPI spec.
// TODO: Ensure that `originUrl` matches any origin servers in the openapi spec?
delete openapiSpec.servers
// TODO: Additional, agentic-specific validation of the OpenAPI spec's
// operations to ensure they are valid AI functions.
// TODO: Simplify OpenAPI spec by removing any query params and headers
// specific to the Agentic API gateway.
// Update the openapi spec with the normalized version
originAdapter.spec = JSON.stringify(openapiSpec)
} else {
assert(
originAdapter.type === 'raw',

Wyświetl plik

@ -5,6 +5,8 @@ import type { RawTeamMember, RawUser } from '@/db'
import type { Env } from './env'
import type { Logger } from './logger'
export type { OpenAPI3 as LooseOpenAPI3Spec } from 'openapi-typescript'
export type Environment = Env['NODE_ENV']
export type Service = 'api'

Wyświetl plik

@ -0,0 +1,135 @@
import {
BaseResolver,
bundle,
type Config as RedoclyConfig,
createConfig,
type Document,
lintDocument,
type NormalizedProblem,
Source
} from '@redocly/openapi-core'
import parseJson from 'parse-json'
import type { Logger } from './logger'
import type { LooseOpenAPI3Spec } from './types'
function _processProblems(
problems: NormalizedProblem[],
{
logger,
silent
}: {
logger: Logger
silent: boolean
}
) {
if (problems.length) {
let errorMessage: string | undefined
for (const problem of problems) {
const problemLocation = problem.location?.[0]?.pointer
const problemMessage = problemLocation
? `${problem.message} at ${problemLocation}`
: problem.message
if (problem.severity === 'error') {
errorMessage = problemMessage
logger.error('openapi spec error', problemMessage)
} else if (!silent) {
logger.warn('openapi spec warning', problemMessage)
}
}
if (errorMessage) {
throw new Error(errorMessage)
}
}
}
/**
* Validates an OpenAPI spec and bundles it into a single, normalized schema.
*
* The input `source` should be a JSON stringified OpenAPI spec (3.0 or 3.1).
*/
export async function validateOpenAPISpec(
source: string,
{
logger,
redoclyConfig,
silent = false
}: {
logger: Logger
redoclyConfig?: RedoclyConfig
silent?: boolean
}
): Promise<LooseOpenAPI3Spec> {
if (!redoclyConfig) {
redoclyConfig = await createConfig(
{
rules: {
// throw error on duplicate operationIds
'operation-operationId-unique': { severity: 'error' }
}
},
{ extends: ['minimal'] }
)
}
logger.debug('Parsing openapi spec')
const resolver = new BaseResolver(redoclyConfig.resolve)
let parsed: any
try {
parsed = parseJson(source)
} catch (err: any) {
throw new Error(`Invalid OpenAPI spec: ${err.message}`)
}
const document: Document = {
source: new Source('', source, 'application/json'),
parsed
}
logger.debug('Parsed openapi spec')
// Check for OpenAPI 3 or greater
const openapiVersion = Number.parseFloat(document.parsed.openapi)
if (
document.parsed.swagger ||
!document.parsed.openapi ||
Number.isNaN(openapiVersion) ||
openapiVersion < 3 ||
openapiVersion >= 4
) {
if (document.parsed.swagger) {
throw new Error(
'Unsupported Swagger version: 2.x. Use OpenAPI 3.x instead.'
)
}
if (document.parsed.openapi || openapiVersion < 3 || openapiVersion >= 4) {
throw new Error(`Unsupported OpenAPI version: ${document.parsed.openapi}`)
}
throw new Error('Unsupported schema format, expected `openapi: 3.x`')
}
logger.debug('>>> Linting openapi spec')
const problems = await lintDocument({
document,
config: redoclyConfig.styleguide,
externalRefResolver: resolver
})
_processProblems(problems, { silent, logger })
logger.debug('<<< Linting openapi spec')
logger.debug('>>> Bundling openapi spec')
const bundled = await bundle({
config: redoclyConfig,
dereference: false,
doc: document
})
_processProblems(bundled.problems, { silent, logger })
logger.debug('<<< Bundling openapi spec')
return bundled.bundle.parsed
}

Wyświetl plik

@ -149,6 +149,9 @@ importers:
'@paralleldrive/cuid2':
specifier: ^2.2.2
version: 2.2.2
'@redocly/openapi-core':
specifier: ^1.34.3
version: 1.34.3(supports-color@10.0.0)
'@sentry/node':
specifier: ^9.19.0
version: 9.19.0
@ -173,6 +176,9 @@ importers:
p-all:
specifier: ^5.0.0
version: 5.0.0
parse-json:
specifier: ^8.3.0
version: 8.3.0
postgres:
specifier: ^3.4.5
version: 3.4.5
@ -207,6 +213,9 @@ importers:
drizzle-orm:
specifier: ^0.43.1
version: 0.43.1(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(postgres@3.4.5)
openapi-typescript:
specifier: ^7.8.0
version: 7.8.0(typescript@5.8.3)
packages/validators:
dependencies:
@ -965,6 +974,16 @@ packages:
peerDependencies:
'@opentelemetry/api': ^1.8
'@redocly/ajv@8.11.2':
resolution: {integrity: sha512-io1JpnwtIcvojV7QKDUSIuMN/ikdOUd1ReEnUnMKGfDVridQZ31J0MmIuqwuRjWDZfmvr+Q0MqCcfHM2gTivOg==}
'@redocly/config@0.22.2':
resolution: {integrity: sha512-roRDai8/zr2S9YfmzUfNhKjOF0NdcOIqF7bhf4MVC5UxpjIysDjyudvlAiVbpPHp3eDRWbdzUgtkK1a7YiDNyQ==}
'@redocly/openapi-core@1.34.3':
resolution: {integrity: sha512-3arRdUp1fNx55itnjKiUhO6t4Mf91TsrTIYINDNLAZPS0TPd5YpiXRctwjel0qqWoOOhjA34cZ3m4dksLDFUYg==}
engines: {node: '>=18.17.0', npm: '>=9.5.0'}
'@rollup/rollup-android-arm-eabi@4.40.0':
resolution: {integrity: sha512-+Fbls/diZ0RDerhE8kyC6hjADCXA1K4yVNlH0EYfd2XjyH0UGgzaQ8MlT0pCXAThfxv3QUAczHaL+qSv1E4/Cg==}
cpu: [arm]
@ -1256,9 +1275,17 @@ packages:
engines: {node: '>=0.4.0'}
hasBin: true
agent-base@7.1.3:
resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==}
engines: {node: '>= 14'}
ajv@6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
ansi-colors@4.1.3:
resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
engines: {node: '>=6'}
ansi-escapes@7.0.0:
resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==}
engines: {node: '>=18'}
@ -1425,6 +1452,9 @@ packages:
resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==}
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
change-case@5.4.4:
resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==}
check-error@2.1.1:
resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==}
engines: {node: '>= 16'}
@ -1459,6 +1489,9 @@ packages:
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
colorette@1.4.0:
resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==}
colorette@2.0.20:
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
@ -2141,6 +2174,10 @@ packages:
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
engines: {node: '>= 0.8'}
https-proxy-agent@7.0.6:
resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
engines: {node: '>= 14'}
iconv-lite@0.6.3:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
engines: {node: '>=0.10.0'}
@ -2343,6 +2380,10 @@ packages:
resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
engines: {node: '>=10'}
js-levenshtein@1.1.6:
resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==}
engines: {node: '>=0.10.0'}
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@ -2370,6 +2411,9 @@ packages:
json-schema-traverse@0.4.1:
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
json-schema-traverse@1.0.0:
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
json-stable-stringify-without-jsonify@1.0.1:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
@ -2524,6 +2568,10 @@ packages:
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
minimatch@5.1.6:
resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
engines: {node: '>=10'}
minimatch@9.0.5:
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
engines: {node: '>=16 || 14 >=14.17'}
@ -2623,6 +2671,12 @@ packages:
resolution: {integrity: sha512-M7CJbmv7UCopc0neRKdzfoGWaVZC+xC1925GitKH9EAqYFzX9//25Q7oX4+jw0tiCCj+t5l6VZh8UPH23NZkMA==}
hasBin: true
openapi-typescript@7.8.0:
resolution: {integrity: sha512-1EeVWmDzi16A+siQlo/SwSGIT7HwaFAVjvMA7/jG5HMLSnrUOzPL7uSTRZZa4v/LCRxHTApHKtNY6glApEoiUQ==}
hasBin: true
peerDependencies:
typescript: ^5.x
openapi3-ts@4.4.0:
resolution: {integrity: sha512-9asTNB9IkKEzWMcHmVZE7Ts3kC9G7AFHfs8i7caD8HbI76gEjdkId4z/AkP83xdZsH7PLAnnbl47qZkXuxpArw==}
@ -2857,6 +2911,10 @@ packages:
resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==}
hasBin: true
require-from-string@2.0.2:
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
engines: {node: '>=0.10.0'}
require-in-the-middle@7.5.2:
resolution: {integrity: sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==}
engines: {node: '>=8.6.0'}
@ -3129,6 +3187,10 @@ packages:
engines: {node: '>=16 || 14 >=14.17'}
hasBin: true
supports-color@10.0.0:
resolution: {integrity: sha512-HRVVSbCCMbj7/kdWF9Q+bbckjBHLtHMEoJWlkmYzzdwhYMkjkOwubLM6t7NbWKjgKamGDrWL1++KrjUO1t9oAQ==}
engines: {node: '>=18'}
supports-color@7.2.0:
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
engines: {node: '>=8'}
@ -3329,6 +3391,9 @@ packages:
peerDependencies:
browserslist: '>= 4.21.0'
uri-js-replace@1.0.1:
resolution: {integrity: sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==}
uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
@ -3488,11 +3553,18 @@ packages:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'}
yaml-ast-parser@0.0.43:
resolution: {integrity: sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==}
yaml@2.7.1:
resolution: {integrity: sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==}
engines: {node: '>= 14'}
hasBin: true
yargs-parser@21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
engines: {node: '>=12'}
yocto-queue@0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
@ -3693,7 +3765,7 @@ snapshots:
'@eslint/config-array@0.20.0':
dependencies:
'@eslint/object-schema': 2.1.6
debug: 4.4.1
debug: 4.4.1(supports-color@10.0.0)
minimatch: 3.1.2
transitivePeerDependencies:
- supports-color
@ -3707,7 +3779,7 @@ snapshots:
'@eslint/eslintrc@3.3.1':
dependencies:
ajv: 6.12.6
debug: 4.4.1
debug: 4.4.1(supports-color@10.0.0)
espree: 10.3.0
globals: 14.0.0
ignore: 5.3.2
@ -4122,6 +4194,29 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@redocly/ajv@8.11.2':
dependencies:
fast-deep-equal: 3.1.3
json-schema-traverse: 1.0.0
require-from-string: 2.0.2
uri-js-replace: 1.0.1
'@redocly/config@0.22.2': {}
'@redocly/openapi-core@1.34.3(supports-color@10.0.0)':
dependencies:
'@redocly/ajv': 8.11.2
'@redocly/config': 0.22.2
colorette: 1.4.0
https-proxy-agent: 7.0.6(supports-color@10.0.0)
js-levenshtein: 1.1.6
js-yaml: 4.1.0
minimatch: 5.1.6
pluralize: 8.0.0
yaml-ast-parser: 0.0.43
transitivePeerDependencies:
- supports-color
'@rollup/rollup-android-arm-eabi@4.40.0':
optional: true
@ -4318,7 +4413,7 @@ snapshots:
'@typescript-eslint/types': 8.31.0
'@typescript-eslint/typescript-estree': 8.31.0(typescript@5.8.3)
'@typescript-eslint/visitor-keys': 8.31.0
debug: 4.4.1
debug: 4.4.1(supports-color@10.0.0)
eslint: 9.26.0
typescript: 5.8.3
transitivePeerDependencies:
@ -4333,7 +4428,7 @@ snapshots:
dependencies:
'@typescript-eslint/typescript-estree': 8.31.0(typescript@5.8.3)
'@typescript-eslint/utils': 8.31.0(eslint@9.26.0)(typescript@5.8.3)
debug: 4.4.1
debug: 4.4.1(supports-color@10.0.0)
eslint: 9.26.0
ts-api-utils: 2.1.0(typescript@5.8.3)
typescript: 5.8.3
@ -4346,7 +4441,7 @@ snapshots:
dependencies:
'@typescript-eslint/types': 8.31.0
'@typescript-eslint/visitor-keys': 8.31.0
debug: 4.4.1
debug: 4.4.1(supports-color@10.0.0)
fast-glob: 3.3.3
is-glob: 4.0.3
minimatch: 9.0.5
@ -4435,6 +4530,8 @@ snapshots:
acorn@8.14.1: {}
agent-base@7.1.3: {}
ajv@6.12.6:
dependencies:
fast-deep-equal: 3.1.3
@ -4442,6 +4539,8 @@ snapshots:
json-schema-traverse: 0.4.1
uri-js: 4.4.1
ansi-colors@4.1.3: {}
ansi-escapes@7.0.0:
dependencies:
environment: 1.1.0
@ -4549,7 +4648,7 @@ snapshots:
dependencies:
bytes: 3.1.2
content-type: 1.0.5
debug: 4.4.1
debug: 4.4.1(supports-color@10.0.0)
http-errors: 2.0.0
iconv-lite: 0.6.3
on-finished: 2.4.1
@ -4630,6 +4729,8 @@ snapshots:
chalk@5.4.1: {}
change-case@5.4.4: {}
check-error@2.1.1: {}
chokidar@4.0.3:
@ -4659,6 +4760,8 @@ snapshots:
color-name@1.1.4: {}
colorette@1.4.0: {}
colorette@2.0.20: {}
commander@13.1.0: {}
@ -4722,9 +4825,11 @@ snapshots:
dependencies:
ms: 2.1.3
debug@4.4.1:
debug@4.4.1(supports-color@10.0.0):
dependencies:
ms: 2.1.3
optionalDependencies:
supports-color: 10.0.0
decircular@0.1.1: {}
@ -4911,7 +5016,7 @@ snapshots:
esbuild-register@3.6.0(esbuild@0.25.4):
dependencies:
debug: 4.4.1
debug: 4.4.1(supports-color@10.0.0)
esbuild: 0.25.4
transitivePeerDependencies:
- supports-color
@ -5149,7 +5254,7 @@ snapshots:
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.6
debug: 4.4.1
debug: 4.4.1(supports-color@10.0.0)
escape-string-regexp: 4.0.0
eslint-scope: 8.3.0
eslint-visitor-keys: 4.2.0
@ -5224,7 +5329,7 @@ snapshots:
content-type: 1.0.5
cookie: 0.7.2
cookie-signature: 1.2.2
debug: 4.4.1
debug: 4.4.1(supports-color@10.0.0)
encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
@ -5280,7 +5385,7 @@ snapshots:
finalhandler@2.1.0:
dependencies:
debug: 4.4.1
debug: 4.4.1(supports-color@10.0.0)
encodeurl: 2.0.0
escape-html: 1.0.3
on-finished: 2.4.1
@ -5448,6 +5553,13 @@ snapshots:
statuses: 2.0.1
toidentifier: 1.0.1
https-proxy-agent@7.0.6(supports-color@10.0.0):
dependencies:
agent-base: 7.1.3
debug: 4.4.1(supports-color@10.0.0)
transitivePeerDependencies:
- supports-color
iconv-lite@0.6.3:
dependencies:
safer-buffer: 2.1.2
@ -5640,6 +5752,8 @@ snapshots:
joycon@3.1.1: {}
js-levenshtein@1.1.6: {}
js-tokens@4.0.0: {}
js-yaml@4.1.0:
@ -5656,6 +5770,8 @@ snapshots:
json-schema-traverse@0.4.1: {}
json-schema-traverse@1.0.0: {}
json-stable-stringify-without-jsonify@1.0.1: {}
json5@1.0.2:
@ -5716,7 +5832,7 @@ snapshots:
dependencies:
chalk: 5.4.1
commander: 13.1.0
debug: 4.4.1
debug: 4.4.1(supports-color@10.0.0)
lilconfig: 3.1.3
listr2: 8.3.3
micromatch: 4.0.8
@ -5815,6 +5931,10 @@ snapshots:
dependencies:
brace-expansion: 1.1.11
minimatch@5.1.6:
dependencies:
brace-expansion: 2.0.1
minimatch@9.0.5:
dependencies:
brace-expansion: 2.0.1
@ -5920,6 +6040,16 @@ snapshots:
dependencies:
which-pm-runs: 1.1.0
openapi-typescript@7.8.0(typescript@5.8.3):
dependencies:
'@redocly/openapi-core': 1.34.3(supports-color@10.0.0)
ansi-colors: 4.1.3
change-case: 5.4.4
parse-json: 8.3.0
supports-color: 10.0.0
typescript: 5.8.3
yargs-parser: 21.1.1
openapi3-ts@4.4.0:
dependencies:
yaml: 2.7.1
@ -6125,9 +6255,11 @@ snapshots:
dependencies:
jsesc: 3.0.2
require-from-string@2.0.2: {}
require-in-the-middle@7.5.2:
dependencies:
debug: 4.4.1
debug: 4.4.1(supports-color@10.0.0)
module-details-from-path: 1.0.4
resolve: 1.22.10
transitivePeerDependencies:
@ -6190,7 +6322,7 @@ snapshots:
router@2.2.0:
dependencies:
debug: 4.4.1
debug: 4.4.1(supports-color@10.0.0)
depd: 2.0.0
is-promise: 4.0.0
parseurl: 1.3.3
@ -6235,7 +6367,7 @@ snapshots:
send@1.2.0:
dependencies:
debug: 4.4.1
debug: 4.4.1(supports-color@10.0.0)
encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
@ -6477,6 +6609,8 @@ snapshots:
pirates: 4.0.7
ts-interface-checker: 0.1.13
supports-color@10.0.0: {}
supports-color@7.2.0:
dependencies:
has-flag: 4.0.0
@ -6547,7 +6681,7 @@ snapshots:
cac: 6.7.14
chokidar: 4.0.3
consola: 3.4.2
debug: 4.4.1
debug: 4.4.1(supports-color@10.0.0)
esbuild: 0.25.4
joycon: 3.1.1
picocolors: 1.1.1
@ -6680,6 +6814,8 @@ snapshots:
escalade: 3.2.0
picocolors: 1.1.1
uri-js-replace@1.0.1: {}
uri-js@4.4.1:
dependencies:
punycode: 2.3.1
@ -6696,7 +6832,7 @@ snapshots:
vite-node@3.1.3(@types/node@22.15.18)(tsx@4.19.4)(yaml@2.7.1):
dependencies:
cac: 6.7.14
debug: 4.4.1
debug: 4.4.1(supports-color@10.0.0)
es-module-lexer: 1.7.0
pathe: 2.0.3
vite: 6.3.3(@types/node@22.15.18)(tsx@4.19.4)(yaml@2.7.1)
@ -6749,7 +6885,7 @@ snapshots:
'@vitest/spy': 3.1.3
'@vitest/utils': 3.1.3
chai: 5.2.0
debug: 4.4.1
debug: 4.4.1(supports-color@10.0.0)
expect-type: 1.2.1
magic-string: 0.30.17
pathe: 2.0.3
@ -6866,8 +7002,12 @@ snapshots:
xtend@4.0.2: {}
yaml-ast-parser@0.0.43: {}
yaml@2.7.1: {}
yargs-parser@21.1.1: {}
yocto-queue@0.1.0: {}
zod-to-json-schema@3.24.5(zod@3.24.4):