From 974ba88a2febcfcac3a967085094186467ab9433 Mon Sep 17 00:00:00 2001 From: Michael Nahkies Date: Wed, 31 Dec 2025 18:51:25 +0000 Subject: [PATCH 1/5] feat: add discriminator to IRUnion --- e2e/openapi.yaml | 50 +++ e2e/src/generated/client/axios/client.ts | 28 ++ e2e/src/generated/client/axios/models.ts | 14 + e2e/src/generated/client/axios/schemas.ts | 14 + e2e/src/generated/client/fetch/client.ts | 25 ++ e2e/src/generated/client/fetch/models.ts | 14 + e2e/src/generated/client/fetch/schemas.ts | 14 + e2e/src/generated/server/express/models.ts | 14 + .../server/express/routes/validation.ts | 64 ++++ e2e/src/generated/server/express/schemas.ts | 14 + e2e/src/generated/server/koa/models.ts | 14 + .../generated/server/koa/routes/validation.ts | 54 ++++ e2e/src/generated/server/koa/schemas.ts | 14 + e2e/src/index.axios.spec.ts | 38 +++ e2e/src/index.fetch.spec.ts | 32 ++ e2e/src/routes/express/validation.ts | 21 ++ e2e/src/routes/koa/validation.ts | 21 ++ .../api.github.com.yaml/generated.ts | 15 +- .../api.github.com.yaml/generated.ts | 15 +- .../src/app/overview/compatibility/page.mdx | 72 ++--- .../openapi-code-generator/src/core/input.ts | 2 +- .../parameter-normalizer.spec.ts | 15 +- .../normalization/schema-normalizer.spec.ts | 303 +++++++++++++++++- .../core/normalization/schema-normalizer.ts | 80 ++++- .../src/core/openapi-types-normalized.ts | 11 + .../src/core/openapi-types.ts | 3 +- .../src/test/ir-model.fixtures.test-utils.ts | 2 +- .../abstract-schema-builder.ts | 20 +- .../schema-builders/joi-schema-builder.ts | 7 + .../schema-builders/zod-v3-schema-builder.ts | 16 + .../schema-builders/zod-v4-schema-builder.ts | 16 + .../zod-v4-schema-builder.unit.spec.ts | 59 ++++ 32 files changed, 1023 insertions(+), 58 deletions(-) diff --git a/e2e/openapi.yaml b/e2e/openapi.yaml index 074526092..e7b3864c6 100644 --- a/e2e/openapi.yaml +++ b/e2e/openapi.yaml @@ -289,6 +289,22 @@ paths: type: string 204: description: ok + /validation/objects/discriminated-union: + post: + tags: + - validation + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Animal' + responses: + 200: + description: ok + content: + application/json: + schema: + $ref: '#/components/schemas/Animal' /responses/500: get: @@ -470,6 +486,40 @@ components: typedHeaders: {} schemas: + Cat: + type: object + required: + - type + properties: + name: + type: string + type: + type: string + enum: ['cat'] + lives: + type: number + Dog: + type: object + required: + - type + properties: + name: + type: string + type: + type: string + enum: ['dog'] + sticks: + type: number + Animal: + type: object + oneOf: + - $ref: '#/components/schemas/Cat' + - $ref: '#/components/schemas/Dog' + discriminator: + propertyName: type + mapping: + cat: '#/components/schemas/Cat' + dog: '#/components/schemas/Dog' Enumerations: type: object required: diff --git a/e2e/src/generated/client/axios/client.ts b/e2e/src/generated/client/axios/client.ts index b823bd6b5..89f81898a 100644 --- a/e2e/src/generated/client/axios/client.ts +++ b/e2e/src/generated/client/axios/client.ts @@ -10,6 +10,7 @@ import { import type {AxiosRequestConfig, AxiosResponse} from "axios" import {z} from "zod/v4" import type { + t_Animal, t_Enumerations, t_GetHeadersRequest200Response, t_GetHeadersUndeclared200Response, @@ -26,6 +27,7 @@ import type { UnknownEnumStringValue, } from "./models.ts" import { + s_Animal, s_Enumerations, s_GetHeadersRequest200Response, s_GetHeadersUndeclared200Response, @@ -368,6 +370,32 @@ export class E2ETestClient extends AbstractAxiosClient { } } + async postValidationObjectsDiscriminatedUnion( + p: { + requestBody: t_Animal + }, + timeout?: number, + opts: AxiosRequestConfig = {}, + ): Promise> { + const url = `/validation/objects/discriminated-union` + const headers = this._headers( + {Accept: "application/json", "Content-Type": "application/json"}, + opts.headers, + ) + const body = JSON.stringify(p.requestBody) + + const res = await this._request({ + url: url, + method: "POST", + data: body, + ...(timeout ? {timeout} : {}), + ...opts, + headers, + }) + + return {...res, data: s_Animal.parse(res.data)} + } + async getResponses500( timeout?: number, opts: AxiosRequestConfig = {}, diff --git a/e2e/src/generated/client/axios/models.ts b/e2e/src/generated/client/axios/models.ts index 81e768a06..8f5780af3 100644 --- a/e2e/src/generated/client/axios/models.ts +++ b/e2e/src/generated/client/axios/models.ts @@ -10,6 +10,20 @@ export type UnknownEnumStringValue = string & { _brand: "unknown enum string value" } +export type t_Animal = t_Cat | t_Dog + +export type t_Cat = { + lives?: number | undefined + name?: string | undefined + type: "cat" +} + +export type t_Dog = { + name?: string | undefined + sticks?: number | undefined + type: "dog" +} + export type t_Enumerations = { colors: "red" | "green" | "blue" | UnknownEnumStringValue starRatings: 1 | 2 | 3 | UnknownEnumNumberValue diff --git a/e2e/src/generated/client/axios/schemas.ts b/e2e/src/generated/client/axios/schemas.ts index 128eb3395..3b0d235f5 100644 --- a/e2e/src/generated/client/axios/schemas.ts +++ b/e2e/src/generated/client/axios/schemas.ts @@ -5,6 +5,18 @@ import {z} from "zod/v4" import type {UnknownEnumNumberValue, UnknownEnumStringValue} from "./models.ts" +export const s_Cat = z.object({ + name: z.string().optional(), + type: z.literal("cat"), + lives: z.coerce.number().optional(), +}) + +export const s_Dog = z.object({ + name: z.string().optional(), + type: z.literal("dog"), + sticks: z.coerce.number().optional(), +}) + export const s_Enumerations = z.object({ colors: z.union([ z.enum(["red", "green", "blue"]), @@ -37,6 +49,8 @@ export const s_RandomNumber = z.object({ .optional(), }) +export const s_Animal = z.discriminatedUnion("type", [s_Cat, s_Dog]) + export const s_GetHeadersUndeclared200Response = z.object({ rawHeaders: z.record(z.string(), z.unknown()).optional(), typedHeaders: z.unknown().optional(), diff --git a/e2e/src/generated/client/fetch/client.ts b/e2e/src/generated/client/fetch/client.ts index f56d114d2..d39c7366d 100644 --- a/e2e/src/generated/client/fetch/client.ts +++ b/e2e/src/generated/client/fetch/client.ts @@ -12,6 +12,7 @@ import { import {responseValidationFactory} from "@nahkies/typescript-fetch-runtime/zod-v4" import {z} from "zod/v4" import type { + t_Animal, t_Enumerations, t_GetHeadersRequest200Response, t_GetHeadersUndeclared200Response, @@ -29,6 +30,7 @@ import type { UnknownEnumStringValue, } from "./models.ts" import { + s_Animal, s_Enumerations, s_GetHeadersRequest200Response, s_GetHeadersUndeclared200Response, @@ -359,6 +361,29 @@ export class E2ETestClient extends AbstractFetchClient { )(res) } + async postValidationObjectsDiscriminatedUnion( + p: { + requestBody: t_Animal + }, + timeout?: number, + opts: RequestInit = {}, + ): Promise> { + const url = this.basePath + `/validation/objects/discriminated-union` + const headers = this._headers( + {Accept: "application/json", "Content-Type": "application/json"}, + opts.headers, + ) + const body = JSON.stringify(p.requestBody) + + const res = this._fetch( + url, + {method: "POST", body, ...opts, headers}, + timeout, + ) + + return responseValidationFactory([["200", s_Animal]], undefined)(res) + } + async getResponses500( timeout?: number, opts: RequestInit = {}, diff --git a/e2e/src/generated/client/fetch/models.ts b/e2e/src/generated/client/fetch/models.ts index 81e768a06..8f5780af3 100644 --- a/e2e/src/generated/client/fetch/models.ts +++ b/e2e/src/generated/client/fetch/models.ts @@ -10,6 +10,20 @@ export type UnknownEnumStringValue = string & { _brand: "unknown enum string value" } +export type t_Animal = t_Cat | t_Dog + +export type t_Cat = { + lives?: number | undefined + name?: string | undefined + type: "cat" +} + +export type t_Dog = { + name?: string | undefined + sticks?: number | undefined + type: "dog" +} + export type t_Enumerations = { colors: "red" | "green" | "blue" | UnknownEnumStringValue starRatings: 1 | 2 | 3 | UnknownEnumNumberValue diff --git a/e2e/src/generated/client/fetch/schemas.ts b/e2e/src/generated/client/fetch/schemas.ts index 128eb3395..3b0d235f5 100644 --- a/e2e/src/generated/client/fetch/schemas.ts +++ b/e2e/src/generated/client/fetch/schemas.ts @@ -5,6 +5,18 @@ import {z} from "zod/v4" import type {UnknownEnumNumberValue, UnknownEnumStringValue} from "./models.ts" +export const s_Cat = z.object({ + name: z.string().optional(), + type: z.literal("cat"), + lives: z.coerce.number().optional(), +}) + +export const s_Dog = z.object({ + name: z.string().optional(), + type: z.literal("dog"), + sticks: z.coerce.number().optional(), +}) + export const s_Enumerations = z.object({ colors: z.union([ z.enum(["red", "green", "blue"]), @@ -37,6 +49,8 @@ export const s_RandomNumber = z.object({ .optional(), }) +export const s_Animal = z.discriminatedUnion("type", [s_Cat, s_Dog]) + export const s_GetHeadersUndeclared200Response = z.object({ rawHeaders: z.record(z.string(), z.unknown()).optional(), typedHeaders: z.unknown().optional(), diff --git a/e2e/src/generated/server/express/models.ts b/e2e/src/generated/server/express/models.ts index d7de2d805..162f511e8 100644 --- a/e2e/src/generated/server/express/models.ts +++ b/e2e/src/generated/server/express/models.ts @@ -2,6 +2,20 @@ /* tslint:disable */ /* eslint-disable */ +export type t_Animal = t_Cat | t_Dog + +export type t_Cat = { + lives?: number | undefined + name?: string | undefined + type: "cat" +} + +export type t_Dog = { + name?: string | undefined + sticks?: number | undefined + type: "dog" +} + export type t_Enumerations = { colors: "red" | "green" | "blue" starRatings: 1 | 2 | 3 diff --git a/e2e/src/generated/server/express/routes/validation.ts b/e2e/src/generated/server/express/routes/validation.ts index 6af33fa99..f3481e0c0 100644 --- a/e2e/src/generated/server/express/routes/validation.ts +++ b/e2e/src/generated/server/express/routes/validation.ts @@ -25,6 +25,7 @@ import { } from "express" import {z} from "zod/v4" import type { + t_Animal, t_Enumerations, t_GetResponsesDefault200Response, t_GetResponsesDefaultdefaultResponse, @@ -35,6 +36,7 @@ import type { t_RandomNumber, } from "../models.ts" import { + s_Animal, s_Enumerations, s_GetResponsesDefault200Response, s_GetResponsesDefaultdefaultResponse, @@ -90,6 +92,18 @@ export type PostValidationOptionalBody = ( next: NextFunction, ) => Promise | typeof SkipResponse> +export type PostValidationObjectsDiscriminatedUnionResponder = { + with200(): ExpressRuntimeResponse +} & ExpressRuntimeResponder + +export type PostValidationObjectsDiscriminatedUnion = ( + params: Params, + respond: PostValidationObjectsDiscriminatedUnionResponder, + req: Request, + res: Response, + next: NextFunction, +) => Promise | typeof SkipResponse> + export type GetResponses500Responder = { with500(): ExpressRuntimeResponse } & ExpressRuntimeResponder @@ -133,6 +147,7 @@ export type ValidationImplementation = { getValidationNumbersRandomNumber: GetValidationNumbersRandomNumber postValidationEnums: PostValidationEnums postValidationOptionalBody: PostValidationOptionalBody + postValidationObjectsDiscriminatedUnion: PostValidationObjectsDiscriminatedUnion getResponses500: GetResponses500 getResponsesDefault: GetResponsesDefault getResponsesEmpty: GetResponsesEmpty @@ -296,6 +311,55 @@ export function createValidationRouter( }, ) + const postValidationObjectsDiscriminatedUnionResponseBodyValidator = + responseValidationFactory([["200", s_Animal]], undefined) + + // postValidationObjectsDiscriminatedUnion + router.post( + `/validation/objects/discriminated-union`, + async (req: Request, res: Response, next: NextFunction) => { + try { + const input = { + params: undefined, + query: undefined, + body: parseRequestInput( + s_Animal, + req.body, + RequestInputType.RequestBody, + ), + headers: undefined, + } + + const responder = { + with200() { + return new ExpressRuntimeResponse(200) + }, + withStatus(status: StatusCode) { + return new ExpressRuntimeResponse(status) + }, + } + + await implementation + .postValidationObjectsDiscriminatedUnion( + input, + responder, + req, + res, + next, + ) + .catch(handleImplementationError) + .then( + handleResponse( + res, + postValidationObjectsDiscriminatedUnionResponseBodyValidator, + ), + ) + } catch (error) { + next(error) + } + }, + ) + const getResponses500ResponseBodyValidator = responseValidationFactory( [["500", z.undefined()]], undefined, diff --git a/e2e/src/generated/server/express/schemas.ts b/e2e/src/generated/server/express/schemas.ts index 9cd503099..e38a46b50 100644 --- a/e2e/src/generated/server/express/schemas.ts +++ b/e2e/src/generated/server/express/schemas.ts @@ -13,6 +13,18 @@ export const PermissiveBoolean = z.preprocess((value) => { return value }, z.boolean()) +export const s_Cat = z.object({ + name: z.string().optional(), + type: z.literal("cat"), + lives: z.coerce.number().optional(), +}) + +export const s_Dog = z.object({ + name: z.string().optional(), + type: z.literal("dog"), + sticks: z.coerce.number().optional(), +}) + export const s_Enumerations = z.object({ colors: z.enum(["red", "green", "blue"]), starRatings: z.union([z.literal(1), z.literal(2), z.literal(3)]), @@ -37,6 +49,8 @@ export const s_RandomNumber = z.object({ .optional(), }) +export const s_Animal = z.discriminatedUnion("type", [s_Cat, s_Dog]) + export const s_GetHeadersUndeclared200Response = z.object({ rawHeaders: z.record(z.string(), z.unknown()).optional(), typedHeaders: z.unknown().optional(), diff --git a/e2e/src/generated/server/koa/models.ts b/e2e/src/generated/server/koa/models.ts index d7de2d805..162f511e8 100644 --- a/e2e/src/generated/server/koa/models.ts +++ b/e2e/src/generated/server/koa/models.ts @@ -2,6 +2,20 @@ /* tslint:disable */ /* eslint-disable */ +export type t_Animal = t_Cat | t_Dog + +export type t_Cat = { + lives?: number | undefined + name?: string | undefined + type: "cat" +} + +export type t_Dog = { + name?: string | undefined + sticks?: number | undefined + type: "dog" +} + export type t_Enumerations = { colors: "red" | "green" | "blue" starRatings: 1 | 2 | 3 diff --git a/e2e/src/generated/server/koa/routes/validation.ts b/e2e/src/generated/server/koa/routes/validation.ts index bf7ab72db..2ac7a1f4d 100644 --- a/e2e/src/generated/server/koa/routes/validation.ts +++ b/e2e/src/generated/server/koa/routes/validation.ts @@ -20,6 +20,7 @@ import { } from "@nahkies/typescript-koa-runtime/zod-v4" import {z} from "zod/v4" import type { + t_Animal, t_Enumerations, t_GetResponsesDefault200Response, t_GetResponsesDefaultdefaultResponse, @@ -30,6 +31,7 @@ import type { t_RandomNumber, } from "../models.ts" import { + s_Animal, s_Enumerations, s_GetResponsesDefault200Response, s_GetResponsesDefaultdefaultResponse, @@ -88,6 +90,18 @@ export type PostValidationOptionalBody = ( | typeof SkipResponse > +export type PostValidationObjectsDiscriminatedUnionResponder = { + with200(): KoaRuntimeResponse +} & KoaRuntimeResponder + +export type PostValidationObjectsDiscriminatedUnion = ( + params: Params, + respond: PostValidationObjectsDiscriminatedUnionResponder, + ctx: RouterContext, +) => Promise< + KoaRuntimeResponse | Res<200, t_Animal> | typeof SkipResponse +> + export type GetResponses500Responder = { with500(): KoaRuntimeResponse } & KoaRuntimeResponder @@ -130,6 +144,7 @@ export type ValidationImplementation = { getValidationNumbersRandomNumber: GetValidationNumbersRandomNumber postValidationEnums: PostValidationEnums postValidationOptionalBody: PostValidationOptionalBody + postValidationObjectsDiscriminatedUnion: PostValidationObjectsDiscriminatedUnion getResponses500: GetResponses500 getResponsesDefault: GetResponsesDefault getResponsesEmpty: GetResponsesEmpty @@ -271,6 +286,45 @@ export function createValidationRouter( }, ) + const postValidationObjectsDiscriminatedUnionResponseValidator = + responseValidationFactory([["200", s_Animal]], undefined) + + router.post( + "postValidationObjectsDiscriminatedUnion", + "/validation/objects/discriminated-union", + async (ctx) => { + const input = { + params: undefined, + query: undefined, + body: parseRequestInput( + s_Animal, + Reflect.get(ctx.request, "body"), + RequestInputType.RequestBody, + ), + headers: undefined, + } + + const responder = { + with200() { + return new KoaRuntimeResponse(200) + }, + withStatus(status: StatusCode) { + return new KoaRuntimeResponse(status) + }, + } + + await implementation + .postValidationObjectsDiscriminatedUnion(input, responder, ctx) + .catch(handleImplementationError) + .then( + handleResponse( + ctx, + postValidationObjectsDiscriminatedUnionResponseValidator, + ), + ) + }, + ) + const getResponses500ResponseValidator = responseValidationFactory( [["500", z.undefined()]], undefined, diff --git a/e2e/src/generated/server/koa/schemas.ts b/e2e/src/generated/server/koa/schemas.ts index 9cd503099..e38a46b50 100644 --- a/e2e/src/generated/server/koa/schemas.ts +++ b/e2e/src/generated/server/koa/schemas.ts @@ -13,6 +13,18 @@ export const PermissiveBoolean = z.preprocess((value) => { return value }, z.boolean()) +export const s_Cat = z.object({ + name: z.string().optional(), + type: z.literal("cat"), + lives: z.coerce.number().optional(), +}) + +export const s_Dog = z.object({ + name: z.string().optional(), + type: z.literal("dog"), + sticks: z.coerce.number().optional(), +}) + export const s_Enumerations = z.object({ colors: z.enum(["red", "green", "blue"]), starRatings: z.union([z.literal(1), z.literal(2), z.literal(3)]), @@ -37,6 +49,8 @@ export const s_RandomNumber = z.object({ .optional(), }) +export const s_Animal = z.discriminatedUnion("type", [s_Cat, s_Dog]) + export const s_GetHeadersUndeclared200Response = z.object({ rawHeaders: z.record(z.string(), z.unknown()).optional(), typedHeaders: z.unknown().optional(), diff --git a/e2e/src/index.axios.spec.ts b/e2e/src/index.axios.spec.ts index 34a8fa619..b81c8a44a 100644 --- a/e2e/src/index.axios.spec.ts +++ b/e2e/src/index.axios.spec.ts @@ -364,6 +364,44 @@ describe.each( }) }) + describe("POST /validation/objects/discriminated-union", () => { + it("can post a cat", async () => { + const cat = { + type: "cat" as const, + name: "Felix", + lives: 9, + } + + const res = await client.postValidationObjectsDiscriminatedUnion({ + requestBody: cat, + }) + + expect(res.status).toBe(200) + expect(res.data).toStrictEqual({ + ...cat, + type: "cat", + }) + }) + + it("can post a dog", async () => { + const dog = { + type: "dog" as const, + name: "Rex", + sticks: 5, + } + + const res = await client.postValidationObjectsDiscriminatedUnion({ + requestBody: dog, + }) + + expect(res.status).toBe(200) + expect(res.data).toStrictEqual({ + ...dog, + type: "dog", + }) + }) + }) + describe("GET /responses/empty", () => { it("returns undefined", async () => { const {status, data} = await client.getResponsesEmpty() diff --git a/e2e/src/index.fetch.spec.ts b/e2e/src/index.fetch.spec.ts index aac792db3..1702ddb4e 100644 --- a/e2e/src/index.fetch.spec.ts +++ b/e2e/src/index.fetch.spec.ts @@ -381,6 +381,38 @@ describe.each( }) }) + describe("POST /validation/objects/discriminated-union", () => { + it("can post a cat", async () => { + const cat = { + type: "cat" as const, + name: "Felix", + lives: 9, + } + + const res = await client.postValidationObjectsDiscriminatedUnion({ + requestBody: cat, + }) + + expect(res.status).toBe(200) + await expect(res.json()).resolves.toStrictEqual(cat) + }) + + it("can post a dog", async () => { + const dog = { + type: "dog" as const, + name: "Rex", + sticks: 5, + } + + const res = await client.postValidationObjectsDiscriminatedUnion({ + requestBody: dog, + }) + + expect(res.status).toBe(200) + await expect(res.json()).resolves.toStrictEqual(dog) + }) + }) + describe("GET /responses/empty", () => { it("returns undefined", async () => { const res = await client.getResponsesEmpty() diff --git a/e2e/src/routes/express/validation.ts b/e2e/src/routes/express/validation.ts index 06081fd04..300251571 100644 --- a/e2e/src/routes/express/validation.ts +++ b/e2e/src/routes/express/validation.ts @@ -5,6 +5,7 @@ import { type GetResponsesEmpty, type GetValidationNumbersRandomNumber, type PostValidationEnums, + type PostValidationObjectsDiscriminatedUnion, type PostValidationOptionalBody, } from "../../generated/server/express/routes/validation.ts" @@ -23,6 +24,25 @@ const postValidationOptionalBody: PostValidationOptionalBody = async ( } } +const postValidationObjectsDiscriminatedUnion: PostValidationObjectsDiscriminatedUnion = + async ({body}, respond) => { + if (body.type === "cat") { + return respond.with200().body({ + name: body.name, + type: body.type, + lives: body.lives, + }) + } else if (body.type === "dog") { + return respond.with200().body({ + name: body.name, + type: body.type, + sticks: body.sticks, + }) + } + + return respond.withStatus(404) + } + const getValidationNumbersRandomNumber: GetValidationNumbersRandomNumber = async ({query}, respond) => { const max = query.max ?? 10 @@ -72,6 +92,7 @@ export function createValidationRouter() { return createRouter({ postValidationEnums, postValidationOptionalBody, + postValidationObjectsDiscriminatedUnion, getValidationNumbersRandomNumber, getResponsesEmpty, getResponsesDefault, diff --git a/e2e/src/routes/koa/validation.ts b/e2e/src/routes/koa/validation.ts index da34d63b5..a1416564a 100644 --- a/e2e/src/routes/koa/validation.ts +++ b/e2e/src/routes/koa/validation.ts @@ -5,6 +5,7 @@ import { type GetResponsesEmpty, type GetValidationNumbersRandomNumber, type PostValidationEnums, + type PostValidationObjectsDiscriminatedUnion, type PostValidationOptionalBody, } from "../../generated/server/koa/routes/validation.ts" @@ -23,6 +24,25 @@ const postValidationOptionalBody: PostValidationOptionalBody = async ( } } +const postValidationObjectsDiscriminatedUnion: PostValidationObjectsDiscriminatedUnion = + async ({body}, respond) => { + if (body.type === "cat") { + return respond.with200().body({ + name: body.name, + type: body.type, + lives: body.lives, + }) + } else if (body.type === "dog") { + return respond.with200().body({ + name: body.name, + type: body.type, + sticks: body.sticks, + }) + } + + return respond.withStatus(404) + } + const getValidationNumbersRandomNumber: GetValidationNumbersRandomNumber = async ({query}, respond) => { const max = query.max ?? 10 @@ -74,6 +94,7 @@ export function createValidationRouter() { return createRouter({ postValidationEnums, postValidationOptionalBody, + postValidationObjectsDiscriminatedUnion, getValidationNumbersRandomNumber, getResponsesEmpty, getResponsesDefault, diff --git a/integration-tests/typescript-express/src/generated/api.github.com.yaml/generated.ts b/integration-tests/typescript-express/src/generated/api.github.com.yaml/generated.ts index dd055b0af..db645f1a6 100644 --- a/integration-tests/typescript-express/src/generated/api.github.com.yaml/generated.ts +++ b/integration-tests/typescript-express/src/generated/api.github.com.yaml/generated.ts @@ -92814,7 +92814,10 @@ export function createRouter( const usersGetAuthenticatedResponseBodyValidator = responseValidationFactory( [ - ["200", z.union([s_private_user, s_public_user])], + [ + "200", + z.discriminatedUnion("user_view_type", [s_public_user, s_private_user]), + ], ["304", z.undefined()], ["401", s_basic_error], ["403", s_basic_error], @@ -99402,7 +99405,10 @@ export function createRouter( const usersGetByIdResponseBodyValidator = responseValidationFactory( [ - ["200", z.union([s_private_user, s_public_user])], + [ + "200", + z.discriminatedUnion("user_view_type", [s_public_user, s_private_user]), + ], ["404", s_basic_error], ], undefined, @@ -99656,7 +99662,10 @@ export function createRouter( const usersGetByUsernameResponseBodyValidator = responseValidationFactory( [ - ["200", z.union([s_private_user, s_public_user])], + [ + "200", + z.discriminatedUnion("user_view_type", [s_public_user, s_private_user]), + ], ["404", s_basic_error], ], undefined, diff --git a/integration-tests/typescript-koa/src/generated/api.github.com.yaml/generated.ts b/integration-tests/typescript-koa/src/generated/api.github.com.yaml/generated.ts index 4a39a75ce..a1ce00c43 100644 --- a/integration-tests/typescript-koa/src/generated/api.github.com.yaml/generated.ts +++ b/integration-tests/typescript-koa/src/generated/api.github.com.yaml/generated.ts @@ -91568,7 +91568,10 @@ export function createRouter( const usersGetAuthenticatedResponseValidator = responseValidationFactory( [ - ["200", z.union([s_private_user, s_public_user])], + [ + "200", + z.discriminatedUnion("user_view_type", [s_public_user, s_private_user]), + ], ["304", z.undefined()], ["401", s_basic_error], ["403", s_basic_error], @@ -97332,7 +97335,10 @@ export function createRouter( const usersGetByIdResponseValidator = responseValidationFactory( [ - ["200", z.union([s_private_user, s_public_user])], + [ + "200", + z.discriminatedUnion("user_view_type", [s_public_user, s_private_user]), + ], ["404", s_basic_error], ], undefined, @@ -97551,7 +97557,10 @@ export function createRouter( const usersGetByUsernameResponseValidator = responseValidationFactory( [ - ["200", z.union([s_private_user, s_public_user])], + [ + "200", + z.discriminatedUnion("user_view_type", [s_public_user, s_private_user]), + ], ["404", s_basic_error], ], undefined, diff --git a/packages/documentation/src/app/overview/compatibility/page.mdx b/packages/documentation/src/app/overview/compatibility/page.mdx index 094f1ed37..38e8f769b 100644 --- a/packages/documentation/src/app/overview/compatibility/page.mdx +++ b/packages/documentation/src/app/overview/compatibility/page.mdx @@ -244,42 +244,42 @@ openapi specification / json schema validation specifications. Most notable exception is `readOnly` / `writeOnly` which are currently ignored, planned to be addressed prior to v1. -| Attribute | Supported | Notes | -|:---------------------|:---------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------| -| title | __N/A__ | | -| multipleOf | ✅ | Applies to `type: number` | -| maximum | ✅ | Applies to `type: number` | -| exclusiveMaximum | ✅ | Applies to `type: number` | -| minimum | ✅ | Applies to `type: number` | -| exclusiveMinimum | ✅ | Applies to `type: number` | -| maxLength | ✅ | Applies to `type: string` | -| minLength | ✅ | Applies to `type: string` | -| pattern | ✅ | Support for `type: string` | -| maxItems | ✅ | Applies to `type: array` | -| minItems | ✅ | Applies to `type: array` | -| uniqueItems | ✅ | Applies to `type: array` | -| maxProperties | 🚫 | Not yet supported | -| minProperties | 🚫 | Not yet supported | -| required | ✅ | Controls whether `undefined` is allowed for each value in `properties` | -| enum | ✅ | Applies to `type: number`, `type: string` and `type: boolean` | -| type | ✅ | | -| not | 🚫 | Not yet supported | -| allOf | ✅ | Produces a intersection type like `A & B` | -| oneOf | ✅ | Produces a union type like `A \| B` | -| anyOf | ✅ | Produces a union type like `A \| B` | -| items | ✅ | Applies to `type: array` | -| properties | ✅ | Applies to `type: object` | -| additionalProperties | ✅ | Fairly comprehensive support, produces `Record` or `unknown`/`any` (dependent on [`--ts-allow-any`](../reference/cli-options#--ts-allow-any)) | -| format | ✅/🚧 | Limited support for format `email` and `date-time` | -| default | ✅ | | -| nullable | ✅ | Also supports `type: null` as an alternative | -| discriminator | 🚫 | Ignored. Union / Intersection types are usd based on `anyOf` / `allOf` / `oneOf`. | -| readOnly | 🚫 | Not yet supported | -| writeOnly | 🚫 | Not yet supported | -| example | __N/A__ | Ignored | -| externalDocs | __N/A__ | Ignored | -| deprecated | 🚫 | Not yet supported | -| xml | 🚫 | Not yet supported | +| Attribute | Supported | Notes | +|:---------------------|:---------:|:---------------------------------------------------------------------------------------------------------------------------| +| title | __N/A__ | | +| multipleOf | ✅ | Applies to `type: number` | +| maximum | ✅ | Applies to `type: number` | +| exclusiveMaximum | ✅ | Applies to `type: number` | +| minimum | ✅ | Applies to `type: number` | +| exclusiveMinimum | ✅ | Applies to `type: number` | +| maxLength | ✅ | Applies to `type: string` | +| minLength | ✅ | Applies to `type: string` | +| pattern | ✅ | Support for `type: string` | +| maxItems | ✅ | Applies to `type: array` | +| minItems | ✅ | Applies to `type: array` | +| uniqueItems | ✅ | Applies to `type: array` | +| maxProperties | 🚫 | Not yet supported | +| minProperties | 🚫 | Not yet supported | +| required | ✅ | Controls whether `undefined` is allowed for each value in `properties` | +| enum | ✅ | Applies to `type: number`, `type: string` and `type: boolean`. See also [enums guide](../guides/concepts/enums) | +| type | ✅ | | +| not | 🚫 | Not yet supported | +| allOf | ✅ | Produces a intersection type like `A & B` | +| oneOf | ✅ | Produces a union type like `A \| B` | +| anyOf | ✅ | Produces a union type like `A \| B` | +| items | ✅ | Applies to `type: array` | +| properties | ✅ | Applies to `type: object` | +| additionalProperties | ✅ | Produces `Record` or `unknown`/`any` (dependent on [`--ts-allow-any`](../reference/cli-options#--ts-allow-any)) | +| format | ✅/🚧 | Support for format `binary`, `email`, `date-time`, `date`, `time` | +| default | ✅ | | +| nullable | ✅ | Also supports `type: null` as an alternative | +| discriminator | ✅/🚧 | Well supported when union is using $ref. Ignored for in-line schemas. `defaultMapping` not yet supported. | +| readOnly | 🚫 | Not yet supported | +| writeOnly | 🚫 | Not yet supported | +| example | __N/A__ | Ignored | +| externalDocs | __N/A__ | Ignored | +| deprecated | 🚫 | Not yet supported | +| xml | 🚫 | Not yet supported | ### Encoding Object | Attribute | Supported | Notes | diff --git a/packages/openapi-code-generator/src/core/input.ts b/packages/openapi-code-generator/src/core/input.ts index 82b961ab4..b7d767458 100644 --- a/packages/openapi-code-generator/src/core/input.ts +++ b/packages/openapi-code-generator/src/core/input.ts @@ -48,7 +48,7 @@ export class Input implements ISchemaProvider { private loader: OpenapiLoader, readonly config: InputConfig, private readonly syntheticNameGenerator: SyntheticNameGenerator = defaultSyntheticNameGenerator, - private readonly schemaNormalizer = new SchemaNormalizer(config), + private readonly schemaNormalizer = new SchemaNormalizer(config, this), private readonly parameterNormalizer = new ParameterNormalizer( loader, schemaNormalizer, diff --git a/packages/openapi-code-generator/src/core/normalization/parameter-normalizer.spec.ts b/packages/openapi-code-generator/src/core/normalization/parameter-normalizer.spec.ts index 63fd4314a..a5a2f3552 100644 --- a/packages/openapi-code-generator/src/core/normalization/parameter-normalizer.spec.ts +++ b/packages/openapi-code-generator/src/core/normalization/parameter-normalizer.spec.ts @@ -1,4 +1,5 @@ import {beforeEach, describe, expect, it, jest} from "@jest/globals" +import {FakeSchemaProvider} from "../../test/fake-schema-provider.ts" import {irFixture as ir} from "../../test/ir-model.fixtures.test-utils.ts" import type {OpenapiLoader} from "../loaders/openapi-loader.ts" import type {Parameter} from "../openapi-types.ts" @@ -8,6 +9,7 @@ import {SchemaNormalizer} from "./schema-normalizer.ts" describe("ParameterNormalizer", () => { let loader: jest.Mocked + let fakeSchemaProvider: FakeSchemaProvider let schemaNormalizer: SchemaNormalizer let parameterNormalizer: ParameterNormalizer @@ -18,10 +20,15 @@ describe("ParameterNormalizer", () => { addVirtualType: jest.fn(), } as unknown as jest.Mocked - schemaNormalizer = new SchemaNormalizer({ - extractInlineSchemas: true, - enumExtensibility: "open", - }) + fakeSchemaProvider = new FakeSchemaProvider() + + schemaNormalizer = new SchemaNormalizer( + { + extractInlineSchemas: true, + enumExtensibility: "open", + }, + fakeSchemaProvider, + ) parameterNormalizer = new ParameterNormalizer( loader, diff --git a/packages/openapi-code-generator/src/core/normalization/schema-normalizer.spec.ts b/packages/openapi-code-generator/src/core/normalization/schema-normalizer.spec.ts index b7895a824..1f795c37f 100644 --- a/packages/openapi-code-generator/src/core/normalization/schema-normalizer.spec.ts +++ b/packages/openapi-code-generator/src/core/normalization/schema-normalizer.spec.ts @@ -1,12 +1,22 @@ -import {describe, expect, it} from "@jest/globals" +import {beforeEach, describe, expect, it} from "@jest/globals" +import {FakeSchemaProvider} from "../../test/fake-schema-provider.ts" import {irFixture as ir} from "../../test/ir-model.fixtures.test-utils.ts" import {generationLib} from "../generation-lib.ts" import {SchemaNormalizer} from "./schema-normalizer.ts" describe("core/input - SchemaNormalizer", () => { - const schemaNormalizer = new SchemaNormalizer({ - extractInlineSchemas: true, - enumExtensibility: "open", + let schemaProvider: FakeSchemaProvider + let schemaNormalizer: SchemaNormalizer + + beforeEach(() => { + schemaProvider = new FakeSchemaProvider() + schemaNormalizer = new SchemaNormalizer( + { + extractInlineSchemas: true, + enumExtensibility: "open", + }, + schemaProvider, + ) }) it("passes through $ref untouched", () => { @@ -632,6 +642,291 @@ describe("core/input - SchemaNormalizer", () => { }) }) + describe("discriminator", () => { + describe("all alternatives are $ref of type: object", () => { + it("supports mapping", () => { + schemaProvider.registerTestRef( + ir.ref("/components/schemas/Foo"), + ir.object({properties: {type: ir.string()}}), + ) + schemaProvider.registerTestRef( + ir.ref("/components/schemas/Bar"), + ir.object({properties: {type: ir.string()}}), + ) + + const actual = schemaNormalizer.normalize({ + type: "object", + discriminator: { + propertyName: "type", + mapping: { + foo: "#/components/schemas/Foo", + bar: "#/components/schemas/Bar", + }, + }, + oneOf: [ + {$ref: "#/components/schemas/Foo"}, + {$ref: "#/components/schemas/Bar"}, + ], + }) + + expect(actual).toStrictEqual( + ir.union({ + discriminator: { + propertyName: "type", + mapping: { + foo: ir.ref("/components/schemas/Foo"), + bar: ir.ref("/components/schemas/Bar"), + }, + }, + schemas: [ + ir.ref("/components/schemas/Foo"), + ir.ref("/components/schemas/Bar"), + ], + }), + ) + }) + + it("supports a defined path mapping", () => { + schemaProvider.registerTestRef( + ir.ref("/components/schemas/Foo", "/absolute/path.yaml"), + ir.object({properties: {type: ir.string()}}), + ) + schemaProvider.registerTestRef( + ir.ref("/components/schemas/Bar", "/absolute/path.yaml"), + ir.object({properties: {type: ir.string()}}), + ) + + const actual = schemaNormalizer.normalize({ + type: "object", + discriminator: { + propertyName: "type", + mapping: { + foo: "#/components/schemas/Foo", + bar: "#/components/schemas/Bar", + }, + }, + oneOf: [ + {$ref: "/absolute/path.yaml#/components/schemas/Foo"}, + {$ref: "/absolute/path.yaml#/components/schemas/Bar"}, + ], + }) + + expect(actual).toStrictEqual( + ir.union({ + discriminator: { + propertyName: "type", + mapping: { + foo: ir.ref("/components/schemas/Foo", "/absolute/path.yaml"), + bar: ir.ref("/components/schemas/Bar", "/absolute/path.yaml"), + }, + }, + schemas: [ + ir.ref("/components/schemas/Foo", "/absolute/path.yaml"), + ir.ref("/components/schemas/Bar", "/absolute/path.yaml"), + ], + }), + ) + }) + + // todo: normalize relative paths / uris properly here. + it.skip("supports a cross-file defined path mapping", () => { + schemaProvider.registerTestRef( + ir.ref("/components/schemas/Foo", "/absolute/path.yaml"), + ir.object({properties: {type: ir.string()}}), + ) + schemaProvider.registerTestRef( + ir.ref("/components/schemas/Bar", "/absolute/path.yaml"), + ir.object({properties: {type: ir.string()}}), + ) + + const actual = schemaNormalizer.normalize({ + type: "object", + discriminator: { + propertyName: "type", + mapping: { + foo: "./path.yaml#/components/schemas/Foo", + bar: "./path.yaml#/components/schemas/Bar", + }, + }, + oneOf: [ + {$ref: "/absolute/path.yaml#/components/schemas/Foo"}, + {$ref: "/absolute/path.yaml#/components/schemas/Bar"}, + ], + }) + + expect(actual).toStrictEqual( + ir.union({ + discriminator: { + propertyName: "type", + mapping: { + foo: ir.ref("/components/schemas/Foo", "/absolute/path.yaml"), + bar: ir.ref("/components/schemas/Bar", "/absolute/path.yaml"), + }, + }, + schemas: [ + ir.ref("/components/schemas/Foo", "/absolute/path.yaml"), + ir.ref("/components/schemas/Bar", "/absolute/path.yaml"), + ], + }), + ) + }) + + it("infers a mapping when none provided", () => { + schemaProvider.registerTestRef( + ir.ref("/components/schemas/Foo"), + ir.object({properties: {type: ir.string()}}), + ) + schemaProvider.registerTestRef( + ir.ref("/components/schemas/Bar"), + ir.object({properties: {type: ir.string()}}), + ) + + const actual = schemaNormalizer.normalize({ + type: "object", + discriminator: { + propertyName: "type", + }, + oneOf: [ + {$ref: "#/components/schemas/Foo"}, + {$ref: "#/components/schemas/Bar"}, + ], + }) + + expect(actual).toStrictEqual( + ir.union({ + discriminator: { + propertyName: "type", + mapping: { + Foo: ir.ref("/components/schemas/Foo"), + Bar: ir.ref("/components/schemas/Bar"), + }, + }, + schemas: [ + ir.ref("/components/schemas/Foo"), + ir.ref("/components/schemas/Bar"), + ], + }), + ) + }) + }) + + it("ignores the discriminator property where some alternatives are not type: object", () => {}) + + it("ignores the discriminator property where no composition is defined", () => { + const actual = schemaNormalizer.normalize({ + type: "object", + properties: { + name: {type: "string"}, + type: {type: "string"}, + }, + discriminator: { + propertyName: "type", + mapping: { + foo: "#/components/schemas/Foo", + bar: "#/components/schemas/Bar", + }, + }, + }) + + expect(actual).toStrictEqual( + ir.object({properties: {name: ir.string(), type: ir.string()}}), + ) + }) + + // todo: figure this out + it.skip("handles a discriminator altering the base object with in-line schemas", () => { + // example derived from POST /repos/{owner}/{repo}/check-runs + const actual = schemaNormalizer.normalize({ + type: "object", + properties: { + status: {type: "string", enum: ["success", "fail", "in-progress"]}, + completed_at: {type: "string", format: "date-time"}, + }, + oneOf: [ + { + type: "object", + properties: {status: {type: "string", enum: ["success", "fail"]}}, + required: ["completed_at"], + }, + { + type: "object", + properties: {status: {type: "string", enum: ["in-progress"]}}, + }, + ], + discriminator: { + propertyName: "status", + }, + }) + + expect(actual).toStrictEqual( + ir.union({ + schemas: [ + ir.object({ + properties: { + status: ir.string({enum: ["success", "fail"]}), + completed_at: ir.string({format: "date-time"}), + }, + required: ["completed_at"], + }), + ir.object({ + properties: { + status: ir.string({enum: ["in-progress"]}), + completed_at: ir.string({format: "date-time"}), + }, + }), + ], + discriminator: { + propertyName: "status", + mapping: { + success: ir.object({ + properties: { + status: ir.string({enum: ["success", "fail"]}), + completed_at: ir.string({format: "date-time"}), + }, + required: ["completed_at"], + }), + fail: ir.object({ + properties: { + status: ir.string({enum: ["success", "fail"]}), + completed_at: ir.string({format: "date-time"}), + }, + required: ["completed_at"], + }), + "in-progress": ir.object({ + properties: { + status: ir.string({enum: ["in-progress"]}), + completed_at: ir.string({format: "date-time"}), + }, + }), + }, + }, + }), + ) + }) + + it("ignores the discriminator property where some alternatives are inline schemas", () => { + const actual = schemaNormalizer.normalize({ + type: "object", + discriminator: { + propertyName: "type", + }, + oneOf: [ + {type: "object", properties: {type: {type: "string"}}}, + {$ref: "#/components/schemas/Bar"}, + ], + }) + + expect(actual).toStrictEqual( + ir.union({ + schemas: [ + ir.object({properties: {type: ir.string()}}), + ir.ref("/components/schemas/Bar"), + ], + }), + ) + }) + }) + describe("empty schemas / additionalProperties", () => { it("translates '{}' to an any", () => { const actual = schemaNormalizer.normalize({}) diff --git a/packages/openapi-code-generator/src/core/normalization/schema-normalizer.ts b/packages/openapi-code-generator/src/core/normalization/schema-normalizer.ts index d3de82dc1..9850b7710 100644 --- a/packages/openapi-code-generator/src/core/normalization/schema-normalizer.ts +++ b/packages/openapi-code-generator/src/core/normalization/schema-normalizer.ts @@ -1,8 +1,9 @@ import {isNonEmptyArray} from "@nahkies/typescript-common-runtime/types" import {generationLib} from "../generation-lib.ts" -import type {InputConfig} from "../input.ts" +import type {InputConfig, ISchemaProvider} from "../input.ts" import {logger} from "../logger.ts" import type { + Discriminator, Reference, Schema, SchemaNumber, @@ -24,10 +25,13 @@ import type { IRRef, MaybeIRModel, } from "../openapi-types-normalized.ts" -import {isRef} from "../openapi-utils.ts" +import {getRawNameFromRef, isRef} from "../openapi-utils.ts" export class SchemaNormalizer { - constructor(readonly config: InputConfig) {} + constructor( + private readonly config: InputConfig, + private readonly schemaProvider: ISchemaProvider, + ) {} public isNormalized(schema: Schema | IRModel): schema is IRModel { return schema && Reflect.get(schema, "isIRModel") @@ -201,7 +205,11 @@ export class SchemaNormalizer { {...base, nullable}, hasOwnProperties ? [...allOf, result] : allOf, ) - const maybeUnion = this.union({...base, nullable}, [...oneOf, ...anyOf]) + const maybeUnion = this.union( + {...base, nullable}, + [...oneOf, ...anyOf], + schemaObject.discriminator, + ) if (maybeIntersection && maybeUnion) { return this.intersection({...base, nullable}, [ @@ -383,6 +391,68 @@ export class SchemaNormalizer { } } + private normalizeDiscriminator( + discriminator: Discriminator | undefined, + schemas: MaybeIRModel[], + ): IRModelUnion["discriminator"] | undefined { + if (!discriminator) { + return undefined + } + + const referencedSchemas = schemas.filter((it) => isRef(it)) + + const includesInlineSchemas = referencedSchemas.length !== schemas.length + + if (includesInlineSchemas) { + logger.info( + `ignoring 'discriminator' over propertyName '${discriminator.propertyName}' as the union includes inline schemas`, + ) + return undefined + } + + // todo: infinite loop possibility? might make more sense to go to the loader. + const everyAlternativeIsObject = referencedSchemas.every( + (it) => this.schemaProvider.schema(it).type === "object", + ) + + if (!everyAlternativeIsObject) { + logger.info( + `ignoring 'discriminator' over propertyName '${discriminator.propertyName}' as the union references non-object schemas`, + ) + return undefined + } + + // todo: validate that the discriminated property is actually an enum? otherwise it can't be used. + // todo: also validate that the discriminated property is required? (avoid 'Duplicate discriminator value "undefined"') + + // note: mapping is optional, where the default is ${NAME} -> '#/components/schemas/${NAME}' + const mapping = discriminator.mapping + ? Object.fromEntries( + Object.entries(discriminator.mapping).map(([key, $ref]) => { + // schema-loader doesn't normalize these $ref, as they don't look like normal $ref propreties. + const normalized$ref = referencedSchemas.find((it) => + it.$ref.endsWith($ref), + ) + + if (!normalized$ref) { + throw new Error( + `discriminator mapping over propertyName '${discriminator.propertyName}' includes a reference that isn't part of the union.`, + ) + } + + return [key, normalized$ref] + }), + ) + : Object.fromEntries( + referencedSchemas.map((it) => [getRawNameFromRef(it), it]), + ) + + return { + propertyName: discriminator.propertyName, + mapping, + } + } + private normalizeComposition( items: (Schema | Reference)[] = [], parent: SchemaObject, @@ -551,6 +621,7 @@ export class SchemaNormalizer { private union( base: IRModelBase, schemas: MaybeIRModel[], + discriminator: Discriminator | undefined, ): MaybeIRModel | IRModelUnion | undefined { // (A|B)|(C|D) is the same as (A|B|C|D) // todo: merge repeated in-line schemas @@ -570,6 +641,7 @@ export class SchemaNormalizer { return { ...base, type: "union", + discriminator: this.normalizeDiscriminator(discriminator, schemas), schemas, } } diff --git a/packages/openapi-code-generator/src/core/openapi-types-normalized.ts b/packages/openapi-code-generator/src/core/openapi-types-normalized.ts index 57aafd8e7..4bf2891d3 100644 --- a/packages/openapi-code-generator/src/core/openapi-types-normalized.ts +++ b/packages/openapi-code-generator/src/core/openapi-types-normalized.ts @@ -79,6 +79,17 @@ export interface IRModelUnion extends IRModelBase { // of this. type: "union" schemas: NonEmptyArray + + discriminator?: + | { + propertyName: string + mapping: { + // todo: whilst the downstream schema generation supports IRModelObject, the normalizer ignores them and falls back to a union + [propertyValue: string]: IRRef | IRModelObject + } + //todo: support defaultMapping + } + | undefined } export interface IRModelObject extends IRModelBase { diff --git a/packages/openapi-code-generator/src/core/openapi-types.ts b/packages/openapi-code-generator/src/core/openapi-types.ts index ce61d838e..d97e97b91 100644 --- a/packages/openapi-code-generator/src/core/openapi-types.ts +++ b/packages/openapi-code-generator/src/core/openapi-types.ts @@ -359,8 +359,9 @@ export interface xInternalPreproccess { export interface Discriminator { propertyName: string mapping?: { - [k: string]: string + [propertyValue: string]: string } + defaultMapping?: string } export interface Example { diff --git a/packages/openapi-code-generator/src/test/ir-model.fixtures.test-utils.ts b/packages/openapi-code-generator/src/test/ir-model.fixtures.test-utils.ts index 9041414e3..651298e0b 100644 --- a/packages/openapi-code-generator/src/test/ir-model.fixtures.test-utils.ts +++ b/packages/openapi-code-generator/src/test/ir-model.fixtures.test-utils.ts @@ -115,6 +115,7 @@ const extension = { schemas: [base.any], nullable: false, default: undefined, + discriminator: undefined, "x-internal-preprocess": undefined, } satisfies IRModelUnion, null: { @@ -178,7 +179,6 @@ export const irFixture = { ref(path: string, file = ""): IRRef { return { $ref: `${file}#${path}`, - "x-internal-preprocess": undefined, } }, any(partial: Partial = {}): IRModelAny { diff --git a/packages/openapi-code-generator/src/typescript/common/schema-builders/abstract-schema-builder.ts b/packages/openapi-code-generator/src/typescript/common/schema-builders/abstract-schema-builder.ts index 26cf2f736..2ff0451f1 100644 --- a/packages/openapi-code-generator/src/typescript/common/schema-builders/abstract-schema-builder.ts +++ b/packages/openapi-code-generator/src/typescript/common/schema-builders/abstract-schema-builder.ts @@ -244,7 +244,20 @@ export abstract class AbstractSchemaBuilder< } case "union": { - result = this.union(model.schemas.map((it) => this.fromModel(it, true))) + if (model.discriminator) { + result = this.discriminatedUnion( + model.discriminator.propertyName, + Object.fromEntries( + Object.entries(model.discriminator.mapping).map( + ([value, ref]) => [value, this.fromModel(ref, true)], + ), + ), + ) + } else { + result = this.union( + model.schemas.map((it) => this.fromModel(it, true)), + ) + } break } @@ -354,6 +367,11 @@ export abstract class AbstractSchemaBuilder< protected abstract union(schemas: string[]): string + protected abstract discriminatedUnion( + propertyName: string, + mapping: Record, + ): string + protected abstract preprocess( schema: string, transformation: string | ((it: unknown) => unknown), diff --git a/packages/openapi-code-generator/src/typescript/common/schema-builders/joi-schema-builder.ts b/packages/openapi-code-generator/src/typescript/common/schema-builders/joi-schema-builder.ts index 7d76ecb66..7ba8ed4dd 100644 --- a/packages/openapi-code-generator/src/typescript/common/schema-builders/joi-schema-builder.ts +++ b/packages/openapi-code-generator/src/typescript/common/schema-builders/joi-schema-builder.ts @@ -157,6 +157,13 @@ export class JoiBuilder extends AbstractSchemaBuilder< .join(".") } + protected discriminatedUnion( + _propertyName: string, + mapping: Record, + ): string { + return this.union(Object.values(mapping)) + } + protected preprocess( schema: string, transformation: string | ((it: unknown) => unknown), diff --git a/packages/openapi-code-generator/src/typescript/common/schema-builders/zod-v3-schema-builder.ts b/packages/openapi-code-generator/src/typescript/common/schema-builders/zod-v3-schema-builder.ts index 5a55d07bc..23c7e47c2 100644 --- a/packages/openapi-code-generator/src/typescript/common/schema-builders/zod-v3-schema-builder.ts +++ b/packages/openapi-code-generator/src/typescript/common/schema-builders/zod-v3-schema-builder.ts @@ -165,6 +165,22 @@ export class ZodV3Builder extends AbstractSchemaBuilder< .join(".") } + protected discriminatedUnion( + propertyName: string, + mapping: Record, + ): string { + const schemas = Object.values(mapping) + + return [ + zod, + `discriminatedUnion("${propertyName}", [\n${schemas + .map((it) => `${it},`) + .join("\n")}\n])`, + ] + .filter(isDefined) + .join(".") + } + protected preprocess( schema: string, transformation: string | ((it: unknown) => unknown), diff --git a/packages/openapi-code-generator/src/typescript/common/schema-builders/zod-v4-schema-builder.ts b/packages/openapi-code-generator/src/typescript/common/schema-builders/zod-v4-schema-builder.ts index df5f63c3e..eed7f5f30 100644 --- a/packages/openapi-code-generator/src/typescript/common/schema-builders/zod-v4-schema-builder.ts +++ b/packages/openapi-code-generator/src/typescript/common/schema-builders/zod-v4-schema-builder.ts @@ -190,6 +190,22 @@ export class ZodV4Builder extends AbstractSchemaBuilder< .join(".") } + protected discriminatedUnion( + propertyName: string, + mapping: Record, + ): string { + const schemas = Object.values(mapping) + + return [ + zod, + `discriminatedUnion("${propertyName}", [\n${schemas + .map((it) => `${it},`) + .join("\n")}\n])`, + ] + .filter(isDefined) + .join(".") + } + protected preprocess( schema: string, transformation: string | ((it: unknown) => unknown), diff --git a/packages/openapi-code-generator/src/typescript/common/schema-builders/zod-v4-schema-builder.unit.spec.ts b/packages/openapi-code-generator/src/typescript/common/schema-builders/zod-v4-schema-builder.unit.spec.ts index 9c24ed0bb..a427cf6e6 100644 --- a/packages/openapi-code-generator/src/typescript/common/schema-builders/zod-v4-schema-builder.unit.spec.ts +++ b/packages/openapi-code-generator/src/typescript/common/schema-builders/zod-v4-schema-builder.unit.spec.ts @@ -1214,6 +1214,65 @@ describe("typescript/common/schema-builders/zod-v4-schema-builder - unit tests", await expect(execute("some string")).resolves.toEqual("some string") }) + + it("can generate a discriminated union", async () => { + const {code, execute} = await getActual( + ir.union({ + schemas: [ + ir.object({ + properties: { + kind: ir.string({enum: ["a"]}), + foo: ir.string(), + }, + required: ["kind", "foo"], + }), + ir.object({ + properties: { + kind: ir.string({enum: ["b"]}), + bar: ir.string(), + }, + required: ["kind", "bar"], + }), + ], + discriminator: { + propertyName: "kind", + mapping: { + a: ir.object({ + properties: { + kind: ir.string({enum: ["a"]}), + foo: ir.string(), + }, + required: ["kind", "foo"], + }), + b: ir.object({ + properties: { + kind: ir.string({enum: ["b"]}), + bar: ir.string(), + }, + required: ["kind", "bar"], + }), + }, + }, + }), + ) + + expect(code).toMatchInlineSnapshot(` + "const x = z.discriminatedUnion("kind", [ + z.object({ kind: z.literal("a"), foo: z.string() }), + z.object({ kind: z.literal("b"), bar: z.string() }), + ])" + `) + + await expect(execute({kind: "a", foo: "foo"})).resolves.toEqual({ + kind: "a", + foo: "foo", + }) + + await expect(execute({kind: "b", bar: "bar"})).resolves.toEqual({ + kind: "b", + bar: "bar", + }) + }) }) describe("intersections", () => { From 8b17d745151679b935274a594980a6bffe308091 Mon Sep 17 00:00:00 2001 From: Michael Nahkies Date: Sat, 30 May 2026 11:12:48 +0100 Subject: [PATCH 2/5] fix: add validation, fall back to union --- .../normalization/schema-normalizer.spec.ts | 129 +++++++++++++++++- .../core/normalization/schema-normalizer.ts | 34 +++++ 2 files changed, 157 insertions(+), 6 deletions(-) diff --git a/packages/openapi-code-generator/src/core/normalization/schema-normalizer.spec.ts b/packages/openapi-code-generator/src/core/normalization/schema-normalizer.spec.ts index 1f795c37f..050dcec94 100644 --- a/packages/openapi-code-generator/src/core/normalization/schema-normalizer.spec.ts +++ b/packages/openapi-code-generator/src/core/normalization/schema-normalizer.spec.ts @@ -647,11 +647,17 @@ describe("core/input - SchemaNormalizer", () => { it("supports mapping", () => { schemaProvider.registerTestRef( ir.ref("/components/schemas/Foo"), - ir.object({properties: {type: ir.string()}}), + ir.object({ + properties: {type: ir.string({enum: ["foo"]})}, + required: ["type"], + }), ) schemaProvider.registerTestRef( ir.ref("/components/schemas/Bar"), - ir.object({properties: {type: ir.string()}}), + ir.object({ + properties: {type: ir.string({enum: ["bar"]})}, + required: ["type"], + }), ) const actual = schemaNormalizer.normalize({ @@ -689,11 +695,17 @@ describe("core/input - SchemaNormalizer", () => { it("supports a defined path mapping", () => { schemaProvider.registerTestRef( ir.ref("/components/schemas/Foo", "/absolute/path.yaml"), - ir.object({properties: {type: ir.string()}}), + ir.object({ + properties: {type: ir.string({enum: ["foo"]})}, + required: ["type"], + }), ) schemaProvider.registerTestRef( ir.ref("/components/schemas/Bar", "/absolute/path.yaml"), - ir.object({properties: {type: ir.string()}}), + ir.object({ + properties: {type: ir.string({enum: ["bar"]})}, + required: ["type"], + }), ) const actual = schemaNormalizer.normalize({ @@ -774,11 +786,17 @@ describe("core/input - SchemaNormalizer", () => { it("infers a mapping when none provided", () => { schemaProvider.registerTestRef( ir.ref("/components/schemas/Foo"), - ir.object({properties: {type: ir.string()}}), + ir.object({ + properties: {type: ir.string({enum: ["foo"]})}, + required: ["type"], + }), ) schemaProvider.registerTestRef( ir.ref("/components/schemas/Bar"), - ir.object({properties: {type: ir.string()}}), + ir.object({ + properties: {type: ir.string({enum: ["bar"]})}, + required: ["type"], + }), ) const actual = schemaNormalizer.normalize({ @@ -925,6 +943,105 @@ describe("core/input - SchemaNormalizer", () => { }), ) }) + + it("ignores the discriminator property when the discriminator property is missing in one or more alternatives", () => { + schemaProvider.registerTestRef( + ir.ref("/components/schemas/Foo"), + ir.object({ + properties: {type: ir.string({enum: ["foo"]})}, + required: ["type"], + }), + ) + schemaProvider.registerTestRef( + ir.ref("/components/schemas/Bar"), + ir.object({ + properties: {other: ir.string({enum: ["bar"]})}, + required: ["other"], + }), + ) + + const actual = schemaNormalizer.normalize({ + type: "object", + discriminator: { + propertyName: "type", + }, + oneOf: [ + {$ref: "#/components/schemas/Foo"}, + {$ref: "#/components/schemas/Bar"}, + ], + }) + + expect(actual).toStrictEqual( + ir.union({ + schemas: [ + ir.ref("/components/schemas/Foo"), + ir.ref("/components/schemas/Bar"), + ], + }), + ) + }) + + it("ignores the discriminator property when the discriminator property is not an enum in all alternatives", () => { + schemaProvider.registerTestRef( + ir.ref("/components/schemas/Foo"), + ir.object({properties: {type: ir.string()}}), + ) + schemaProvider.registerTestRef( + ir.ref("/components/schemas/Bar"), + ir.object({properties: {type: ir.string()}}), + ) + + const actual = schemaNormalizer.normalize({ + type: "object", + discriminator: { + propertyName: "type", + }, + oneOf: [ + {$ref: "#/components/schemas/Foo"}, + {$ref: "#/components/schemas/Bar"}, + ], + }) + + expect(actual).toStrictEqual( + ir.union({ + schemas: [ + ir.ref("/components/schemas/Foo"), + ir.ref("/components/schemas/Bar"), + ], + }), + ) + }) + + it("ignores the discriminator property when the discriminator property is not required in all alternatives", () => { + schemaProvider.registerTestRef( + ir.ref("/components/schemas/Foo"), + ir.object({properties: {type: ir.string({enum: ["foo"]})}}), + ) + schemaProvider.registerTestRef( + ir.ref("/components/schemas/Bar"), + ir.object({properties: {type: ir.string({enum: ["bar"]})}}), + ) + + const actual = schemaNormalizer.normalize({ + type: "object", + discriminator: { + propertyName: "type", + }, + oneOf: [ + {$ref: "#/components/schemas/Foo"}, + {$ref: "#/components/schemas/Bar"}, + ], + }) + + expect(actual).toStrictEqual( + ir.union({ + schemas: [ + ir.ref("/components/schemas/Foo"), + ir.ref("/components/schemas/Bar"), + ], + }), + ) + }) }) describe("empty schemas / additionalProperties", () => { diff --git a/packages/openapi-code-generator/src/core/normalization/schema-normalizer.ts b/packages/openapi-code-generator/src/core/normalization/schema-normalizer.ts index 9850b7710..2a2592e01 100644 --- a/packages/openapi-code-generator/src/core/normalization/schema-normalizer.ts +++ b/packages/openapi-code-generator/src/core/normalization/schema-normalizer.ts @@ -425,6 +425,40 @@ export class SchemaNormalizer { // todo: validate that the discriminated property is actually an enum? otherwise it can't be used. // todo: also validate that the discriminated property is required? (avoid 'Duplicate discriminator value "undefined"') + for (const ref of referencedSchemas) { + const referencedSchema = this.schemaProvider.schema(ref) as SchemaObject + const property = referencedSchema.properties?.[discriminator.propertyName] + + if (!property) { + logger.warn( + `ignoring 'discriminator' over propertyName '${discriminator.propertyName}' as it's missing from one or more schemas`, + ) + return undefined + } + + const normalizedProperty = isRef(property) + ? this.schemaProvider.schema(property) + : property + + if (!normalizedProperty || !Reflect.get(normalizedProperty, "enum")) { + logger.warn( + `ignoring 'discriminator' over propertyName '${discriminator.propertyName}' as it's not an enum in one or more schemas`, + ) + return undefined + } + + const isRequired = referencedSchema.required?.includes( + discriminator.propertyName, + ) + + if (!isRequired) { + logger.warn( + `ignoring 'discriminator' over propertyName '${discriminator.propertyName}' as it's not required in one or more schemas`, + ) + return undefined + } + } + // note: mapping is optional, where the default is ${NAME} -> '#/components/schemas/${NAME}' const mapping = discriminator.mapping ? Object.fromEntries( From 251ab22c97a55c03dae0d731782618aee4c56454 Mon Sep 17 00:00:00 2001 From: Michael Nahkies Date: Sat, 30 May 2026 11:24:35 +0100 Subject: [PATCH 3/5] test: add test --- .../zod-v4-schema-builder.unit.spec.ts | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/packages/openapi-code-generator/src/typescript/common/schema-builders/zod-v4-schema-builder.unit.spec.ts b/packages/openapi-code-generator/src/typescript/common/schema-builders/zod-v4-schema-builder.unit.spec.ts index a427cf6e6..610d79009 100644 --- a/packages/openapi-code-generator/src/typescript/common/schema-builders/zod-v4-schema-builder.unit.spec.ts +++ b/packages/openapi-code-generator/src/typescript/common/schema-builders/zod-v4-schema-builder.unit.spec.ts @@ -4,6 +4,7 @@ import type {CompilerOptions} from "../../../core/loaders/tsconfig.loader.ts" import type {IRModel} from "../../../core/openapi-types-normalized.ts" import {isDefined} from "../../../core/utils.ts" import {FakeSchemaProvider} from "../../../test/fake-schema-provider.ts" +import {unitTestInput} from "../../../test/input.test-utils.ts" import {irFixture as ir} from "../../../test/ir-model.fixtures.test-utils.ts" import {TypescriptFormatterBiome} from "../typescript-formatter.biome.ts" import type {SchemaBuilderConfig} from "./abstract-schema-builder.ts" @@ -1273,6 +1274,48 @@ describe("typescript/common/schema-builders/zod-v4-schema-builder - unit tests", bar: "bar", }) }) + + it("can generate a discriminated union with $ref", async () => { + const {code} = await getActual( + ir.union({ + schemas: [ + ir.ref("/components/schemas/A"), + ir.ref("/components/schemas/B"), + ], + discriminator: { + propertyName: "kind", + mapping: { + a: ir.ref("/components/schemas/A"), + b: ir.ref("/components/schemas/B"), + }, + }, + }), + { + schemas: { + "/components/schemas/A": ir.object({ + properties: { + kind: ir.string({enum: ["a"]}), + foo: ir.string(), + }, + required: ["kind", "foo"], + }), + "/components/schemas/B": ir.object({ + properties: { + kind: ir.string({enum: ["b"]}), + bar: ir.string(), + }, + required: ["kind", "bar"], + }), + }, + }, + ) + + expect(code).toMatchInlineSnapshot(` + "import { s_A, s_B } from "./unit-test.schemas" + + const x = z.discriminatedUnion("kind", [s_A, s_B])" + `) + }) }) describe("intersections", () => { @@ -1516,11 +1559,17 @@ describe("typescript/common/schema-builders/zod-v4-schema-builder - unit tests", { config = {allowAny: false}, compilerOptions = {exactOptionalPropertyTypes: false}, + schemas = {}, }: { config?: SchemaBuilderConfig compilerOptions?: CompilerOptions + schemas?: Record } = {}, ) { + for (const [ref, model] of Object.entries(schemas)) { + schemaProvider.registerTestRef(ir.ref(ref), model) + } + return testHarness.getActual(schema, schemaProvider, { config, compilerOptions, From 34ec3939fe0a60eca497efaecde395087570a926 Mon Sep 17 00:00:00 2001 From: Michael Nahkies Date: Sat, 30 May 2026 11:28:00 +0100 Subject: [PATCH 4/5] fix: regenerate --- .../generated/api.github.com.yaml/generated.ts | 15 +++------------ .../generated/api.github.com.yaml/generated.ts | 15 +++------------ .../src/core/normalization/schema-normalizer.ts | 1 + 3 files changed, 7 insertions(+), 24 deletions(-) diff --git a/integration-tests/typescript-express/src/generated/api.github.com.yaml/generated.ts b/integration-tests/typescript-express/src/generated/api.github.com.yaml/generated.ts index db645f1a6..dd055b0af 100644 --- a/integration-tests/typescript-express/src/generated/api.github.com.yaml/generated.ts +++ b/integration-tests/typescript-express/src/generated/api.github.com.yaml/generated.ts @@ -92814,10 +92814,7 @@ export function createRouter( const usersGetAuthenticatedResponseBodyValidator = responseValidationFactory( [ - [ - "200", - z.discriminatedUnion("user_view_type", [s_public_user, s_private_user]), - ], + ["200", z.union([s_private_user, s_public_user])], ["304", z.undefined()], ["401", s_basic_error], ["403", s_basic_error], @@ -99405,10 +99402,7 @@ export function createRouter( const usersGetByIdResponseBodyValidator = responseValidationFactory( [ - [ - "200", - z.discriminatedUnion("user_view_type", [s_public_user, s_private_user]), - ], + ["200", z.union([s_private_user, s_public_user])], ["404", s_basic_error], ], undefined, @@ -99662,10 +99656,7 @@ export function createRouter( const usersGetByUsernameResponseBodyValidator = responseValidationFactory( [ - [ - "200", - z.discriminatedUnion("user_view_type", [s_public_user, s_private_user]), - ], + ["200", z.union([s_private_user, s_public_user])], ["404", s_basic_error], ], undefined, diff --git a/integration-tests/typescript-koa/src/generated/api.github.com.yaml/generated.ts b/integration-tests/typescript-koa/src/generated/api.github.com.yaml/generated.ts index a1ce00c43..4a39a75ce 100644 --- a/integration-tests/typescript-koa/src/generated/api.github.com.yaml/generated.ts +++ b/integration-tests/typescript-koa/src/generated/api.github.com.yaml/generated.ts @@ -91568,10 +91568,7 @@ export function createRouter( const usersGetAuthenticatedResponseValidator = responseValidationFactory( [ - [ - "200", - z.discriminatedUnion("user_view_type", [s_public_user, s_private_user]), - ], + ["200", z.union([s_private_user, s_public_user])], ["304", z.undefined()], ["401", s_basic_error], ["403", s_basic_error], @@ -97335,10 +97332,7 @@ export function createRouter( const usersGetByIdResponseValidator = responseValidationFactory( [ - [ - "200", - z.discriminatedUnion("user_view_type", [s_public_user, s_private_user]), - ], + ["200", z.union([s_private_user, s_public_user])], ["404", s_basic_error], ], undefined, @@ -97557,10 +97551,7 @@ export function createRouter( const usersGetByUsernameResponseValidator = responseValidationFactory( [ - [ - "200", - z.discriminatedUnion("user_view_type", [s_public_user, s_private_user]), - ], + ["200", z.union([s_private_user, s_public_user])], ["404", s_basic_error], ], undefined, diff --git a/packages/openapi-code-generator/src/core/normalization/schema-normalizer.ts b/packages/openapi-code-generator/src/core/normalization/schema-normalizer.ts index 2a2592e01..5b0a2c221 100644 --- a/packages/openapi-code-generator/src/core/normalization/schema-normalizer.ts +++ b/packages/openapi-code-generator/src/core/normalization/schema-normalizer.ts @@ -452,6 +452,7 @@ export class SchemaNormalizer { ) if (!isRequired) { + // todo: when defaultMapping support is added, an undefined discriminator property value will map to the defaultMapping logger.warn( `ignoring 'discriminator' over propertyName '${discriminator.propertyName}' as it's not required in one or more schemas`, ) From 107f3940e643f556db4f0b459c65956e85828b48 Mon Sep 17 00:00:00 2001 From: Michael Nahkies Date: Sat, 30 May 2026 11:31:47 +0100 Subject: [PATCH 5/5] chore: deps --- e2e/package.json | 6 +- .../typescript-angular/package.json | 18 +- .../typescript-axios/package.json | 4 +- .../typescript-express/package.json | 2 +- .../typescript-fetch/package.json | 2 +- integration-tests/typescript-koa/package.json | 6 +- package.json | 2 +- packages/documentation/package.json | 8 +- packages/openapi-code-generator/package.json | 2 +- .../typescript-axios-runtime/package.json | 2 +- packages/typescript-koa-runtime/package.json | 4 +- pnpm-lock.yaml | 556 ++++++++++-------- 12 files changed, 337 insertions(+), 275 deletions(-) diff --git a/e2e/package.json b/e2e/package.json index 6d10ad4a3..825a94499 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -19,16 +19,16 @@ "@nahkies/typescript-express-runtime": "workspace:*", "@nahkies/typescript-fetch-runtime": "workspace:*", "@nahkies/typescript-koa-runtime": "workspace:*", - "axios": "^1.16.1", + "axios": "^1.15.2", "express": "^5.2.1", - "koa": "^3.2.0", + "koa": "^3.2.1", "zod": "^3.25.76" }, "devDependencies": { "@jest/globals": "^30.4.1", "@nahkies/openapi-code-generator": "workspace:*", "@types/express": "^5.0.6", - "@types/koa": "^3.0.2", + "@types/koa": "^3.0.3", "expect": "^30.4.1", "jest": "^30.4.2", "typescript": "^6.0.3" diff --git a/integration-tests/typescript-angular/package.json b/integration-tests/typescript-angular/package.json index c6f26d52b..6c43372e0 100644 --- a/integration-tests/typescript-angular/package.json +++ b/integration-tests/typescript-angular/package.json @@ -10,19 +10,19 @@ }, "private": true, "dependencies": { - "@angular/common": "^21.2.13", - "@angular/compiler": "^21.2.13", - "@angular/core": "^21.2.13", - "@angular/forms": "^21.2.13", - "@angular/platform-browser": "^21.2.13", - "@angular/router": "^21.2.13", + "@angular/common": "^21.2.14", + "@angular/compiler": "^21.2.14", + "@angular/core": "^21.2.14", + "@angular/forms": "^21.2.14", + "@angular/platform-browser": "^21.2.14", + "@angular/router": "^21.2.14", "rxjs": "~7.8.2", "tslib": "^2.8.1" }, "devDependencies": { - "@angular/build": "^21.2.11", - "@angular/cli": "^21.2.11", - "@angular/compiler-cli": "^21.2.13", + "@angular/build": "^21.2.12", + "@angular/cli": "^21.2.12", + "@angular/compiler-cli": "^21.2.14", "typescript": "^6.0.3" } } diff --git a/integration-tests/typescript-axios/package.json b/integration-tests/typescript-axios/package.json index 0c3626e0a..518c8ddec 100644 --- a/integration-tests/typescript-axios/package.json +++ b/integration-tests/typescript-axios/package.json @@ -11,12 +11,12 @@ }, "dependencies": { "@nahkies/typescript-axios-runtime": "workspace:*", - "axios": "^1.16.1", + "axios": "^1.15.2", "dotenv": "^17.4.2", "tslib": "^2.8.1" }, "devDependencies": { "@types/node": "^22.19.17", - "@typescript/native-preview": "7.0.0-dev.20260517.1" + "@typescript/native-preview": "7.0.0-dev.20260523.1" } } diff --git a/integration-tests/typescript-express/package.json b/integration-tests/typescript-express/package.json index 25ae9ffd8..f6acedb01 100644 --- a/integration-tests/typescript-express/package.json +++ b/integration-tests/typescript-express/package.json @@ -19,6 +19,6 @@ }, "devDependencies": { "@types/express": "^5.0.6", - "@typescript/native-preview": "7.0.0-dev.20260517.1" + "@typescript/native-preview": "7.0.0-dev.20260523.1" } } diff --git a/integration-tests/typescript-fetch/package.json b/integration-tests/typescript-fetch/package.json index c1221b806..f460156a3 100644 --- a/integration-tests/typescript-fetch/package.json +++ b/integration-tests/typescript-fetch/package.json @@ -17,6 +17,6 @@ }, "devDependencies": { "@types/node": "^22.19.17", - "@typescript/native-preview": "7.0.0-dev.20260517.1" + "@typescript/native-preview": "7.0.0-dev.20260523.1" } } diff --git a/integration-tests/typescript-koa/package.json b/integration-tests/typescript-koa/package.json index ea74daedf..11cc72e9d 100644 --- a/integration-tests/typescript-koa/package.json +++ b/integration-tests/typescript-koa/package.json @@ -13,12 +13,12 @@ "@koa/router": "^15.5.0", "@nahkies/typescript-koa-runtime": "workspace:*", "joi": "^18.2.1", - "koa": "^3.2.0", + "koa": "^3.2.1", "tslib": "^2.8.1", "zod": "^3.25.76" }, "devDependencies": { - "@types/koa": "^3.0.2", - "@typescript/native-preview": "7.0.0-dev.20260517.1" + "@types/koa": "^3.0.3", + "@typescript/native-preview": "7.0.0-dev.20260523.1" } } diff --git a/package.json b/package.json index cbddd6b71..e7b8b3a24 100644 --- a/package.json +++ b/package.json @@ -82,5 +82,5 @@ "engines": { "node": ">=22" }, - "packageManager": "pnpm@10.33.2+sha512.a90faf6feeab71ad6c6e57f94e0fe1a12f5dcc22cd754db40ae9593eb6a3e0b6b12e3540218bb37ae083404b1f2ce6db2a4121e979829b4aff94b99f49da1cf8" + "packageManager": "pnpm@10.34.1+sha512.b58fbde6dca66a929538021581f648b4570b6ca19b18e7cbd7f2c07a7b24454155388dacdf08f2af3678e88a6d1fe04f9d609df24bf51735a060ea041b374ab7" } diff --git a/packages/documentation/package.json b/packages/documentation/package.json index 35739516f..9336dea72 100644 --- a/packages/documentation/package.json +++ b/packages/documentation/package.json @@ -25,7 +25,7 @@ "publish:gh-pages": "pnpm gh-pages -d ./dist -b gh-pages --cname openapi-code-generator.nahkies.co.nz --nojekyll" }, "dependencies": { - "@hookform/resolvers": "^5.2.2", + "@hookform/resolvers": "^5.4.0", "@monaco-editor/react": "^4.7.0", "@nahkies/openapi-code-generator": "workspace:*", "lodash": "^4.18.1", @@ -36,17 +36,17 @@ "nextra-theme-docs": "^4.6.1", "react": "19.2.6", "react-dom": "19.2.6", - "react-hook-form": "^7.76.0", + "react-hook-form": "^7.76.1", "tslib": "^2.8.1", "zod": "^3.25.76" }, "devDependencies": { "@types/lodash": "^4.17.24", "@types/node": "^22.19.17", - "@types/react": "^19.2.14", + "@types/react": "^19.2.15", "@types/react-dom": "^19.2.3", "gh-pages": "^6.3.0", - "tsx": "^4.22.1", + "tsx": "^4.22.3", "typescript": "^6.0.3" }, "engines": { diff --git a/packages/openapi-code-generator/package.json b/packages/openapi-code-generator/package.json index abed237fe..c8662de2c 100644 --- a/packages/openapi-code-generator/package.json +++ b/packages/openapi-code-generator/package.json @@ -82,7 +82,7 @@ "@typespec/xml": "0.82.0", "joi": "^18.2.1", "tsdown": "^0.22.0", - "tsx": "^4.22.1" + "tsx": "^4.22.3" }, "dependencies": { "@biomejs/biome": "2.4.15", diff --git a/packages/typescript-axios-runtime/package.json b/packages/typescript-axios-runtime/package.json index 213d1fbff..b50e89757 100644 --- a/packages/typescript-axios-runtime/package.json +++ b/packages/typescript-axios-runtime/package.json @@ -44,7 +44,7 @@ "devDependencies": { "@jest/globals": "^30.4.1", "@nahkies/typescript-common-runtime": "workspace:^", - "axios": "^1.16.1", + "axios": "^1.15.2", "jest": "^30.4.2", "tsdown": "^0.22.0", "typescript": "^6.0.3" diff --git a/packages/typescript-koa-runtime/package.json b/packages/typescript-koa-runtime/package.json index e20f38b1b..b135bc4ee 100644 --- a/packages/typescript-koa-runtime/package.json +++ b/packages/typescript-koa-runtime/package.json @@ -100,11 +100,11 @@ "@koa/cors": "^5.0.0", "@koa/router": "^15.5.0", "@nahkies/typescript-common-runtime": "workspace:^", - "@types/koa": "^3.0.2", + "@types/koa": "^3.0.3", "@types/koa__cors": "^5.0.1", "jest": "^30.4.2", "joi": "^18.2.1", - "koa": "^3.2.0", + "koa": "^3.2.1", "koa-body": "^7.0.1", "tsdown": "^0.22.0", "typescript": "^6.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 843db015c..8c64bc2a3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -98,7 +98,7 @@ importers: dependencies: '@koa/router': specifier: ^15.5.0 - version: 15.5.0(koa@3.2.0) + version: 15.5.0(koa@3.2.1) '@nahkies/typescript-axios-runtime': specifier: workspace:* version: link:../packages/typescript-axios-runtime @@ -118,8 +118,8 @@ importers: specifier: ^5.2.1 version: 5.2.1 koa: - specifier: ^3.2.0 - version: 3.2.0 + specifier: ^3.2.1 + version: 3.2.1 zod: specifier: ^3.25.76 version: 3.25.76 @@ -134,8 +134,8 @@ importers: specifier: ^5.0.6 version: 5.0.6 '@types/koa': - specifier: ^3.0.2 - version: 3.0.2 + specifier: ^3.0.3 + version: 3.0.3 expect: specifier: ^30.4.1 version: 30.4.1 @@ -149,23 +149,23 @@ importers: integration-tests/typescript-angular: dependencies: '@angular/common': - specifier: ^21.2.13 - version: 21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2) + specifier: ^21.2.14 + version: 21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2) '@angular/compiler': - specifier: ^21.2.13 - version: 21.2.13 + specifier: ^21.2.14 + version: 21.2.14 '@angular/core': - specifier: ^21.2.13 - version: 21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2) + specifier: ^21.2.14 + version: 21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2) '@angular/forms': - specifier: ^21.2.13 - version: 21.2.13(@angular/common@21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(@angular/platform-browser@21.2.13(@angular/common@21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2)))(rxjs@7.8.2) + specifier: ^21.2.14 + version: 21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(@angular/platform-browser@21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)))(rxjs@7.8.2) '@angular/platform-browser': - specifier: ^21.2.13 - version: 21.2.13(@angular/common@21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2)) + specifier: ^21.2.14 + version: 21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)) '@angular/router': - specifier: ^21.2.13 - version: 21.2.13(@angular/common@21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(@angular/platform-browser@21.2.13(@angular/common@21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2)))(rxjs@7.8.2) + specifier: ^21.2.14 + version: 21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(@angular/platform-browser@21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)))(rxjs@7.8.2) rxjs: specifier: ~7.8.2 version: 7.8.2 @@ -174,14 +174,14 @@ importers: version: 2.8.1 devDependencies: '@angular/build': - specifier: ^21.2.11 - version: 21.2.11(@angular/compiler-cli@21.2.13(@angular/compiler@21.2.13)(typescript@6.0.3))(@angular/compiler@21.2.13)(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(@angular/platform-browser@21.2.13(@angular/common@21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2)))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.19)(chokidar@5.0.0)(postcss@8.5.14)(tslib@2.8.1)(tsx@4.22.1)(typescript@6.0.3)(yaml@2.9.0) + specifier: ^21.2.12 + version: 21.2.12(@angular/compiler-cli@21.2.14(@angular/compiler@21.2.14)(typescript@6.0.3))(@angular/compiler@21.2.14)(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(@angular/platform-browser@21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.19)(chokidar@5.0.0)(postcss@8.5.15)(tslib@2.8.1)(tsx@4.22.3)(typescript@6.0.3)(yaml@2.9.0) '@angular/cli': - specifier: ^21.2.11 - version: 21.2.11(@types/node@22.19.19)(chokidar@5.0.0) + specifier: ^21.2.12 + version: 21.2.12(@types/node@22.19.19)(chokidar@5.0.0) '@angular/compiler-cli': - specifier: ^21.2.13 - version: 21.2.13(@angular/compiler@21.2.13)(typescript@6.0.3) + specifier: ^21.2.14 + version: 21.2.14(@angular/compiler@21.2.14)(typescript@6.0.3) typescript: specifier: ^6.0.3 version: 6.0.3 @@ -205,8 +205,8 @@ importers: specifier: ^22.19.17 version: 22.19.19 '@typescript/native-preview': - specifier: 7.0.0-dev.20260517.1 - version: 7.0.0-dev.20260517.1 + specifier: 7.0.0-dev.20260523.1 + version: 7.0.0-dev.20260523.1 integration-tests/typescript-express: dependencies: @@ -230,8 +230,8 @@ importers: specifier: ^5.0.6 version: 5.0.6 '@typescript/native-preview': - specifier: 7.0.0-dev.20260517.1 - version: 7.0.0-dev.20260517.1 + specifier: 7.0.0-dev.20260523.1 + version: 7.0.0-dev.20260523.1 integration-tests/typescript-fetch: dependencies: @@ -249,14 +249,14 @@ importers: specifier: ^22.19.17 version: 22.19.19 '@typescript/native-preview': - specifier: 7.0.0-dev.20260517.1 - version: 7.0.0-dev.20260517.1 + specifier: 7.0.0-dev.20260523.1 + version: 7.0.0-dev.20260523.1 integration-tests/typescript-koa: dependencies: '@koa/router': specifier: ^15.5.0 - version: 15.5.0(koa@3.2.0) + version: 15.5.0(koa@3.2.1) '@nahkies/typescript-koa-runtime': specifier: workspace:* version: link:../../packages/typescript-koa-runtime @@ -264,8 +264,8 @@ importers: specifier: ^18.2.1 version: 18.2.1 koa: - specifier: ^3.2.0 - version: 3.2.0 + specifier: ^3.2.1 + version: 3.2.1 tslib: specifier: ^2.8.1 version: 2.8.1 @@ -274,17 +274,17 @@ importers: version: 3.25.76 devDependencies: '@types/koa': - specifier: ^3.0.2 - version: 3.0.2 + specifier: ^3.0.3 + version: 3.0.3 '@typescript/native-preview': - specifier: 7.0.0-dev.20260517.1 - version: 7.0.0-dev.20260517.1 + specifier: 7.0.0-dev.20260523.1 + version: 7.0.0-dev.20260523.1 packages/documentation: dependencies: '@hookform/resolvers': - specifier: ^5.2.2 - version: 5.2.2(react-hook-form@7.76.0(react@19.2.6)) + specifier: ^5.4.0 + version: 5.4.0(react-hook-form@7.76.1(react@19.2.6)) '@monaco-editor/react': specifier: ^4.7.0 version: 4.7.0(monaco-editor@0.55.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -308,7 +308,7 @@ importers: version: 4.6.1(next@16.2.6(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.97.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) nextra-theme-docs: specifier: ^4.6.1 - version: 4.6.1(@types/react@19.2.14)(next@16.2.6(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.97.3))(nextra@4.6.1(next@16.2.6(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.97.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6)) + version: 4.6.1(@types/react@19.2.15)(next@16.2.6(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.97.3))(nextra@4.6.1(next@16.2.6(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.97.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6)) react: specifier: 19.2.6 version: 19.2.6 @@ -316,8 +316,8 @@ importers: specifier: 19.2.6 version: 19.2.6(react@19.2.6) react-hook-form: - specifier: ^7.76.0 - version: 7.76.0(react@19.2.6) + specifier: ^7.76.1 + version: 7.76.1(react@19.2.6) tslib: specifier: ^2.8.1 version: 2.8.1 @@ -332,17 +332,17 @@ importers: specifier: ^22.19.17 version: 22.19.19 '@types/react': - specifier: ^19.2.14 - version: 19.2.14 + specifier: ^19.2.15 + version: 19.2.15 '@types/react-dom': specifier: ^19.2.3 - version: 19.2.3(@types/react@19.2.14) + version: 19.2.3(@types/react@19.2.15) gh-pages: specifier: ^6.3.0 version: 6.3.0 tsx: - specifier: ^4.22.1 - version: 4.22.1 + specifier: ^4.22.3 + version: 4.22.3 typescript: specifier: ^6.0.3 version: 6.0.3 @@ -454,10 +454,10 @@ importers: version: 18.2.1 tsdown: specifier: ^0.22.0 - version: 0.22.0(@arethetypeswrong/core@0.18.2)(@typescript/native-preview@7.0.0-dev.20260517.1)(publint@0.3.21)(tsx@4.22.1)(typescript@6.0.3)(unrun@0.2.37(synckit@0.11.12)) + version: 0.22.0(@arethetypeswrong/core@0.18.2)(@typescript/native-preview@7.0.0-dev.20260523.1)(publint@0.3.21)(tsx@4.22.3)(typescript@6.0.3)(unrun@0.2.37(synckit@0.11.12)) tsx: - specifier: ^4.22.1 - version: 4.22.1 + specifier: ^4.22.3 + version: 4.22.3 packages/typescript-axios-runtime: dependencies: @@ -479,7 +479,7 @@ importers: version: 30.4.2(@types/node@22.19.19) tsdown: specifier: ^0.22.0 - version: 0.22.0(@arethetypeswrong/core@0.18.2)(@typescript/native-preview@7.0.0-dev.20260517.1)(publint@0.3.21)(tsx@4.22.1)(typescript@6.0.3)(unrun@0.2.37(synckit@0.11.12)) + version: 0.22.0(@arethetypeswrong/core@0.18.2)(@typescript/native-preview@7.0.0-dev.20260523.1)(publint@0.3.21)(tsx@4.22.3)(typescript@6.0.3)(unrun@0.2.37(synckit@0.11.12)) typescript: specifier: ^6.0.3 version: 6.0.3 @@ -501,7 +501,7 @@ importers: version: 30.4.2(@types/node@22.19.19) tsdown: specifier: ^0.22.0 - version: 0.22.0(@arethetypeswrong/core@0.18.2)(@typescript/native-preview@7.0.0-dev.20260517.1)(publint@0.3.21)(tsx@4.22.1)(typescript@6.0.3)(unrun@0.2.37(synckit@0.11.12)) + version: 0.22.0(@arethetypeswrong/core@0.18.2)(@typescript/native-preview@7.0.0-dev.20260523.1)(publint@0.3.21)(tsx@4.22.3)(typescript@6.0.3)(unrun@0.2.37(synckit@0.11.12)) typescript: specifier: ^6.0.3 version: 6.0.3 @@ -544,7 +544,7 @@ importers: version: 18.2.1 tsdown: specifier: ^0.22.0 - version: 0.22.0(@arethetypeswrong/core@0.18.2)(@typescript/native-preview@7.0.0-dev.20260517.1)(publint@0.3.21)(tsx@4.22.1)(typescript@6.0.3)(unrun@0.2.37(synckit@0.11.12)) + version: 0.22.0(@arethetypeswrong/core@0.18.2)(@typescript/native-preview@7.0.0-dev.20260523.1)(publint@0.3.21)(tsx@4.22.3)(typescript@6.0.3)(unrun@0.2.37(synckit@0.11.12)) typescript: specifier: ^6.0.3 version: 6.0.3 @@ -572,7 +572,7 @@ importers: version: 18.2.1 tsdown: specifier: ^0.22.0 - version: 0.22.0(@arethetypeswrong/core@0.18.2)(@typescript/native-preview@7.0.0-dev.20260517.1)(publint@0.3.21)(tsx@4.22.1)(typescript@6.0.3)(unrun@0.2.37(synckit@0.11.12)) + version: 0.22.0(@arethetypeswrong/core@0.18.2)(@typescript/native-preview@7.0.0-dev.20260523.1)(publint@0.3.21)(tsx@4.22.3)(typescript@6.0.3)(unrun@0.2.37(synckit@0.11.12)) typescript: specifier: ^6.0.3 version: 6.0.3 @@ -597,13 +597,13 @@ importers: version: 5.0.0 '@koa/router': specifier: ^15.5.0 - version: 15.5.0(koa@3.2.0) + version: 15.5.0(koa@3.2.1) '@nahkies/typescript-common-runtime': specifier: workspace:^ version: link:../typescript-common-runtime '@types/koa': - specifier: ^3.0.2 - version: 3.0.2 + specifier: ^3.0.3 + version: 3.0.3 '@types/koa__cors': specifier: ^5.0.1 version: 5.0.1 @@ -614,14 +614,14 @@ importers: specifier: ^18.2.1 version: 18.2.1 koa: - specifier: ^3.2.0 - version: 3.2.0 + specifier: ^3.2.1 + version: 3.2.1 koa-body: specifier: ^7.0.1 version: 7.0.1 tsdown: specifier: ^0.22.0 - version: 0.22.0(@arethetypeswrong/core@0.18.2)(@typescript/native-preview@7.0.0-dev.20260517.1)(publint@0.3.21)(tsx@4.22.1)(typescript@6.0.3)(unrun@0.2.37(synckit@0.11.12)) + version: 0.22.0(@arethetypeswrong/core@0.18.2)(@typescript/native-preview@7.0.0-dev.20260523.1)(publint@0.3.21)(tsx@4.22.3)(typescript@6.0.3)(unrun@0.2.37(synckit@0.11.12)) typescript: specifier: ^6.0.3 version: 6.0.3 @@ -694,13 +694,13 @@ packages: '@andrewbranch/untar.js@1.0.3': resolution: {integrity: sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==} - '@angular-devkit/architect@0.2102.11': - resolution: {integrity: sha512-t7J8aaUho1mXjiIecPNX5/rjXeV8j8ZCGY5tD3ic5kzKxPkbuYYcQpJLdzlmBcN+wDgCmNdo8ySvItvU0m58lg==} + '@angular-devkit/architect@0.2102.12': + resolution: {integrity: sha512-w9FSMHYeeHkk0kRSAOCvNqEVyOHqpC1SUf3iN7tDnXBOA0dtc6JYvJU7O4joiwf7wMPZDK8LKc/6eu8/Tx87Fw==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} hasBin: true - '@angular-devkit/core@21.2.11': - resolution: {integrity: sha512-kfMNh5X2hOdyr0uNFaaHUJR3OVr4oH2+UhI+FsTu7gqogdgYlHAVHhHAFulfDgtAEOiqpeSQF9RhQnCJl+/LXA==} + '@angular-devkit/core@21.2.12': + resolution: {integrity: sha512-nXms0jVWwHOJK+z6vHvhw7HYFBelxh2gEnkij0OQMABXZN5hoUlTD0DDP1lYR7hQNi8Yb2Ar0UN9ihyUFVM5Kg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} peerDependencies: chokidar: ^5.0.0 @@ -708,12 +708,12 @@ packages: chokidar: optional: true - '@angular-devkit/schematics@21.2.11': - resolution: {integrity: sha512-69CWZ5/ftLdpUPAwwdAxTNosiGXUyvwdnOfmHsd9NvCT0OSTeq0eQ0UfnGcHASrXIVmnyWiNfBWM1DLqsgBXmw==} + '@angular-devkit/schematics@21.2.12': + resolution: {integrity: sha512-29xe6C9nwHejV9zBcu0js7NmzLWuCFzBGBTmL6eD4JN1NcxEZ/nO1JuaGINjPjzb/UDXPZIqEwHbnFNcGS5v1A==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - '@angular/build@21.2.11': - resolution: {integrity: sha512-2afR6VKkP0HH2u6OuijSMgSHsL5tU4CBCixgQtY677mlvS8TOZg/kOksJIUlz0EvDVCJZBK8WLH9cPJ6mC/Qdg==} + '@angular/build@21.2.12': + resolution: {integrity: sha512-zYfo21RuldDWXnshuPfWYtmh5ltlO9+XFHpNObdIInQTFxKD6grLNVNOblFFpi+oIIm4Km+CGSXvBHs/aH0ufA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} peerDependencies: '@angular/compiler': ^21.0.0 @@ -723,7 +723,7 @@ packages: '@angular/platform-browser': ^21.0.0 '@angular/platform-server': ^21.0.0 '@angular/service-worker': ^21.0.0 - '@angular/ssr': ^21.2.11 + '@angular/ssr': ^21.2.12 karma: ^6.4.0 less: ^4.2.0 ng-packagr: ^21.0.0 @@ -758,38 +758,38 @@ packages: vitest: optional: true - '@angular/cli@21.2.11': - resolution: {integrity: sha512-vpF/oa+HzLl4lF78ePCgkhBdQj29IlFvZtBsbAXXpb16FLZSua2m7+yHd/PICTlchh1+LfIxFY9snMY1BllBsQ==} + '@angular/cli@21.2.12': + resolution: {integrity: sha512-oLEL1C1fI39b1eQo5f2cyQhQfE+QMv7dm8z2MmxbP7YR7jAdQPVfGU8CXECR5g7mrYi9WgvIRKB+9Oeq2aH6Jw==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} hasBin: true - '@angular/common@21.2.13': - resolution: {integrity: sha512-fNvRmGAX0zbsLX/kJjgb6l8HAuGTpfYRNc06taTCIvED2RsRpfwrh79IxYlPBspr+hpFbHa0/kxU6Q5I8V0jKQ==} + '@angular/common@21.2.14': + resolution: {integrity: sha512-J6K7cE7uKOKmg4+sxLeGfsmaYDjP5l1XCiMMI0WPT0t68uxLk8g3MzV5Trqfb6ZnRxWcfp9c4c+XxAvMBB7ymA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/core': 21.2.13 + '@angular/core': 21.2.14 rxjs: ^6.5.3 || ^7.4.0 - '@angular/compiler-cli@21.2.13': - resolution: {integrity: sha512-ueETJy2ZcXZ4a0aLEr+oPMw26f8Hn903WC4QN0MCH+sLB9Zustpzydqtmzo5mdSzwuoLoxcesYJTZFmpwD1xIQ==} + '@angular/compiler-cli@21.2.14': + resolution: {integrity: sha512-h+WQfPKFxaDfDhMqUUdOQ1TsDMccav8kLFERmKTRfD4MNOczSMpOMyeXJHCL0Rq4I8WDQvaBJGMG7DXRDefSog==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} hasBin: true peerDependencies: - '@angular/compiler': 21.2.13 + '@angular/compiler': 21.2.14 typescript: '>=5.9 <6.1' peerDependenciesMeta: typescript: optional: true - '@angular/compiler@21.2.13': - resolution: {integrity: sha512-0OZk5ujHgowRme3iXJ1Ce1OI3eTDcGovBARBiyJT0E8kt9Y0TdQdGaYMRrNN1UzDv4hk8f1d/xVeF0BpMTvqPQ==} + '@angular/compiler@21.2.14': + resolution: {integrity: sha512-8mqgwRYfn2Z1vg/5YVt60dDBattnZL45nNJd2vTMwAiDTzhWhgKgRWKOeVL0aj2JqHeHiwuIlrLnz46acJMulQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - '@angular/core@21.2.13': - resolution: {integrity: sha512-23tS4oNL8nvkHcI4l9rbruQs2WS4yqQmBVQxWakqS9cmRpArLGgveR+hKNU5tPXm5EAi8oLO34/Zy7z70jUpCg==} + '@angular/core@21.2.14': + resolution: {integrity: sha512-Z1Ivjh7L2lT//8LA7vQ3tj7Rg6wl2XRA5kPSAukgn8u0Yu0XxG8NE8KG0Eypb3v9CEcbwATwpgnxzbJFZ8TFcw==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/compiler': 21.2.13 + '@angular/compiler': 21.2.14 rxjs: ^6.5.3 || ^7.4.0 zone.js: ~0.15.0 || ~0.16.0 peerDependenciesMeta: @@ -798,33 +798,33 @@ packages: zone.js: optional: true - '@angular/forms@21.2.13': - resolution: {integrity: sha512-efAKdL8eVRlGvcJWrUFcYyRE/togWfopUTw2D5TIkDAndnmmRaWA70wD4n/E1FFV5UdxSBxoyEYE0qVlPiewtQ==} + '@angular/forms@21.2.14': + resolution: {integrity: sha512-HQYIybyMt0CrI31rW6vXbiDsSM2DDtTcOVeT/nWDRNCoqBrREDg8rVsm2Y+fUMsiQVJNa6dCXPwvYhjzJ4r7ug==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/common': 21.2.13 - '@angular/core': 21.2.13 - '@angular/platform-browser': 21.2.13 + '@angular/common': 21.2.14 + '@angular/core': 21.2.14 + '@angular/platform-browser': 21.2.14 rxjs: ^6.5.3 || ^7.4.0 - '@angular/platform-browser@21.2.13': - resolution: {integrity: sha512-96rcwLHsklqAYRuS2SEBOUdQS5PLkuUIEEIjpYu4rxU2PVvOMapJEImM/QBxrbwjnCgRbj/CivkgfjiR0R0wSA==} + '@angular/platform-browser@21.2.14': + resolution: {integrity: sha512-34tBwxh86yN2YifBDhCesm6N+nn9WcbuXjRwfo0mTme15OZ/zt56yw7v1mcK3UFLegIIALtsIgpXXrPWWQoKkA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/animations': 21.2.13 - '@angular/common': 21.2.13 - '@angular/core': 21.2.13 + '@angular/animations': 21.2.14 + '@angular/common': 21.2.14 + '@angular/core': 21.2.14 peerDependenciesMeta: '@angular/animations': optional: true - '@angular/router@21.2.13': - resolution: {integrity: sha512-/JXtdhUH/rDGiJmUNrrbs52Aji4sygVCz5HIBujrnj3cjreKam7n98Ufkh0aZvAKybdGd5A8srNUFePzAvfExQ==} + '@angular/router@21.2.14': + resolution: {integrity: sha512-Yo3LdgcqkfMu2/Ycl8o/4QjCBqZhtA+a7B8JVdW5cWdrpFTxKCOrzm+YRUMuIFmH5nzSv9oGnUuz64uk1+7r5Q==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/common': 21.2.13 - '@angular/core': 21.2.13 - '@angular/platform-browser': 21.2.13 + '@angular/common': 21.2.14 + '@angular/core': 21.2.14 + '@angular/platform-browser': 21.2.14 rxjs: ^6.5.3 || ^7.4.0 '@antfu/install-pkg@1.1.0': @@ -1581,8 +1581,8 @@ packages: peerDependencies: hono: ^4 - '@hookform/resolvers@5.2.2': - resolution: {integrity: sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA==} + '@hookform/resolvers@5.4.0': + resolution: {integrity: sha512-EIsqr/t/qbinPIhGjMdtvutIN1Kk4uwbROE9/UQ93CAVGR7GkA7Y92+fX80OzXi/OB67jVFYwKGO1WzkxmkFZw==} peerDependencies: react-hook-form: ^7.55.0 @@ -3365,8 +3365,8 @@ packages: resolution: {integrity: sha512-pvEmfSCDNYR4+lygidUqfo+shzyp4OSh9+UgK110rzA8Oot6WbJBM03Fuq3M255G7G6R9iXyfsebB7MBUocPkw==} engines: {node: '>=22'} - '@schematics/angular@21.2.11': - resolution: {integrity: sha512-EqH12Fr3vaWFpsilFDFXkxwMIidEDZr5cGl0w2hDRG7DjXE2oRB/VXix8xmpuHkzJ40Jgew6hIc+bfbwQhFK1A==} + '@schematics/angular@21.2.12': + resolution: {integrity: sha512-eHoAbxd6Kdw9YIQeZO/6lBXTmKKi10t4WTujY8CM5v4qv1zoJu9yiwVeQp9y3e7/Sybz5Ec3m4FmQ0Tw8iVDiA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} '@shikijs/core@3.23.0': @@ -3403,6 +3403,10 @@ packages: resolution: {integrity: sha512-kxHrDQ9YgfrWUSXU0cjsQGv8JykOFZQ9ErNKbFPWzk3Hgpwu8x2hHrQ9IdA8yl+j9RTLTC3sAF3Tdq1IQCP4oA==} engines: {node: ^20.17.0 || >=22.9.0} + '@sigstore/core@3.2.1': + resolution: {integrity: sha512-qRsxPnCrbC/puegGxKuynfnxgLiHqWStrSjxkoB4YKqq3Z3s4cyZyj42ZdWFAEblNP65C+rBH8EuREHIXoi83g==} + engines: {node: ^20.17.0 || >=22.9.0} + '@sigstore/protobuf-specs@0.5.1': resolution: {integrity: sha512-/ScWUhhoFasJsSRGTVBwId1loQjjnjAfE4djL6ZhrXRpNCmPTnUKF5Jokd58ILseOMjzET3UrMOtJPS9sYeI0g==} engines: {node: ^18.17.0 || >=20.5.0} @@ -3419,6 +3423,10 @@ packages: resolution: {integrity: sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag==} engines: {node: ^20.17.0 || >=22.9.0} + '@sigstore/verify@3.1.1': + resolution: {integrity: sha512-qv7+G3J2cc6wwFj3yKvXOamzqhMwSk1ogPGmhpS8iXllcPrJaIIBA+4HbttlHVu1pqWTdmaCH/WE7UOC51kdoA==} + engines: {node: ^20.17.0 || >=22.9.0} + '@sinclair/typebox@0.34.49': resolution: {integrity: sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==} @@ -3759,8 +3767,8 @@ packages: '@types/koa-compose@3.2.9': resolution: {integrity: sha512-BroAZ9FTvPiCy0Pi8tjD1OfJ7bgU1gQf0eR6e1Vm+JJATy9eKOG3hQMFtMciMawiSOVnLMdmUOC46s7HBhSTsA==} - '@types/koa@3.0.2': - resolution: {integrity: sha512-7TRzVOBcH/q8CfPh9AmHBQ8TZtimT4Sn+rw8//hXveI6+F41z93W8a+0B0O8L7apKQv+vKBIEZSECiL0Oo1JFA==} + '@types/koa@3.0.3': + resolution: {integrity: sha512-TdtNEJ7sYSrFQcVuS2ySsVqnq5EyE3oJbnfFJvkC9UtGP4Kpem5KE7r+ivHIbIAQAofSqnlB5D3vkfYO69TQpg==} '@types/koa__cors@5.0.1': resolution: {integrity: sha512-xZckuh3B6ycSBAIYnBImG1VDHyBNZsltGAuGb4THuZllccdLgD5DUs4RA7TAUjB58THg00SSZ1e//duQef7WRw==} @@ -3800,8 +3808,8 @@ packages: peerDependencies: '@types/react': ^19.2.0 - '@types/react@19.2.14': - resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + '@types/react@19.2.15': + resolution: {integrity: sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q==} '@types/send@1.2.1': resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} @@ -3830,50 +3838,50 @@ packages: '@types/yargs@17.0.35': resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} - '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260517.1': - resolution: {integrity: sha512-YjoHUk4g7ayc8328Wt/JU9T+ChfOO1hNc5qGmkkygL4J4Q3/Wp+EqCNcFinYRSca0Yl5WdcVngd8xyGFeTlwUA==} + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260523.1': + resolution: {integrity: sha512-4WHj9v41per176h00j3moITcHpR+8SNoAFdbDuJwUDCJiQkbrCjwulK8UwALxLPEGqyBdNARWcM6GXVTexBg1w==} engines: {node: '>=16.20.0'} cpu: [arm64] os: [darwin] - '@typescript/native-preview-darwin-x64@7.0.0-dev.20260517.1': - resolution: {integrity: sha512-E/xAkhVaWaoU/u5itoRc1WD8M+A/JPmNbb4SiBexTZDQ3h/5xWU0HRwq/drRiLjFlcm0e1i66MzB8tbc2icctQ==} + '@typescript/native-preview-darwin-x64@7.0.0-dev.20260523.1': + resolution: {integrity: sha512-WeVqasFLVwbnwmjLhBTwfNminhaTfCo+ptOW2JT+IgY2WYBGIKXQmhaPPU5bdsHCur7O2RmY5tUAmvqv7V+kog==} engines: {node: '>=16.20.0'} cpu: [x64] os: [darwin] - '@typescript/native-preview-linux-arm64@7.0.0-dev.20260517.1': - resolution: {integrity: sha512-u+xY12IarGGRFXh7hbN/cxW5aYNdwa84mG0pyXglvThXT0rzzPGUEJdxVkNBo6UHqnc4FJihdcaioWpXBxQe9w==} + '@typescript/native-preview-linux-arm64@7.0.0-dev.20260523.1': + resolution: {integrity: sha512-2Jd0iJOd77LLwsEDFc9O5nfPxvs75d1FafG7BhGGlfD8RtxL4+BzAy8KYI0++TTmHL6aL7+VIr3+TQ58S68Sfw==} engines: {node: '>=16.20.0'} cpu: [arm64] os: [linux] - '@typescript/native-preview-linux-arm@7.0.0-dev.20260517.1': - resolution: {integrity: sha512-CJZJ21rSBtBxmfebMh8K/kH+e3Z+s8hM2+4ud0ZesEBgkBjePBo6FR4/1IJl38i4OvYnpbZerANR0yCRytv/Pw==} + '@typescript/native-preview-linux-arm@7.0.0-dev.20260523.1': + resolution: {integrity: sha512-C+fOL4DO/JTLkKT22Bw34FGiUpS4scqC+5AaaCVBCiHWXn1NknSrbvcMWEmg8HzCWPmiUwSQUryNZIFDqi8tUw==} engines: {node: '>=16.20.0'} cpu: [arm] os: [linux] - '@typescript/native-preview-linux-x64@7.0.0-dev.20260517.1': - resolution: {integrity: sha512-yRnlMPugNitsW9lBBQVfy8NgeUrgenjspq2LKeYmaAlvw6uf1bkbSHw6hJeCpl1oh7kH+RAHUx0yzm/RlfFdKg==} + '@typescript/native-preview-linux-x64@7.0.0-dev.20260523.1': + resolution: {integrity: sha512-DiJLdnzh/TolhvDuGxqD1sxlQNnCFLsLLnGPVN6i+/DUPC/cWy0c+5RHruow9lQbtPkZ3aapztkYP2wEP1Ll6Q==} engines: {node: '>=16.20.0'} cpu: [x64] os: [linux] - '@typescript/native-preview-win32-arm64@7.0.0-dev.20260517.1': - resolution: {integrity: sha512-fomiKzxtXrrasjJWbwaC8BGbzVQQv0VYVWijF0yKdXqxXjDRD01zT72Z1sjQGz0QJ19TVTVhJiNa7nI3wUaEsw==} + '@typescript/native-preview-win32-arm64@7.0.0-dev.20260523.1': + resolution: {integrity: sha512-axyNrdvX4D6T5ZuZHhufFbPRiKzJyqxusLl5nI3wJqmGN3G5JYCJY9k39LjRYI6oB3ingyKng+3QJ2q7b3IHQA==} engines: {node: '>=16.20.0'} cpu: [arm64] os: [win32] - '@typescript/native-preview-win32-x64@7.0.0-dev.20260517.1': - resolution: {integrity: sha512-ekFca6XpdGIfLwqaRSm0GzYvI1COhoN+a62KeSwmaZN8EGWN/Rwrp/Tm9VjWGrdHSOLQFdEAGNibmp4bRB4HyA==} + '@typescript/native-preview-win32-x64@7.0.0-dev.20260523.1': + resolution: {integrity: sha512-NRBlDy12DLqCC7smCWlEgsiwCxUUl0TAVLUikm+c+WvFhnsY909jk1X8FNUHhNZmR3APHS57AMOq2rreQwHdiQ==} engines: {node: '>=16.20.0'} cpu: [x64] os: [win32] - '@typescript/native-preview@7.0.0-dev.20260517.1': - resolution: {integrity: sha512-RSenvv0X4Uubpqyq9Z28xucCqpt5Gm/YaBs04b2Chps+qxYH+sRhYlLoiRkCx9x7Kxx6WLK3mjP+Xj6YNxHZjg==} + '@typescript/native-preview@7.0.0-dev.20260523.1': + resolution: {integrity: sha512-+pkICUeoIbnecsvkEQFmkBC7qQqR5ltQQl+bXuGpKBOURVu2/zDA4i09Ef4KWWD6Kmx7i/EMO2fMZ3IsZEdzPw==} engines: {node: '>=16.20.0'} hasBin: true @@ -4312,6 +4320,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + baseline-browser-mapping@2.10.32: + resolution: {integrity: sha512-wbPvpyjJPC0zdfdKXxqEL3Ea+bOMD/87X4lftiJkkaBiuG6ALQy1SLmEd7BSmVCuwCQsBrCamgBoLyfFDD1EPg==} + engines: {node: '>=6.0.0'} + hasBin: true + beasties@0.4.1: resolution: {integrity: sha512-2Imdcw3LznDuxAbJM26RHniOLAzE6WgrK8OuvVXCQtNBS8rsnD9zsSEa3fHl4hHpUY7BYTlrpvtPVbvu9G6neg==} engines: {node: '>=18.0.0'} @@ -4649,6 +4662,10 @@ packages: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} + content-type@2.0.0: + resolution: {integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==} + engines: {node: '>=18'} + conventional-changelog-angular@7.0.0: resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} engines: {node: '>=16'} @@ -5064,8 +5081,8 @@ packages: engines: {node: '>=0.12.18'} hasBin: true - electron-to-chromium@1.5.358: - resolution: {integrity: sha512-EO7tKm3QxRqTs1lSuPXzl6yRAwznehp0AH9OoMOIC+4mQzTFday8FJCO5KU6J/TFSQXEOahNq4vTKpz1jmCVOA==} + electron-to-chromium@1.5.361: + resolution: {integrity: sha512-Q6Hts7N9FnJc5LeGRINFvLhCI9xZmNtTDe5ZbcVezQz7cU4a8Aua3GH1b8J2XY8Al9PF+OCwYqhgsOOheMdvkA==} email-addresses@5.0.0: resolution: {integrity: sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==} @@ -5624,8 +5641,8 @@ packages: hastscript@9.0.1: resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} - hono@4.12.19: - resolution: {integrity: sha512-xa3eYXYXx68XTT4hZ7dRzsXBhaq85ToSrlUJNoR0gwz/1Ap/CNwX47wfvV7pc/xWhjKVVkLT7zBJy8chhNguqQ==} + hono@4.12.22: + resolution: {integrity: sha512-7fvVPbB92zNRsQke+uiRGwtTuef0tB2Dg4hWxYfFNvkQhIltWoyi0ONReM5LWA+jJWS3nfT5lTq+qbsIpX0IQw==} engines: {node: '>=16.9.0'} hookable@6.1.1: @@ -6199,8 +6216,8 @@ packages: koa-compose@4.1.0: resolution: {integrity: sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==} - koa@3.2.0: - resolution: {integrity: sha512-TrM4/tnNY7uJ1aW55sIIa+dqBvc4V14WRIAlGcWat9wV5pRS9Wr5Zk2ZTjQP1jtfIHDoHiSbPuV08P0fUZo2pg==} + koa@3.2.1: + resolution: {integrity: sha512-e7IpWJrnanNUroVK2taAgMxoEZvHLXdQiNjeExSu/DEIWm83jaKGBgb7tLmu2rMYpA027qFB3iLR/k3AVpFRnA==} engines: {node: '>= 18'} langium@4.2.2: @@ -6801,8 +6818,9 @@ packages: node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - node-releases@2.0.44: - resolution: {integrity: sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==} + node-releases@2.0.46: + resolution: {integrity: sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==} + engines: {node: '>=18'} nopt@8.1.0: resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} @@ -7211,8 +7229,8 @@ packages: resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} - postcss@8.5.14: - resolution: {integrity: sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==} + postcss@8.5.15: + resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} engines: {node: ^10 || ^12 || >=14} prettier@3.8.3: @@ -7317,8 +7335,8 @@ packages: peerDependencies: react: ^19.2.6 - react-hook-form@7.76.0: - resolution: {integrity: sha512-eKtLGgFeSgkHqQD8J59AMZ9a4uD1D83iSIzt4YlTGD7liDen5rrjcUO1rVIGd9yC1gofryjtHbv+4ny4hkLWlw==} + react-hook-form@7.76.1: + resolution: {integrity: sha512-rYM7tPiWlu3nZchkR/ex7piyzui2vFPyaLnXnI/RnblB/L4qfMmyses8llJVtF1NpE9WBBsJlGtcSZzPCXW1qQ==} engines: {node: '>=18.0.0'} peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 @@ -7644,6 +7662,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.8.1: + resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==} + engines: {node: '>=10'} + hasBin: true + send@1.2.1: resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} engines: {node: '>= 18'} @@ -7700,6 +7723,10 @@ packages: resolution: {integrity: sha512-/fUgUhYghuLzVT/gaJoeVehLCgZiUxPCPMcyVNY0lIf/cTCz58K/WTI7PefDarXxp9nUKpEwg1yyz3eSBMTtgA==} engines: {node: ^20.17.0 || >=22.9.0} + sigstore@4.1.1: + resolution: {integrity: sha512-endqECJkfhozrXMK5ngu/UAA0xVcVEFdnHJCElGaExypjW+HK5i6zu3NteLoaX/iFbRUbC3+DjttQs0GARr+5w==} + engines: {node: ^20.17.0 || >=22.9.0} + slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -8063,8 +8090,8 @@ packages: resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} engines: {node: '>=0.6.x'} - tsx@4.22.1: - resolution: {integrity: sha512-TvncJykhxAzFCk0VQZKBTClall4Pm7qXDSodb6uxi8QFa8X8mT6ABjxxsQ2opDRYxG7AzcRWXaFtruz5HJKuWg==} + tsx@4.22.3: + resolution: {integrity: sha512-mdoNxBC/cSQObGGVQ5Bpn5i+yv7j68gk3Nfm3wFjcJg3Z0Mix9jzAFfP12prmm5eVGmDKtp0yyArrs0Q+8gZHg==} engines: {node: '>=18.0.0'} hasBin: true @@ -8112,6 +8139,10 @@ packages: resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} engines: {node: '>= 0.6'} + type-is@2.1.0: + resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} + engines: {node: '>= 18'} + typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} @@ -8590,14 +8621,14 @@ snapshots: '@andrewbranch/untar.js@1.0.3': {} - '@angular-devkit/architect@0.2102.11(chokidar@5.0.0)': + '@angular-devkit/architect@0.2102.12(chokidar@5.0.0)': dependencies: - '@angular-devkit/core': 21.2.11(chokidar@5.0.0) + '@angular-devkit/core': 21.2.12(chokidar@5.0.0) rxjs: 7.8.2 transitivePeerDependencies: - chokidar - '@angular-devkit/core@21.2.11(chokidar@5.0.0)': + '@angular-devkit/core@21.2.12(chokidar@5.0.0)': dependencies: ajv: 8.18.0 ajv-formats: 3.0.1(ajv@8.18.0) @@ -8608,9 +8639,9 @@ snapshots: optionalDependencies: chokidar: 5.0.0 - '@angular-devkit/schematics@21.2.11(chokidar@5.0.0)': + '@angular-devkit/schematics@21.2.12(chokidar@5.0.0)': dependencies: - '@angular-devkit/core': 21.2.11(chokidar@5.0.0) + '@angular-devkit/core': 21.2.12(chokidar@5.0.0) jsonc-parser: 3.3.1 magic-string: 0.30.21 ora: 9.3.0 @@ -8618,17 +8649,17 @@ snapshots: transitivePeerDependencies: - chokidar - '@angular/build@21.2.11(@angular/compiler-cli@21.2.13(@angular/compiler@21.2.13)(typescript@6.0.3))(@angular/compiler@21.2.13)(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(@angular/platform-browser@21.2.13(@angular/common@21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2)))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.19)(chokidar@5.0.0)(postcss@8.5.14)(tslib@2.8.1)(tsx@4.22.1)(typescript@6.0.3)(yaml@2.9.0)': + '@angular/build@21.2.12(@angular/compiler-cli@21.2.14(@angular/compiler@21.2.14)(typescript@6.0.3))(@angular/compiler@21.2.14)(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(@angular/platform-browser@21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.19)(chokidar@5.0.0)(postcss@8.5.15)(tslib@2.8.1)(tsx@4.22.3)(typescript@6.0.3)(yaml@2.9.0)': dependencies: '@ampproject/remapping': 2.3.0 - '@angular-devkit/architect': 0.2102.11(chokidar@5.0.0) - '@angular/compiler': 21.2.13 - '@angular/compiler-cli': 21.2.13(@angular/compiler@21.2.13)(typescript@6.0.3) + '@angular-devkit/architect': 0.2102.12(chokidar@5.0.0) + '@angular/compiler': 21.2.14 + '@angular/compiler-cli': 21.2.14(@angular/compiler@21.2.14)(typescript@6.0.3) '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-split-export-declaration': 7.24.7 '@inquirer/confirm': 5.1.21(@types/node@22.19.19) - '@vitejs/plugin-basic-ssl': 2.1.4(vite@7.3.2(@types/node@22.19.19)(sass@1.97.3)(tsx@4.22.1)(yaml@2.9.0)) + '@vitejs/plugin-basic-ssl': 2.1.4(vite@7.3.2(@types/node@22.19.19)(sass@1.97.3)(tsx@4.22.3)(yaml@2.9.0)) beasties: 0.4.1 browserslist: 4.28.2 esbuild: 0.27.3 @@ -8649,13 +8680,13 @@ snapshots: tslib: 2.8.1 typescript: 6.0.3 undici: 7.24.4 - vite: 7.3.2(@types/node@22.19.19)(sass@1.97.3)(tsx@4.22.1)(yaml@2.9.0) + vite: 7.3.2(@types/node@22.19.19)(sass@1.97.3)(tsx@4.22.3)(yaml@2.9.0) watchpack: 2.5.1 optionalDependencies: - '@angular/core': 21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2) - '@angular/platform-browser': 21.2.13(@angular/common@21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2)) + '@angular/core': 21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2) + '@angular/platform-browser': 21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)) lmdb: 3.5.1 - postcss: 8.5.14 + postcss: 8.5.15 transitivePeerDependencies: - '@emnapi/core' - '@emnapi/runtime' @@ -8671,15 +8702,15 @@ snapshots: - tsx - yaml - '@angular/cli@21.2.11(@types/node@22.19.19)(chokidar@5.0.0)': + '@angular/cli@21.2.12(@types/node@22.19.19)(chokidar@5.0.0)': dependencies: - '@angular-devkit/architect': 0.2102.11(chokidar@5.0.0) - '@angular-devkit/core': 21.2.11(chokidar@5.0.0) - '@angular-devkit/schematics': 21.2.11(chokidar@5.0.0) + '@angular-devkit/architect': 0.2102.12(chokidar@5.0.0) + '@angular-devkit/core': 21.2.12(chokidar@5.0.0) + '@angular-devkit/schematics': 21.2.12(chokidar@5.0.0) '@inquirer/prompts': 7.10.1(@types/node@22.19.19) '@listr2/prompt-adapter-inquirer': 3.0.5(@inquirer/prompts@7.10.1(@types/node@22.19.19))(@types/node@22.19.19)(listr2@9.0.5) '@modelcontextprotocol/sdk': 1.26.0(zod@4.3.6) - '@schematics/angular': 21.2.11(chokidar@5.0.0) + '@schematics/angular': 21.2.12(chokidar@5.0.0) '@yarnpkg/lockfile': 1.1.0 algoliasearch: 5.48.1 ini: 6.0.0 @@ -8697,21 +8728,21 @@ snapshots: - chokidar - supports-color - '@angular/common@21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2)': + '@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2)': dependencies: - '@angular/core': 21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2) + '@angular/core': 21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/compiler-cli@21.2.13(@angular/compiler@21.2.13)(typescript@6.0.3)': + '@angular/compiler-cli@21.2.14(@angular/compiler@21.2.14)(typescript@6.0.3)': dependencies: - '@angular/compiler': 21.2.13 + '@angular/compiler': 21.2.14 '@babel/core': 7.29.0 '@jridgewell/sourcemap-codec': 1.5.5 chokidar: 5.0.0 convert-source-map: 1.9.0 reflect-metadata: 0.2.2 - semver: 7.8.0 + semver: 7.8.1 tslib: 2.8.1 yargs: 18.0.0 optionalDependencies: @@ -8719,37 +8750,37 @@ snapshots: transitivePeerDependencies: - supports-color - '@angular/compiler@21.2.13': + '@angular/compiler@21.2.14': dependencies: tslib: 2.8.1 - '@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2)': + '@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)': dependencies: rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@angular/compiler': 21.2.13 + '@angular/compiler': 21.2.14 - '@angular/forms@21.2.13(@angular/common@21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(@angular/platform-browser@21.2.13(@angular/common@21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2)))(rxjs@7.8.2)': + '@angular/forms@21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(@angular/platform-browser@21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2) - '@angular/core': 21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2) - '@angular/platform-browser': 21.2.13(@angular/common@21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2)) + '@angular/common': 21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2) + '@angular/core': 21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2) + '@angular/platform-browser': 21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)) '@standard-schema/spec': 1.1.0 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/platform-browser@21.2.13(@angular/common@21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))': + '@angular/platform-browser@21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))': dependencies: - '@angular/common': 21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2) - '@angular/core': 21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2) + '@angular/common': 21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2) + '@angular/core': 21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2) tslib: 2.8.1 - '@angular/router@21.2.13(@angular/common@21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(@angular/platform-browser@21.2.13(@angular/common@21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2)))(rxjs@7.8.2)': + '@angular/router@21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(@angular/platform-browser@21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2) - '@angular/core': 21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2) - '@angular/platform-browser': 21.2.13(@angular/common@21.2.13(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.13(@angular/compiler@21.2.13)(rxjs@7.8.2)) + '@angular/common': 21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2) + '@angular/core': 21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2) + '@angular/platform-browser': 21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)) rxjs: 7.8.2 tslib: 2.8.1 @@ -9346,14 +9377,14 @@ snapshots: react-dom: 19.2.6(react@19.2.6) use-sync-external-store: 1.6.0(react@19.2.6) - '@hono/node-server@1.19.14(hono@4.12.19)': + '@hono/node-server@1.19.14(hono@4.12.22)': dependencies: - hono: 4.12.19 + hono: 4.12.22 - '@hookform/resolvers@5.2.2(react-hook-form@7.76.0(react@19.2.6))': + '@hookform/resolvers@5.4.0(react-hook-form@7.76.1(react@19.2.6))': dependencies: '@standard-schema/utils': 0.3.0 - react-hook-form: 7.76.0(react@19.2.6) + react-hook-form: 7.76.1(react@19.2.6) '@hutson/parse-repository-url@3.0.2': {} @@ -9971,11 +10002,11 @@ snapshots: dependencies: vary: 1.1.2 - '@koa/router@15.5.0(koa@3.2.0)': + '@koa/router@15.5.0(koa@3.2.1)': dependencies: debug: 4.4.3(supports-color@7.2.0) http-errors: 2.0.1 - koa: 3.2.0 + koa: 3.2.1 koa-compose: 4.1.0 path-to-regexp: 8.4.2 transitivePeerDependencies: @@ -10050,7 +10081,7 @@ snapshots: '@modelcontextprotocol/sdk@1.26.0(zod@4.3.6)': dependencies: - '@hono/node-server': 1.19.14(hono@4.12.19) + '@hono/node-server': 1.19.14(hono@4.12.22) ajv: 8.20.0 ajv-formats: 3.0.1(ajv@8.20.0) content-type: 1.0.5 @@ -10060,7 +10091,7 @@ snapshots: eventsource-parser: 3.0.8 express: 5.2.1 express-rate-limit: 8.5.2(express@5.2.1) - hono: 4.12.19 + hono: 4.12.22 jose: 6.2.3 json-schema-typed: 8.0.2 pkce-challenge: 5.0.1 @@ -10358,7 +10389,7 @@ snapshots: npm-pick-manifest: 10.0.0 proc-log: 5.0.0 promise-retry: 2.0.1 - semver: 7.8.0 + semver: 7.7.2 which: 5.0.0 '@npmcli/git@7.0.2': @@ -10929,10 +10960,10 @@ snapshots: dependencies: '@scalar/openapi-types': 0.8.0 - '@schematics/angular@21.2.11(chokidar@5.0.0)': + '@schematics/angular@21.2.12(chokidar@5.0.0)': dependencies: - '@angular-devkit/core': 21.2.11(chokidar@5.0.0) - '@angular-devkit/schematics': 21.2.11(chokidar@5.0.0) + '@angular-devkit/core': 21.2.12(chokidar@5.0.0) + '@angular-devkit/schematics': 21.2.12(chokidar@5.0.0) jsonc-parser: 3.3.1 transitivePeerDependencies: - chokidar @@ -10985,6 +11016,8 @@ snapshots: '@sigstore/core@3.2.0': {} + '@sigstore/core@3.2.1': {} + '@sigstore/protobuf-specs@0.5.1': {} '@sigstore/sign@4.1.1': @@ -11011,6 +11044,12 @@ snapshots: '@sigstore/core': 3.2.0 '@sigstore/protobuf-specs': 0.5.1 + '@sigstore/verify@3.1.1': + dependencies: + '@sigstore/bundle': 4.0.0 + '@sigstore/core': 3.2.1 + '@sigstore/protobuf-specs': 0.5.1 + '@sinclair/typebox@0.34.49': {} '@sinonjs/commons@3.0.1': @@ -11372,9 +11411,9 @@ snapshots: '@types/koa-compose@3.2.9': dependencies: - '@types/koa': 3.0.2 + '@types/koa': 3.0.3 - '@types/koa@3.0.2': + '@types/koa@3.0.3': dependencies: '@types/accepts': 1.3.7 '@types/content-disposition': 0.5.9 @@ -11387,7 +11426,7 @@ snapshots: '@types/koa__cors@5.0.1': dependencies: - '@types/koa': 3.0.2 + '@types/koa': 3.0.3 '@types/lodash@4.17.24': {} @@ -11415,11 +11454,11 @@ snapshots: '@types/range-parser@1.2.7': {} - '@types/react-dom@19.2.3(@types/react@19.2.14)': + '@types/react-dom@19.2.3(@types/react@19.2.15)': dependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - '@types/react@19.2.14': + '@types/react@19.2.15': dependencies: csstype: 3.2.3 @@ -11449,36 +11488,36 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260517.1': + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260523.1': optional: true - '@typescript/native-preview-darwin-x64@7.0.0-dev.20260517.1': + '@typescript/native-preview-darwin-x64@7.0.0-dev.20260523.1': optional: true - '@typescript/native-preview-linux-arm64@7.0.0-dev.20260517.1': + '@typescript/native-preview-linux-arm64@7.0.0-dev.20260523.1': optional: true - '@typescript/native-preview-linux-arm@7.0.0-dev.20260517.1': + '@typescript/native-preview-linux-arm@7.0.0-dev.20260523.1': optional: true - '@typescript/native-preview-linux-x64@7.0.0-dev.20260517.1': + '@typescript/native-preview-linux-x64@7.0.0-dev.20260523.1': optional: true - '@typescript/native-preview-win32-arm64@7.0.0-dev.20260517.1': + '@typescript/native-preview-win32-arm64@7.0.0-dev.20260523.1': optional: true - '@typescript/native-preview-win32-x64@7.0.0-dev.20260517.1': + '@typescript/native-preview-win32-x64@7.0.0-dev.20260523.1': optional: true - '@typescript/native-preview@7.0.0-dev.20260517.1': + '@typescript/native-preview@7.0.0-dev.20260523.1': optionalDependencies: - '@typescript/native-preview-darwin-arm64': 7.0.0-dev.20260517.1 - '@typescript/native-preview-darwin-x64': 7.0.0-dev.20260517.1 - '@typescript/native-preview-linux-arm': 7.0.0-dev.20260517.1 - '@typescript/native-preview-linux-arm64': 7.0.0-dev.20260517.1 - '@typescript/native-preview-linux-x64': 7.0.0-dev.20260517.1 - '@typescript/native-preview-win32-arm64': 7.0.0-dev.20260517.1 - '@typescript/native-preview-win32-x64': 7.0.0-dev.20260517.1 + '@typescript/native-preview-darwin-arm64': 7.0.0-dev.20260523.1 + '@typescript/native-preview-darwin-x64': 7.0.0-dev.20260523.1 + '@typescript/native-preview-linux-arm': 7.0.0-dev.20260523.1 + '@typescript/native-preview-linux-arm64': 7.0.0-dev.20260523.1 + '@typescript/native-preview-linux-x64': 7.0.0-dev.20260523.1 + '@typescript/native-preview-win32-arm64': 7.0.0-dev.20260523.1 + '@typescript/native-preview-win32-x64': 7.0.0-dev.20260523.1 '@typescript/vfs@1.6.4(typescript@6.0.3)': dependencies: @@ -11634,9 +11673,9 @@ snapshots: d3-selection: 3.0.0 d3-transition: 3.0.1(d3-selection@3.0.0) - '@vitejs/plugin-basic-ssl@2.1.4(vite@7.3.2(@types/node@22.19.19)(sass@1.97.3)(tsx@4.22.1)(yaml@2.9.0))': + '@vitejs/plugin-basic-ssl@2.1.4(vite@7.3.2(@types/node@22.19.19)(sass@1.97.3)(tsx@4.22.3)(yaml@2.9.0))': dependencies: - vite: 7.3.2(@types/node@22.19.19)(sass@1.97.3)(tsx@4.22.1)(yaml@2.9.0) + vite: 7.3.2(@types/node@22.19.19)(sass@1.97.3)(tsx@4.22.3)(yaml@2.9.0) '@xmldom/xmldom@0.9.10': {} @@ -11868,6 +11907,8 @@ snapshots: baseline-browser-mapping@2.10.30: {} + baseline-browser-mapping@2.10.32: {} + beasties@0.4.1: dependencies: css-select: 6.0.0 @@ -11876,9 +11917,9 @@ snapshots: domhandler: 5.0.3 htmlparser2: 10.1.0 picocolors: 1.1.1 - postcss: 8.5.14 + postcss: 8.5.15 postcss-media-query-parser: 0.2.3 - postcss-safe-parser: 7.0.1(postcss@8.5.14) + postcss-safe-parser: 7.0.1(postcss@8.5.15) before-after-hook@2.2.3: {} @@ -11942,10 +11983,10 @@ snapshots: browserslist@4.28.2: dependencies: - baseline-browser-mapping: 2.10.30 + baseline-browser-mapping: 2.10.32 caniuse-lite: 1.0.30001793 - electron-to-chromium: 1.5.358 - node-releases: 2.0.44 + electron-to-chromium: 1.5.361 + node-releases: 2.0.46 update-browserslist-db: 1.2.3(browserslist@4.28.2) bser@2.1.1: @@ -12193,6 +12234,8 @@ snapshots: content-type@1.0.5: {} + content-type@2.0.0: {} + conventional-changelog-angular@7.0.0: dependencies: compare-func: 2.0.0 @@ -12220,7 +12263,7 @@ snapshots: handlebars: 4.7.9 json-stringify-safe: 5.0.1 meow: 8.1.2 - semver: 7.8.0 + semver: 7.7.2 split: 1.0.1 conventional-commits-filter@3.0.0: @@ -12613,7 +12656,7 @@ snapshots: ejs@5.0.1: {} - electron-to-chromium@1.5.358: {} + electron-to-chromium@1.5.361: {} email-addresses@5.0.0: {} @@ -13108,7 +13151,7 @@ snapshots: git-semver-tags@5.0.1: dependencies: meow: 8.1.2 - semver: 7.8.0 + semver: 7.7.2 git-up@7.0.0: dependencies: @@ -13357,7 +13400,7 @@ snapshots: property-information: 7.1.0 space-separated-tokens: 2.0.2 - hono@4.12.19: {} + hono@4.12.22: {} hookable@6.1.1: {} @@ -13922,7 +13965,7 @@ snapshots: jest-message-util: 30.4.1 jest-util: 30.4.1 pretty-format: 30.4.1 - semver: 7.8.0 + semver: 7.8.1 synckit: 0.11.12 transitivePeerDependencies: - supports-color @@ -14054,7 +14097,7 @@ snapshots: dependencies: '@types/co-body': 6.1.3 '@types/formidable': 3.5.1 - '@types/koa': 3.0.2 + '@types/koa': 3.0.3 co-body: 6.2.0 formidable: 3.5.4 type-fest: 5.6.0 @@ -14062,7 +14105,7 @@ snapshots: koa-compose@4.1.0: {} - koa@3.2.0: + koa@3.2.1: dependencies: accepts: 1.3.8 content-disposition: 1.0.1 @@ -14080,7 +14123,7 @@ snapshots: on-finished: 2.4.1 parseurl: 1.3.3 statuses: 2.0.2 - type-is: 2.0.1 + type-is: 2.1.0 vary: 1.1.2 langium@4.2.2: @@ -14315,7 +14358,7 @@ snapshots: make-dir@4.0.0: dependencies: - semver: 7.8.0 + semver: 7.8.1 make-fetch-happen@15.0.2: dependencies: @@ -15092,7 +15135,7 @@ snapshots: - '@babel/core' - babel-plugin-macros - nextra-theme-docs@4.6.1(@types/react@19.2.14)(next@16.2.6(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.97.3))(nextra@4.6.1(next@16.2.6(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.97.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6)): + nextra-theme-docs@4.6.1(@types/react@19.2.15)(next@16.2.6(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.97.3))(nextra@4.6.1(next@16.2.6(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.97.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6)): dependencies: '@headlessui/react': 2.2.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6) clsx: 2.1.1 @@ -15104,7 +15147,7 @@ snapshots: react-dom: 19.2.6(react@19.2.6) scroll-into-view-if-needed: 3.1.0 zod: 4.3.6 - zustand: 5.0.12(@types/react@19.2.14)(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6)) + zustand: 5.0.12(@types/react@19.2.15)(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6)) transitivePeerDependencies: - '@types/react' - immer @@ -15180,7 +15223,7 @@ snapshots: graceful-fs: 4.2.11 nopt: 9.0.0 proc-log: 6.1.0 - semver: 7.8.0 + semver: 7.7.2 tar: 7.5.15 tinyglobby: 0.2.16 undici: 6.25.0 @@ -15188,7 +15231,7 @@ snapshots: node-int64@0.4.0: {} - node-releases@2.0.44: {} + node-releases@2.0.46: {} nopt@8.1.0: dependencies: @@ -15209,7 +15252,7 @@ snapshots: dependencies: hosted-git-info: 4.1.0 is-core-module: 2.16.1 - semver: 7.8.0 + semver: 7.7.2 validate-npm-package-license: 3.0.4 normalize-path@3.0.0: {} @@ -15238,7 +15281,7 @@ snapshots: dependencies: hosted-git-info: 8.1.0 proc-log: 5.0.0 - semver: 7.8.0 + semver: 7.7.2 validate-npm-package-name: 6.0.2 npm-package-arg@13.0.1: @@ -15252,7 +15295,7 @@ snapshots: dependencies: hosted-git-info: 9.0.3 proc-log: 6.1.0 - semver: 7.8.0 + semver: 7.7.4 validate-npm-package-name: 7.0.2 npm-packlist@10.0.3: @@ -15270,7 +15313,7 @@ snapshots: npm-install-checks: 7.1.2 npm-normalize-package-bin: 4.0.0 npm-package-arg: 12.0.2 - semver: 7.8.0 + semver: 7.7.2 npm-pick-manifest@11.0.3: dependencies: @@ -15604,7 +15647,7 @@ snapshots: npm-registry-fetch: 19.1.1 proc-log: 6.1.0 promise-retry: 2.0.1 - sigstore: 4.1.0 + sigstore: 4.1.1 ssri: 13.0.1 tar: 7.5.15 transitivePeerDependencies: @@ -15778,9 +15821,9 @@ snapshots: postcss-media-query-parser@0.2.3: {} - postcss-safe-parser@7.0.1(postcss@8.5.14): + postcss-safe-parser@7.0.1(postcss@8.5.15): dependencies: - postcss: 8.5.14 + postcss: 8.5.15 postcss-selector-parser@7.1.1: dependencies: @@ -15793,7 +15836,7 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - postcss@8.5.14: + postcss@8.5.15: dependencies: nanoid: 3.3.12 picocolors: 1.1.1 @@ -15898,7 +15941,7 @@ snapshots: react: 19.2.6 scheduler: 0.27.0 - react-hook-form@7.76.0(react@19.2.6): + react-hook-form@7.76.1(react@19.2.6): dependencies: react: 19.2.6 @@ -16216,7 +16259,7 @@ snapshots: robust-predicates@3.0.3: {} - rolldown-plugin-dts@0.25.1(@typescript/native-preview@7.0.0-dev.20260517.1)(rolldown@1.0.1)(typescript@6.0.3): + rolldown-plugin-dts@0.25.1(@typescript/native-preview@7.0.0-dev.20260523.1)(rolldown@1.0.1)(typescript@6.0.3): dependencies: '@babel/generator': 8.0.0-rc.5 '@babel/helper-validator-identifier': 8.0.0-rc.5 @@ -16228,7 +16271,7 @@ snapshots: obug: 2.1.1 rolldown: 1.0.1 optionalDependencies: - '@typescript/native-preview': 7.0.0-dev.20260517.1 + '@typescript/native-preview': 7.0.0-dev.20260523.1 typescript: 6.0.3 transitivePeerDependencies: - oxc-resolver @@ -16392,6 +16435,8 @@ snapshots: semver@7.8.0: {} + semver@7.8.1: {} + send@1.2.1: dependencies: debug: 4.4.3(supports-color@7.2.0) @@ -16425,7 +16470,7 @@ snapshots: dependencies: '@img/colour': 1.1.0 detect-libc: 2.1.2 - semver: 7.8.0 + semver: 7.8.1 optionalDependencies: '@img/sharp-darwin-arm64': 0.34.5 '@img/sharp-darwin-x64': 0.34.5 @@ -16513,6 +16558,17 @@ snapshots: transitivePeerDependencies: - supports-color + sigstore@4.1.1: + dependencies: + '@sigstore/bundle': 4.0.0 + '@sigstore/core': 3.2.1 + '@sigstore/protobuf-specs': 0.5.1 + '@sigstore/sign': 4.1.1 + '@sigstore/tuf': 4.0.2 + '@sigstore/verify': 3.1.1 + transitivePeerDependencies: + - supports-color + slash@3.0.0: {} slash@5.1.0: {} @@ -16820,7 +16876,7 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 - tsdown@0.22.0(@arethetypeswrong/core@0.18.2)(@typescript/native-preview@7.0.0-dev.20260517.1)(publint@0.3.21)(tsx@4.22.1)(typescript@6.0.3)(unrun@0.2.37(synckit@0.11.12)): + tsdown@0.22.0(@arethetypeswrong/core@0.18.2)(@typescript/native-preview@7.0.0-dev.20260523.1)(publint@0.3.21)(tsx@4.22.3)(typescript@6.0.3)(unrun@0.2.37(synckit@0.11.12)): dependencies: ansis: 4.3.0 cac: 7.0.0 @@ -16831,7 +16887,7 @@ snapshots: obug: 2.1.1 picomatch: 4.0.4 rolldown: 1.0.1 - rolldown-plugin-dts: 0.25.1(@typescript/native-preview@7.0.0-dev.20260517.1)(rolldown@1.0.1)(typescript@6.0.3) + rolldown-plugin-dts: 0.25.1(@typescript/native-preview@7.0.0-dev.20260523.1)(rolldown@1.0.1)(typescript@6.0.3) semver: 7.8.0 tinyexec: 1.1.2 tinyglobby: 0.2.16 @@ -16840,7 +16896,7 @@ snapshots: optionalDependencies: '@arethetypeswrong/core': 0.18.2 publint: 0.3.21 - tsx: 4.22.1 + tsx: 4.22.3 typescript: 6.0.3 unrun: 0.2.37(synckit@0.11.12) transitivePeerDependencies: @@ -16853,7 +16909,7 @@ snapshots: tsscmp@1.0.6: {} - tsx@4.22.1: + tsx@4.22.3: dependencies: esbuild: 0.28.0 optionalDependencies: @@ -16902,6 +16958,12 @@ snapshots: media-typer: 1.1.0 mime-types: 3.0.2 + type-is@2.1.0: + dependencies: + content-type: 2.0.0 + media-typer: 1.1.0 + mime-types: 3.0.2 + typedarray@0.0.6: {} typescript@5.6.1-rc: {} @@ -17075,19 +17137,19 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite@7.3.2(@types/node@22.19.19)(sass@1.97.3)(tsx@4.22.1)(yaml@2.9.0): + vite@7.3.2(@types/node@22.19.19)(sass@1.97.3)(tsx@4.22.3)(yaml@2.9.0): dependencies: esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 - postcss: 8.5.14 + postcss: 8.5.15 rollup: 4.60.4 - tinyglobby: 0.2.16 + tinyglobby: 0.2.15 optionalDependencies: '@types/node': 22.19.19 fsevents: 2.3.3 sass: 1.97.3 - tsx: 4.22.1 + tsx: 4.22.3 yaml: 2.9.0 vscode-jsonrpc@8.2.0: {} @@ -17252,9 +17314,9 @@ snapshots: zod@4.3.6: {} - zustand@5.0.12(@types/react@19.2.14)(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6)): + zustand@5.0.12(@types/react@19.2.15)(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6)): optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 react: 19.2.6 use-sync-external-store: 1.6.0(react@19.2.6)