From d3ffedf9f984b19e52f5e45ac2b5458f327ca4dd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 00:38:42 +0000 Subject: [PATCH 01/22] chore(deps): update dependency @pinia/colada to v0.17.6 --- packages/openapi-ts-tests/main/package.json | 2 +- pnpm-lock.yaml | 358 +++++++++++++++++--- 2 files changed, 309 insertions(+), 51 deletions(-) diff --git a/packages/openapi-ts-tests/main/package.json b/packages/openapi-ts-tests/main/package.json index f66c60134..1b3347afd 100644 --- a/packages/openapi-ts-tests/main/package.json +++ b/packages/openapi-ts-tests/main/package.json @@ -30,7 +30,7 @@ "@hey-api/codegen-core": "workspace:*", "@hey-api/custom-client": "workspace:*", "@hey-api/openapi-ts": "workspace:*", - "@pinia/colada": "0.17.5", + "@pinia/colada": "0.17.6", "@tanstack/angular-query-experimental": "5.73.3", "@tanstack/react-query": "5.73.3", "@tanstack/solid-query": "5.73.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 42d174af5..5d5b2147e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1235,10 +1235,10 @@ importers: version: 1.7.4 nuxt: specifier: '>=3.0.0' - version: 3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.10.5)(db0@0.3.2)(encoding@0.1.13)(eslint@9.17.0(jiti@2.5.1))(ioredis@5.7.0)(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@3.29.5)(sass@1.85.0)(terser@5.43.1)(typescript@5.9.2)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) + version: 3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.10.5)(db0@0.3.2)(encoding@0.1.13)(eslint@9.17.0(jiti@2.5.1))(ioredis@5.7.0)(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@3.29.5)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) vue: specifier: '>=3.5.13' - version: 3.5.13(typescript@5.9.2) + version: 3.5.13(typescript@5.8.3) devDependencies: '@config/vite-base': specifier: workspace:* @@ -1248,13 +1248,13 @@ importers: version: link:../openapi-ts '@nuxt/module-builder': specifier: 0.8.4 - version: 0.8.4(@nuxt/kit@3.15.4(magicast@0.3.5))(nuxi@3.28.0)(sass@1.85.0)(typescript@5.9.2) + version: 0.8.4(@nuxt/kit@3.15.4(magicast@0.3.5))(nuxi@3.28.0)(sass@1.85.0)(typescript@5.8.3) '@nuxt/schema': specifier: 3.16.2 version: 3.16.2 '@nuxt/test-utils': specifier: 3.17.2 - version: 3.17.2(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(magicast@0.3.5)(sass@1.85.0)(terser@5.43.1)(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.10.5)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(yaml@2.8.0) + version: 3.17.2(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(magicast@0.3.5)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.10.5)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(yaml@2.8.0) vite: specifier: 7.1.2 version: 7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0) @@ -1345,7 +1345,7 @@ importers: version: 3.3.2 nuxt: specifier: 3.14.1592 - version: 3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.10.5)(db0@0.3.2)(encoding@0.1.13)(eslint@9.17.0(jiti@2.5.1))(ioredis@5.7.0)(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.50.0)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vite@7.1.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) + version: 3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.10.5)(db0@0.3.2)(encoding@0.1.13)(eslint@9.17.0(jiti@2.5.1))(ioredis@5.7.0)(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.50.0)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)) ofetch: specifier: 1.4.1 version: 1.4.1 @@ -1422,8 +1422,8 @@ importers: specifier: workspace:* version: link:../../openapi-ts '@pinia/colada': - specifier: 0.17.5 - version: 0.17.5(pinia@3.0.3(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)))(vue@3.5.13(typescript@5.8.3)) + specifier: 0.17.6 + version: 0.17.6(pinia@3.0.3(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)))(vue@3.5.13(typescript@5.8.3)) '@tanstack/angular-query-experimental': specifier: 5.73.3 version: 5.73.3(@angular/common@19.2.15(@angular/core@19.2.15(rxjs@7.8.1)(zone.js@0.15.1))(rxjs@7.8.1))(@angular/core@19.2.15(rxjs@7.8.1)(zone.js@0.15.1)) @@ -4758,6 +4758,12 @@ packages: pinia: ^2.2.6 || ^3.0.0 vue: ^3.5.17 + '@pinia/colada@0.17.6': + resolution: {integrity: sha512-odayx9xVMUgC8ZMU/hwqODoboHnSWigp7VsbKGHKrNl9yHnljmxgJMwm1vtF/KIBSd2vUBigmN3maFqcC48/Rg==} + peerDependencies: + pinia: ^2.2.6 || ^3.0.0 + vue: ^3.5.17 + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -6635,6 +6641,9 @@ packages: '@vue/devtools-api@8.0.1': resolution: {integrity: sha512-YBvjfpM7LEp5+b7ZDm4+mFrC+TgGjUmN8ff9lZcbHQ1MKhmftT/urCTZP0y1j26YQWr25l9TPaEbNLbILRiGoQ==} + '@vue/devtools-api@8.0.2': + resolution: {integrity: sha512-RdwsaYoSTumwZ7XOt5yIPP1/T4O0bTs+c5XaEjmUB6f9x+FvDSL9AekxW1vuhK1lmA9TfewpXVt2r5LIax3LHw==} + '@vue/devtools-core@7.6.8': resolution: {integrity: sha512-8X4roysTwzQ94o7IobjVcOd1aZF5iunikrMrHPI2uUdigZCi2kFTQc7ffYiFiTNaLElCpjOhCnM7bo7aK1yU7A==} peerDependencies: @@ -17723,6 +17732,16 @@ snapshots: '@nuxt/devalue@2.0.2': {} + '@nuxt/devtools-kit@1.7.0(magicast@0.3.5)(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1))': + dependencies: + '@nuxt/kit': 3.15.4(magicast@0.3.5) + '@nuxt/schema': 3.16.2 + execa: 7.2.0 + vite: 5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1) + transitivePeerDependencies: + - magicast + - supports-color + '@nuxt/devtools-kit@1.7.0(magicast@0.3.5)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))': dependencies: '@nuxt/kit': 3.15.4(magicast@0.3.5) @@ -17756,13 +17775,13 @@ snapshots: rc9: 2.1.2 semver: 7.7.2 - '@nuxt/devtools@1.7.0(rollup@3.29.5)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.13(typescript@5.9.2))': + '@nuxt/devtools@1.7.0(rollup@3.29.5)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3))': dependencies: '@antfu/utils': 0.7.10 '@nuxt/devtools-kit': 1.7.0(magicast@0.3.5)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) '@nuxt/devtools-wizard': 1.7.0 '@nuxt/kit': 3.15.4(magicast@0.3.5) - '@vue/devtools-core': 7.6.8(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.13(typescript@5.9.2)) + '@vue/devtools-core': 7.6.8(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3)) '@vue/devtools-kit': 7.6.8 birpc: 0.2.19 consola: 3.4.2 @@ -17803,6 +17822,53 @@ snapshots: - utf-8-validate - vue + '@nuxt/devtools@1.7.0(rollup@4.50.0)(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1))(vue@3.5.13(typescript@5.8.3))': + dependencies: + '@antfu/utils': 0.7.10 + '@nuxt/devtools-kit': 1.7.0(magicast@0.3.5)(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)) + '@nuxt/devtools-wizard': 1.7.0 + '@nuxt/kit': 3.15.4(magicast@0.3.5) + '@vue/devtools-core': 7.6.8(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1))(vue@3.5.13(typescript@5.8.3)) + '@vue/devtools-kit': 7.6.8 + birpc: 0.2.19 + consola: 3.4.2 + cronstrue: 2.59.0 + destr: 2.0.5 + error-stack-parser-es: 0.1.5 + execa: 7.2.0 + fast-npm-meta: 0.2.2 + flatted: 3.3.3 + get-port-please: 3.2.0 + hookable: 5.5.3 + image-meta: 0.2.1 + is-installed-globally: 1.0.0 + launch-editor: 2.11.1 + local-pkg: 0.5.1 + magicast: 0.3.5 + nypm: 0.4.1 + ohash: 1.1.6 + pathe: 1.1.2 + perfect-debounce: 1.0.0 + pkg-types: 1.3.1 + rc9: 2.1.2 + scule: 1.3.0 + semver: 7.7.2 + simple-git: 3.28.0 + sirv: 3.0.1 + tinyglobby: 0.2.10 + unimport: 3.14.6(rollup@4.50.0) + vite: 5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1) + vite-plugin-inspect: 0.8.9(@nuxt/kit@3.15.4(magicast@0.3.5))(rollup@4.50.0)(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)) + vite-plugin-vue-inspector: 5.3.2(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)) + which: 3.0.1 + ws: 8.18.3 + transitivePeerDependencies: + - bufferutil + - rollup + - supports-color + - utf-8-validate + - vue + '@nuxt/devtools@1.7.0(rollup@4.50.0)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.13(typescript@5.9.2))': dependencies: '@antfu/utils': 0.7.10 @@ -18004,7 +18070,7 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/module-builder@0.8.4(@nuxt/kit@3.15.4(magicast@0.3.5))(nuxi@3.28.0)(sass@1.85.0)(typescript@5.9.2)': + '@nuxt/module-builder@0.8.4(@nuxt/kit@3.15.4(magicast@0.3.5))(nuxi@3.28.0)(sass@1.85.0)(typescript@5.8.3)': dependencies: '@nuxt/kit': 3.15.4(magicast@0.3.5) citty: 0.1.6 @@ -18015,8 +18081,8 @@ snapshots: nuxi: 3.28.0 pathe: 1.1.2 pkg-types: 1.3.1 - tsconfck: 3.1.6(typescript@5.9.2) - unbuild: 2.0.0(sass@1.85.0)(typescript@5.9.2) + tsconfck: 3.1.6(typescript@5.8.3) + unbuild: 2.0.0(sass@1.85.0)(typescript@5.8.3) transitivePeerDependencies: - sass - supports-color @@ -18088,7 +18154,7 @@ snapshots: - magicast - supports-color - '@nuxt/test-utils@3.17.2(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(magicast@0.3.5)(sass@1.85.0)(terser@5.43.1)(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.10.5)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(yaml@2.8.0)': + '@nuxt/test-utils@3.17.2(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(magicast@0.3.5)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.10.5)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(yaml@2.8.0)': dependencies: '@nuxt/kit': 3.18.1(magicast@0.3.5) '@nuxt/schema': 3.16.2 @@ -18114,8 +18180,8 @@ snapshots: ufo: 1.6.1 unplugin: 2.3.10 vite: 6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0) - vitest-environment-nuxt: 1.0.1(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(magicast@0.3.5)(sass@1.85.0)(terser@5.43.1)(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.10.5)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(yaml@2.8.0) - vue: 3.5.13(typescript@5.9.2) + vitest-environment-nuxt: 1.0.1(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(magicast@0.3.5)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.10.5)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(yaml@2.8.0) + vue: 3.5.13(typescript@5.8.3) optionalDependencies: '@vue/test-utils': 2.4.6 jsdom: 23.0.0 @@ -18135,12 +18201,12 @@ snapshots: - typescript - yaml - '@nuxt/vite-builder@3.14.1592(@types/node@22.10.5)(eslint@9.17.0(jiti@2.5.1))(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@3.29.5)(sass@1.85.0)(terser@5.43.1)(typescript@5.9.2)(vue@3.5.13(typescript@5.9.2))': + '@nuxt/vite-builder@3.14.1592(@types/node@22.10.5)(eslint@9.17.0(jiti@2.5.1))(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@3.29.5)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3))': dependencies: '@nuxt/kit': 3.14.1592(magicast@0.3.5)(rollup@3.29.5) '@rollup/plugin-replace': 6.0.2(rollup@3.29.5) - '@vitejs/plugin-vue': 5.2.1(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1))(vue@3.5.13(typescript@5.9.2)) - '@vitejs/plugin-vue-jsx': 4.1.1(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1))(vue@3.5.13(typescript@5.9.2)) + '@vitejs/plugin-vue': 5.2.1(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1))(vue@3.5.13(typescript@5.8.3)) + '@vitejs/plugin-vue-jsx': 4.1.1(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1))(vue@3.5.13(typescript@5.8.3)) autoprefixer: 10.4.20(postcss@8.5.6) clear: 0.1.0 consola: 3.4.2 @@ -18169,8 +18235,8 @@ snapshots: unplugin: 1.16.1 vite: 5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1) vite-node: 2.1.9(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1) - vite-plugin-checker: 0.8.0(eslint@9.17.0(jiti@2.5.1))(optionator@0.9.4)(typescript@5.9.2)(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)) - vue: 3.5.13(typescript@5.9.2) + vite-plugin-checker: 0.8.0(eslint@9.17.0(jiti@2.5.1))(optionator@0.9.4)(typescript@5.8.3)(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)) + vue: 3.5.13(typescript@5.8.3) vue-bundle-renderer: 2.1.2 transitivePeerDependencies: - '@biomejs/biome' @@ -18390,6 +18456,12 @@ snapshots: pinia: 3.0.3(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)) vue: 3.5.13(typescript@5.8.3) + '@pinia/colada@0.17.6(pinia@3.0.3(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)))(vue@3.5.13(typescript@5.8.3))': + dependencies: + '@vue/devtools-api': 8.0.2 + pinia: 3.0.3(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)) + vue: 3.5.13(typescript@5.8.3) + '@pkgjs/parseargs@0.11.0': optional: true @@ -20490,6 +20562,34 @@ snapshots: dependencies: '@vue/devtools-kit': 8.0.1 + '@vue/devtools-api@8.0.2': + dependencies: + '@vue/devtools-kit': 8.0.2 + + '@vue/devtools-core@7.6.8(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1))(vue@3.5.13(typescript@5.8.3))': + dependencies: + '@vue/devtools-kit': 7.7.7 + '@vue/devtools-shared': 7.7.7 + mitt: 3.0.1 + nanoid: 5.1.5 + pathe: 1.1.2 + vite-hot-client: 0.2.4(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)) + vue: 3.5.13(typescript@5.8.3) + transitivePeerDependencies: + - vite + + '@vue/devtools-core@7.6.8(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3))': + dependencies: + '@vue/devtools-kit': 7.7.7 + '@vue/devtools-shared': 7.7.7 + mitt: 3.0.1 + nanoid: 5.1.5 + pathe: 1.1.2 + vite-hot-client: 0.2.4(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) + vue: 3.5.13(typescript@5.8.3) + transitivePeerDependencies: + - vite + '@vue/devtools-core@7.6.8(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.13(typescript@5.9.2))': dependencies: '@vue/devtools-kit': 7.7.7 @@ -22533,8 +22633,8 @@ snapshots: '@typescript-eslint/parser': 8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3) eslint: 9.17.0(jiti@2.5.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.17.0(jiti@2.5.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.17.0(jiti@2.5.1)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.17.0(jiti@2.5.1)) eslint-plugin-react: 7.37.5(eslint@9.17.0(jiti@2.5.1)) eslint-plugin-react-hooks: 5.2.0(eslint@9.17.0(jiti@2.5.1)) @@ -22557,7 +22657,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.17.0(jiti@2.5.1)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.1 @@ -22568,22 +22668,22 @@ snapshots: tinyglobby: 0.2.14 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.17.0(jiti@2.5.1)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.17.0(jiti@2.5.1)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3) eslint: 9.17.0(jiti@2.5.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.17.0(jiti@2.5.1)) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.17.0(jiti@2.5.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -22594,7 +22694,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.17.0(jiti@2.5.1) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.17.0(jiti@2.5.1)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -24954,7 +25054,7 @@ snapshots: mkdirp@3.0.1: {} - mkdist@1.6.0(sass@1.85.0)(typescript@5.9.2): + mkdist@1.6.0(sass@1.85.0)(typescript@5.8.3): dependencies: autoprefixer: 10.4.20(postcss@8.5.6) citty: 0.1.6 @@ -24971,7 +25071,7 @@ snapshots: tinyglobby: 0.2.14 optionalDependencies: sass: 1.85.0 - typescript: 5.9.2 + typescript: 5.8.3 mlly@1.7.4: dependencies: @@ -25345,18 +25445,18 @@ snapshots: nuxi@3.28.0: {} - nuxt@3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.10.5)(db0@0.3.2)(encoding@0.1.13)(eslint@9.17.0(jiti@2.5.1))(ioredis@5.7.0)(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@3.29.5)(sass@1.85.0)(terser@5.43.1)(typescript@5.9.2)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)): + nuxt@3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.10.5)(db0@0.3.2)(encoding@0.1.13)(eslint@9.17.0(jiti@2.5.1))(ioredis@5.7.0)(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@3.29.5)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)): dependencies: '@nuxt/devalue': 2.0.2 - '@nuxt/devtools': 1.7.0(rollup@3.29.5)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.13(typescript@5.9.2)) + '@nuxt/devtools': 1.7.0(rollup@3.29.5)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3)) '@nuxt/kit': 3.14.1592(magicast@0.3.5)(rollup@3.29.5) '@nuxt/schema': 3.14.1592(magicast@0.3.5)(rollup@3.29.5) '@nuxt/telemetry': 2.6.6(magicast@0.3.5) - '@nuxt/vite-builder': 3.14.1592(@types/node@22.10.5)(eslint@9.17.0(jiti@2.5.1))(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@3.29.5)(sass@1.85.0)(terser@5.43.1)(typescript@5.9.2)(vue@3.5.13(typescript@5.9.2)) + '@nuxt/vite-builder': 3.14.1592(@types/node@22.10.5)(eslint@9.17.0(jiti@2.5.1))(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@3.29.5)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)) '@unhead/dom': 1.11.20 '@unhead/shared': 1.11.20 '@unhead/ssr': 1.11.20 - '@unhead/vue': 1.11.20(vue@3.5.13(typescript@5.9.2)) + '@unhead/vue': 1.11.20(vue@3.5.13(typescript@5.8.3)) '@vue/shared': 3.5.20 acorn: 8.14.0 c12: 2.0.1(magicast@0.3.5) @@ -25404,13 +25504,134 @@ snapshots: unhead: 1.11.20 unimport: 3.14.6(rollup@3.29.5) unplugin: 1.16.1 - unplugin-vue-router: 0.10.9(rollup@3.29.5)(vue-router@4.5.0(vue@3.5.13(typescript@5.9.2)))(vue@3.5.13(typescript@5.9.2)) + unplugin-vue-router: 0.10.9(rollup@3.29.5)(vue-router@4.5.0(vue@3.5.13(typescript@5.8.3)))(vue@3.5.13(typescript@5.8.3)) unstorage: 1.17.0(@netlify/blobs@9.1.2)(db0@0.3.2)(ioredis@5.7.0) untyped: 1.5.2 - vue: 3.5.13(typescript@5.9.2) + vue: 3.5.13(typescript@5.8.3) vue-bundle-renderer: 2.1.2 vue-devtools-stub: 0.1.0 - vue-router: 4.5.0(vue@3.5.13(typescript@5.9.2)) + vue-router: 4.5.0(vue@3.5.13(typescript@5.8.3)) + optionalDependencies: + '@parcel/watcher': 2.5.1 + '@types/node': 22.10.5 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@biomejs/biome' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@libsql/client' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - better-sqlite3 + - bufferutil + - db0 + - drizzle-orm + - encoding + - eslint + - idb-keyval + - ioredis + - less + - lightningcss + - magicast + - meow + - mysql2 + - optionator + - rolldown + - rollup + - sass + - sass-embedded + - sqlite3 + - stylelint + - stylus + - sugarss + - supports-color + - terser + - typescript + - uploadthing + - utf-8-validate + - vite + - vls + - vti + - vue-tsc + - xml2js + + nuxt@3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.10.5)(db0@0.3.2)(encoding@0.1.13)(eslint@9.17.0(jiti@2.5.1))(ioredis@5.7.0)(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.50.0)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)): + dependencies: + '@nuxt/devalue': 2.0.2 + '@nuxt/devtools': 1.7.0(rollup@4.50.0)(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1))(vue@3.5.13(typescript@5.8.3)) + '@nuxt/kit': 3.14.1592(magicast@0.3.5)(rollup@4.50.0) + '@nuxt/schema': 3.14.1592(magicast@0.3.5)(rollup@4.50.0) + '@nuxt/telemetry': 2.6.6(magicast@0.3.5) + '@nuxt/vite-builder': 3.14.1592(@types/node@22.10.5)(eslint@9.17.0(jiti@2.5.1))(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.50.0)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)) + '@unhead/dom': 1.11.20 + '@unhead/shared': 1.11.20 + '@unhead/ssr': 1.11.20 + '@unhead/vue': 1.11.20(vue@3.5.13(typescript@5.8.3)) + '@vue/shared': 3.5.20 + acorn: 8.14.0 + c12: 2.0.1(magicast@0.3.5) + chokidar: 4.0.3 + compatx: 0.1.8 + consola: 3.4.2 + cookie-es: 1.2.2 + defu: 6.1.4 + destr: 2.0.5 + devalue: 5.3.2 + errx: 0.1.0 + esbuild: 0.24.2 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + globby: 14.1.0 + h3: 1.15.4 + hookable: 5.5.3 + ignore: 6.0.2 + impound: 0.2.2(rollup@4.50.0) + jiti: 2.5.1 + klona: 2.0.6 + knitwork: 1.2.0 + magic-string: 0.30.18 + mlly: 1.7.4 + nanotar: 0.1.1 + nitropack: 2.12.4(@netlify/blobs@9.1.2)(encoding@0.1.13) + nuxi: 3.28.0 + nypm: 0.3.12 + ofetch: 1.4.1 + ohash: 1.1.6 + pathe: 1.1.2 + perfect-debounce: 1.0.0 + pkg-types: 1.3.1 + radix3: 1.1.2 + scule: 1.3.0 + semver: 7.7.2 + std-env: 3.9.0 + strip-literal: 2.1.1 + tinyglobby: 0.2.10 + ufo: 1.6.1 + ultrahtml: 1.6.0 + uncrypto: 0.1.3 + unctx: 2.4.1 + unenv: 1.10.0 + unhead: 1.11.20 + unimport: 3.14.6(rollup@4.50.0) + unplugin: 1.16.1 + unplugin-vue-router: 0.10.9(rollup@4.50.0)(vue-router@4.5.0(vue@3.5.13(typescript@5.8.3)))(vue@3.5.13(typescript@5.8.3)) + unstorage: 1.17.0(@netlify/blobs@9.1.2)(db0@0.3.2)(ioredis@5.7.0) + untyped: 1.5.2 + vue: 3.5.13(typescript@5.8.3) + vue-bundle-renderer: 2.1.2 + vue-devtools-stub: 0.1.0 + vue-router: 4.5.0(vue@3.5.13(typescript@5.8.3)) optionalDependencies: '@parcel/watcher': 2.5.1 '@types/node': 22.10.5 @@ -26837,11 +27058,11 @@ snapshots: dependencies: glob: 7.2.3 - rollup-plugin-dts@6.1.1(rollup@3.29.5)(typescript@5.9.2): + rollup-plugin-dts@6.1.1(rollup@3.29.5)(typescript@5.8.3): dependencies: magic-string: 0.30.18 rollup: 3.29.5 - typescript: 5.9.2 + typescript: 5.8.3 optionalDependencies: '@babel/code-frame': 7.27.1 @@ -27973,9 +28194,9 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - tsconfck@3.1.6(typescript@5.9.2): + tsconfck@3.1.6(typescript@5.8.3): optionalDependencies: - typescript: 5.9.2 + typescript: 5.8.3 tsconfig-paths@3.15.0: dependencies: @@ -28141,7 +28362,7 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 - unbuild@2.0.0(sass@1.85.0)(typescript@5.9.2): + unbuild@2.0.0(sass@1.85.0)(typescript@5.8.3): dependencies: '@rollup/plugin-alias': 5.1.1(rollup@3.29.5) '@rollup/plugin-commonjs': 25.0.8(rollup@3.29.5) @@ -28158,17 +28379,17 @@ snapshots: hookable: 5.5.3 jiti: 1.21.7 magic-string: 0.30.18 - mkdist: 1.6.0(sass@1.85.0)(typescript@5.9.2) + mkdist: 1.6.0(sass@1.85.0)(typescript@5.8.3) mlly: 1.7.4 pathe: 1.1.2 pkg-types: 1.3.1 pretty-bytes: 6.1.1 rollup: 3.29.5 - rollup-plugin-dts: 6.1.1(rollup@3.29.5)(typescript@5.9.2) + rollup-plugin-dts: 6.1.1(rollup@3.29.5)(typescript@5.8.3) scule: 1.3.0 untyped: 1.5.2 optionalDependencies: - typescript: 5.9.2 + typescript: 5.8.3 transitivePeerDependencies: - sass - supports-color @@ -28366,11 +28587,11 @@ snapshots: pathe: 2.0.3 picomatch: 4.0.3 - unplugin-vue-router@0.10.9(rollup@3.29.5)(vue-router@4.5.0(vue@3.5.13(typescript@5.9.2)))(vue@3.5.13(typescript@5.9.2)): + unplugin-vue-router@0.10.9(rollup@3.29.5)(vue-router@4.5.0(vue@3.5.13(typescript@5.8.3)))(vue@3.5.13(typescript@5.8.3)): dependencies: '@babel/types': 7.28.2 '@rollup/pluginutils': 5.2.0(rollup@3.29.5) - '@vue-macros/common': 1.16.1(vue@3.5.13(typescript@5.9.2)) + '@vue-macros/common': 1.16.1(vue@3.5.13(typescript@5.8.3)) ast-walker-scope: 0.6.2 chokidar: 3.6.0 fast-glob: 3.3.3 @@ -28383,7 +28604,7 @@ snapshots: unplugin: 2.0.0-beta.1 yaml: 2.8.0 optionalDependencies: - vue-router: 4.5.0(vue@3.5.13(typescript@5.9.2)) + vue-router: 4.5.0(vue@3.5.13(typescript@5.8.3)) transitivePeerDependencies: - rollup - vue @@ -28605,6 +28826,10 @@ snapshots: vite: 7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0) vite-hot-client: 2.1.0(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) + vite-hot-client@0.2.4(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)): + dependencies: + vite: 5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1) + vite-hot-client@0.2.4(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)): dependencies: vite: 7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0) @@ -28739,6 +28964,24 @@ snapshots: - rollup - supports-color + vite-plugin-inspect@0.8.9(@nuxt/kit@3.15.4(magicast@0.3.5))(rollup@4.50.0)(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)): + dependencies: + '@antfu/utils': 0.7.10 + '@rollup/pluginutils': 5.2.0(rollup@4.50.0) + debug: 4.4.1 + error-stack-parser-es: 0.1.5 + fs-extra: 11.3.1 + open: 10.1.2 + perfect-debounce: 1.0.0 + picocolors: 1.1.1 + sirv: 3.0.1 + vite: 5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1) + optionalDependencies: + '@nuxt/kit': 3.15.4(magicast@0.3.5) + transitivePeerDependencies: + - rollup + - supports-color + vite-plugin-inspect@0.8.9(@nuxt/kit@3.15.4(magicast@0.3.5))(rollup@4.50.0)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)): dependencies: '@antfu/utils': 0.7.10 @@ -28805,6 +29048,21 @@ snapshots: - supports-color - vue + vite-plugin-vue-inspector@5.3.2(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)): + dependencies: + '@babel/core': 7.28.3 + '@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.3) + '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.3) + '@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.28.3) + '@vue/compiler-dom': 3.5.21 + kolorist: 1.8.0 + magic-string: 0.30.18 + vite: 5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1) + transitivePeerDependencies: + - supports-color + vite-plugin-vue-inspector@5.3.2(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)): dependencies: '@babel/core': 7.28.3 @@ -29013,9 +29271,9 @@ snapshots: - universal-cookie - yaml - vitest-environment-nuxt@1.0.1(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(magicast@0.3.5)(sass@1.85.0)(terser@5.43.1)(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.10.5)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(yaml@2.8.0): + vitest-environment-nuxt@1.0.1(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(magicast@0.3.5)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.10.5)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(yaml@2.8.0): dependencies: - '@nuxt/test-utils': 3.17.2(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(magicast@0.3.5)(sass@1.85.0)(terser@5.43.1)(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.10.5)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(yaml@2.8.0) + '@nuxt/test-utils': 3.17.2(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(magicast@0.3.5)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.10.5)(jiti@2.5.1)(jsdom@23.0.0)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(yaml@2.8.0) transitivePeerDependencies: - '@cucumber/cucumber' - '@jest/globals' -- 2.51.2 From a472dc82be4e1e07cb90ade5fd92d385680860a0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Sep 2025 18:12:26 +0000 Subject: [PATCH 02/22] Initial plan -- 2.51.2 From cc16cbc74d0bc38a77d0e762a6cbf136b6cb60e4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Sep 2025 18:30:05 +0000 Subject: [PATCH 03/22] Implement numeric enum support for Zod plugins (v3, v4, mini) Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com> --- .../openapi-ts/src/plugins/zod/mini/plugin.ts | 85 +++++++++++++---- .../openapi-ts/src/plugins/zod/v3/plugin.ts | 86 +++++++++++++---- .../openapi-ts/src/plugins/zod/v4/plugin.ts | 93 +++++++++++++++---- 3 files changed, 212 insertions(+), 52 deletions(-) diff --git a/packages/openapi-ts/src/plugins/zod/mini/plugin.ts b/packages/openapi-ts/src/plugins/zod/mini/plugin.ts index 1fdb02e02..b51522a0c 100644 --- a/packages/openapi-ts/src/plugins/zod/mini/plugin.ts +++ b/packages/openapi-ts/src/plugins/zod/mini/plugin.ts @@ -195,15 +195,52 @@ const enumTypeToZodSchema = ({ const result: Partial> = {}; const enumMembers: Array = []; + const literalMembers: Array = []; let isNullable = false; + let allStrings = true; for (const item of schema.items ?? []) { - // Zod supports only string enums + // Zod supports string, number, and boolean enums if (item.type === 'string' && typeof item.const === 'string') { - enumMembers.push( - tsc.stringLiteral({ - text: item.const, + const stringLiteral = tsc.stringLiteral({ + text: item.const, + }); + enumMembers.push(stringLiteral); + literalMembers.push( + tsc.callExpression({ + functionName: tsc.propertyAccessExpression({ + expression: zSymbol.placeholder, + name: identifiers.literal, + }), + parameters: [stringLiteral], + }), + ); + } else if ( + (item.type === 'number' || item.type === 'integer') && + typeof item.const === 'number' + ) { + allStrings = false; + const numberLiteral = tsc.ots.number(item.const); + literalMembers.push( + tsc.callExpression({ + functionName: tsc.propertyAccessExpression({ + expression: zSymbol.placeholder, + name: identifiers.literal, + }), + parameters: [numberLiteral], + }), + ); + } else if (item.type === 'boolean' && typeof item.const === 'boolean') { + allStrings = false; + const booleanLiteral = tsc.ots.boolean(item.const); + literalMembers.push( + tsc.callExpression({ + functionName: tsc.propertyAccessExpression({ + expression: zSymbol.placeholder, + name: identifiers.literal, + }), + parameters: [booleanLiteral], }), ); } else if (item.type === 'null' || item.const === null) { @@ -211,7 +248,7 @@ const enumTypeToZodSchema = ({ } } - if (!enumMembers.length) { + if (!literalMembers.length) { return unknownTypeToZodSchema({ plugin, schema: { @@ -220,18 +257,34 @@ const enumTypeToZodSchema = ({ }); } - result.expression = tsc.callExpression({ - functionName: tsc.propertyAccessExpression({ - expression: zSymbol.placeholder, - name: identifiers.enum, - }), - parameters: [ - tsc.arrayLiteralExpression({ - elements: enumMembers, - multiLine: false, + // Use z.enum() for pure string enums, z.union() for mixed or non-string types + if (allStrings && enumMembers.length > 0) { + result.expression = tsc.callExpression({ + functionName: tsc.propertyAccessExpression({ + expression: zSymbol.placeholder, + name: identifiers.enum, }), - ], - }); + parameters: [ + tsc.arrayLiteralExpression({ + elements: enumMembers, + multiLine: false, + }), + ], + }); + } else { + result.expression = tsc.callExpression({ + functionName: tsc.propertyAccessExpression({ + expression: zSymbol.placeholder, + name: identifiers.union, + }), + parameters: [ + tsc.arrayLiteralExpression({ + elements: literalMembers, + multiLine: literalMembers.length > 3, + }), + ], + }); + } if (isNullable) { result.expression = tsc.callExpression({ diff --git a/packages/openapi-ts/src/plugins/zod/v3/plugin.ts b/packages/openapi-ts/src/plugins/zod/v3/plugin.ts index 1562be1db..26bc2c760 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/plugin.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/plugin.ts @@ -179,15 +179,52 @@ const enumTypeToZodSchema = ({ ); const enumMembers: Array = []; + const literalMembers: Array = []; let isNullable = false; + let allStrings = true; for (const item of schema.items ?? []) { - // Zod supports only string enums + // Zod supports string, number, and boolean enums if (item.type === 'string' && typeof item.const === 'string') { - enumMembers.push( - tsc.stringLiteral({ - text: item.const, + const stringLiteral = tsc.stringLiteral({ + text: item.const, + }); + enumMembers.push(stringLiteral); + literalMembers.push( + tsc.callExpression({ + functionName: tsc.propertyAccessExpression({ + expression: zSymbol.placeholder, + name: identifiers.literal, + }), + parameters: [stringLiteral], + }), + ); + } else if ( + (item.type === 'number' || item.type === 'integer') && + typeof item.const === 'number' + ) { + allStrings = false; + const numberLiteral = tsc.ots.number(item.const); + literalMembers.push( + tsc.callExpression({ + functionName: tsc.propertyAccessExpression({ + expression: zSymbol.placeholder, + name: identifiers.literal, + }), + parameters: [numberLiteral], + }), + ); + } else if (item.type === 'boolean' && typeof item.const === 'boolean') { + allStrings = false; + const booleanLiteral = tsc.ots.boolean(item.const); + literalMembers.push( + tsc.callExpression({ + functionName: tsc.propertyAccessExpression({ + expression: zSymbol.placeholder, + name: identifiers.literal, + }), + parameters: [booleanLiteral], }), ); } else if (item.type === 'null' || item.const === null) { @@ -195,7 +232,7 @@ const enumTypeToZodSchema = ({ } } - if (!enumMembers.length) { + if (!literalMembers.length) { return unknownTypeToZodSchema({ plugin, schema: { @@ -204,18 +241,35 @@ const enumTypeToZodSchema = ({ }); } - let enumExpression = tsc.callExpression({ - functionName: tsc.propertyAccessExpression({ - expression: zSymbol.placeholder, - name: identifiers.enum, - }), - parameters: [ - tsc.arrayLiteralExpression({ - elements: enumMembers, - multiLine: false, + // Use z.enum() for pure string enums, z.union() for mixed or non-string types + let enumExpression: ts.CallExpression; + if (allStrings && enumMembers.length > 0) { + enumExpression = tsc.callExpression({ + functionName: tsc.propertyAccessExpression({ + expression: zSymbol.placeholder, + name: identifiers.enum, }), - ], - }); + parameters: [ + tsc.arrayLiteralExpression({ + elements: enumMembers, + multiLine: false, + }), + ], + }); + } else { + enumExpression = tsc.callExpression({ + functionName: tsc.propertyAccessExpression({ + expression: zSymbol.placeholder, + name: identifiers.union, + }), + parameters: [ + tsc.arrayLiteralExpression({ + elements: literalMembers, + multiLine: literalMembers.length > 3, + }), + ], + }); + } if (isNullable) { enumExpression = tsc.callExpression({ diff --git a/packages/openapi-ts/src/plugins/zod/v4/plugin.ts b/packages/openapi-ts/src/plugins/zod/v4/plugin.ts index e6c89a417..c81f5898a 100644 --- a/packages/openapi-ts/src/plugins/zod/v4/plugin.ts +++ b/packages/openapi-ts/src/plugins/zod/v4/plugin.ts @@ -172,16 +172,57 @@ const enumTypeToZodSchema = ({ }): Omit => { const result: Partial> = {}; + const zSymbol = plugin.referenceSymbol( + plugin.api.getSelector('import', 'zod'), + ); + const enumMembers: Array = []; + const literalMembers: Array = []; let isNullable = false; + let allStrings = true; for (const item of schema.items ?? []) { - // Zod supports only string enums + // Zod supports string, number, and boolean enums if (item.type === 'string' && typeof item.const === 'string') { - enumMembers.push( - tsc.stringLiteral({ - text: item.const, + const stringLiteral = tsc.stringLiteral({ + text: item.const, + }); + enumMembers.push(stringLiteral); + literalMembers.push( + tsc.callExpression({ + functionName: tsc.propertyAccessExpression({ + expression: zSymbol.placeholder, + name: identifiers.literal, + }), + parameters: [stringLiteral], + }), + ); + } else if ( + (item.type === 'number' || item.type === 'integer') && + typeof item.const === 'number' + ) { + allStrings = false; + const numberLiteral = tsc.ots.number(item.const); + literalMembers.push( + tsc.callExpression({ + functionName: tsc.propertyAccessExpression({ + expression: zSymbol.placeholder, + name: identifiers.literal, + }), + parameters: [numberLiteral], + }), + ); + } else if (item.type === 'boolean' && typeof item.const === 'boolean') { + allStrings = false; + const booleanLiteral = tsc.ots.boolean(item.const); + literalMembers.push( + tsc.callExpression({ + functionName: tsc.propertyAccessExpression({ + expression: zSymbol.placeholder, + name: identifiers.literal, + }), + parameters: [booleanLiteral], }), ); } else if (item.type === 'null' || item.const === null) { @@ -189,7 +230,7 @@ const enumTypeToZodSchema = ({ } } - if (!enumMembers.length) { + if (!literalMembers.length) { return unknownTypeToZodSchema({ plugin, schema: { @@ -198,22 +239,34 @@ const enumTypeToZodSchema = ({ }); } - const zSymbol = plugin.referenceSymbol( - plugin.api.getSelector('import', 'zod'), - ); - - result.expression = tsc.callExpression({ - functionName: tsc.propertyAccessExpression({ - expression: zSymbol.placeholder, - name: identifiers.enum, - }), - parameters: [ - tsc.arrayLiteralExpression({ - elements: enumMembers, - multiLine: false, + // Use z.enum() for pure string enums, z.union() for mixed or non-string types + if (allStrings && enumMembers.length > 0) { + result.expression = tsc.callExpression({ + functionName: tsc.propertyAccessExpression({ + expression: zSymbol.placeholder, + name: identifiers.enum, }), - ], - }); + parameters: [ + tsc.arrayLiteralExpression({ + elements: enumMembers, + multiLine: false, + }), + ], + }); + } else { + result.expression = tsc.callExpression({ + functionName: tsc.propertyAccessExpression({ + expression: zSymbol.placeholder, + name: identifiers.union, + }), + parameters: [ + tsc.arrayLiteralExpression({ + elements: literalMembers, + multiLine: literalMembers.length > 3, + }), + ], + }); + } if (isNullable) { result.expression = tsc.callExpression({ -- 2.51.2 From cfd27d6be13d926a2057b225de1f33102131c7eb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Sep 2025 18:37:34 +0000 Subject: [PATCH 04/22] Update test snapshots for Zod numeric enum support Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com> --- .../2.0.x/mini/default/zod.gen.ts | 28 ++++++++- .../__snapshots__/2.0.x/v3/default/zod.gen.ts | 28 ++++++++- .../__snapshots__/2.0.x/v4/default/zod.gen.ts | 28 ++++++++- .../3.0.x/mini/default/zod.gen.ts | 59 +++++++++++++++---- .../__snapshots__/3.0.x/v3/default/zod.gen.ts | 59 +++++++++++++++---- .../__snapshots__/3.0.x/v4/default/zod.gen.ts | 59 +++++++++++++++---- .../3.1.x/mini/default/zod.gen.ts | 55 +++++++++++++---- .../__snapshots__/3.1.x/v3/default/zod.gen.ts | 55 +++++++++++++---- .../__snapshots__/3.1.x/v4/default/zod.gen.ts | 55 +++++++++++++---- .../2.0.x/mini/default/zod.gen.ts | 28 ++++++++- .../__snapshots__/2.0.x/v3/default/zod.gen.ts | 28 ++++++++- .../__snapshots__/2.0.x/v4/default/zod.gen.ts | 28 ++++++++- .../3.0.x/mini/default/zod.gen.ts | 59 +++++++++++++++---- .../__snapshots__/3.0.x/v3/default/zod.gen.ts | 59 +++++++++++++++---- .../__snapshots__/3.0.x/v4/default/zod.gen.ts | 59 +++++++++++++++---- .../3.1.x/mini/default/zod.gen.ts | 55 +++++++++++++---- .../__snapshots__/3.1.x/v3/default/zod.gen.ts | 55 +++++++++++++---- .../__snapshots__/3.1.x/v4/default/zod.gen.ts | 55 +++++++++++++---- 18 files changed, 708 insertions(+), 144 deletions(-) diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/mini/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/mini/default/zod.gen.ts index 5b3da321f..a5d934eb4 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/mini/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/mini/default/zod.gen.ts @@ -103,7 +103,23 @@ export const zEnumWithStrings = z.enum([ /** * This is a simple enum with numbers */ -export const zEnumWithNumbers = z.unknown(); +export const zEnumWithNumbers = z.union([ + z.literal(1), + z.literal(2), + z.literal(3), + z.literal(1.1), + z.literal(1.2), + z.literal(1.3), + z.literal(100), + z.literal(200), + z.literal(300), + z.literal(-100), + z.literal(-200), + z.literal(-300), + z.literal(-1.1), + z.literal(-1.2), + z.literal(-1.3) +]); /** * Success=1,Warning=2,Error=3 @@ -113,7 +129,11 @@ export const zEnumFromDescription = z.number(); /** * This is a simple enum with numbers */ -export const zEnumWithExtensions = z.unknown(); +export const zEnumWithExtensions = z.union([ + z.literal(200), + z.literal(400), + z.literal(500) +]); /** * This is a simple array with numbers @@ -234,7 +254,9 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.unknown()) + bool: z.optional(z.union([ + z.literal(true) + ])) }); /** diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v3/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v3/default/zod.gen.ts index e7ba45f19..341702ba8 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v3/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v3/default/zod.gen.ts @@ -103,7 +103,23 @@ export const zEnumWithStrings = z.enum([ /** * This is a simple enum with numbers */ -export const zEnumWithNumbers = z.unknown(); +export const zEnumWithNumbers = z.union([ + z.literal(1), + z.literal(2), + z.literal(3), + z.literal(1.1), + z.literal(1.2), + z.literal(1.3), + z.literal(100), + z.literal(200), + z.literal(300), + z.literal(-100), + z.literal(-200), + z.literal(-300), + z.literal(-1.1), + z.literal(-1.2), + z.literal(-1.3) +]); /** * Success=1,Warning=2,Error=3 @@ -113,7 +129,11 @@ export const zEnumFromDescription = z.number(); /** * This is a simple enum with numbers */ -export const zEnumWithExtensions = z.unknown(); +export const zEnumWithExtensions = z.union([ + z.literal(200), + z.literal(400), + z.literal(500) +]); /** * This is a simple array with numbers @@ -234,7 +254,9 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ]).optional(), - bool: z.unknown().optional() + bool: z.union([ + z.literal(true) + ]).optional() }); /** diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/default/zod.gen.ts index 34f491c6f..440c1413b 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/default/zod.gen.ts @@ -103,7 +103,23 @@ export const zEnumWithStrings = z.enum([ /** * This is a simple enum with numbers */ -export const zEnumWithNumbers = z.unknown(); +export const zEnumWithNumbers = z.union([ + z.literal(1), + z.literal(2), + z.literal(3), + z.literal(1.1), + z.literal(1.2), + z.literal(1.3), + z.literal(100), + z.literal(200), + z.literal(300), + z.literal(-100), + z.literal(-200), + z.literal(-300), + z.literal(-1.1), + z.literal(-1.2), + z.literal(-1.3) +]); /** * Success=1,Warning=2,Error=3 @@ -113,7 +129,11 @@ export const zEnumFromDescription = z.number(); /** * This is a simple enum with numbers */ -export const zEnumWithExtensions = z.unknown(); +export const zEnumWithExtensions = z.union([ + z.literal(200), + z.literal(400), + z.literal(500) +]); /** * This is a simple array with numbers @@ -234,7 +254,9 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.unknown()) + bool: z.optional(z.union([ + z.literal(true) + ])) }); /** diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/default/zod.gen.ts index 3b02520b7..32a249eb8 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/default/zod.gen.ts @@ -119,17 +119,34 @@ export const zEnumWithStrings = z.enum([ 'Non-ascii: øæåôöØÆÅÔÖ字符串' ]); -export const zEnumWithReplacedCharacters = z.enum([ - "'Single Quote'", - '"Double Quotes"', - 'øæåôöØÆÅÔÖ字符串', - '' +export const zEnumWithReplacedCharacters = z.union([ + z.literal("'Single Quote'"), + z.literal('"Double Quotes"'), + z.literal('øæåôöØÆÅÔÖ字符串'), + z.literal(3.1), + z.literal('') ]); /** * This is a simple enum with numbers */ -export const zEnumWithNumbers = z.unknown(); +export const zEnumWithNumbers = z.union([ + z.literal(1), + z.literal(2), + z.literal(3), + z.literal(1.1), + z.literal(1.2), + z.literal(1.3), + z.literal(100), + z.literal(200), + z.literal(300), + z.literal(-100), + z.literal(-200), + z.literal(-300), + z.literal(-1.1), + z.literal(-1.2), + z.literal(-1.3) +]); /** * Success=1,Warning=2,Error=3 @@ -139,9 +156,17 @@ export const zEnumFromDescription = z.number(); /** * This is a simple enum with numbers */ -export const zEnumWithExtensions = z.unknown(); +export const zEnumWithExtensions = z.union([ + z.literal(200), + z.literal(400), + z.literal(500) +]); -export const zEnumWithXEnumNames = z.unknown(); +export const zEnumWithXEnumNames = z.union([ + z.literal(0), + z.literal(1), + z.literal(2) +]); /** * This is a simple array with numbers @@ -311,7 +336,9 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.unknown()) + bool: z.optional(z.union([ + z.literal(true) + ])) }); /** @@ -752,7 +779,9 @@ export const zModelWithConst = z.object({ String: z.optional(z.enum([ 'String' ])), - number: z.optional(z.unknown()), + number: z.optional(z.union([ + z.literal(0) + ])), null: z.optional(z.unknown()), withType: z.optional(z.enum([ 'Some string' @@ -938,7 +967,15 @@ export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([ ]); export const zModelWithNumericEnumUnion = z.object({ - value: z.optional(z.unknown()) + value: z.optional(z.union([ + z.literal(-10), + z.literal(-1), + z.literal(0), + z.literal(1), + z.literal(3), + z.literal(6), + z.literal(12) + ])) }); /** diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/default/zod.gen.ts index c65ab143e..8ec7c7545 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/default/zod.gen.ts @@ -119,17 +119,34 @@ export const zEnumWithStrings = z.enum([ 'Non-ascii: øæåôöØÆÅÔÖ字符串' ]); -export const zEnumWithReplacedCharacters = z.enum([ - "'Single Quote'", - '"Double Quotes"', - 'øæåôöØÆÅÔÖ字符串', - '' +export const zEnumWithReplacedCharacters = z.union([ + z.literal("'Single Quote'"), + z.literal('"Double Quotes"'), + z.literal('øæåôöØÆÅÔÖ字符串'), + z.literal(3.1), + z.literal('') ]); /** * This is a simple enum with numbers */ -export const zEnumWithNumbers = z.unknown(); +export const zEnumWithNumbers = z.union([ + z.literal(1), + z.literal(2), + z.literal(3), + z.literal(1.1), + z.literal(1.2), + z.literal(1.3), + z.literal(100), + z.literal(200), + z.literal(300), + z.literal(-100), + z.literal(-200), + z.literal(-300), + z.literal(-1.1), + z.literal(-1.2), + z.literal(-1.3) +]); /** * Success=1,Warning=2,Error=3 @@ -139,9 +156,17 @@ export const zEnumFromDescription = z.number(); /** * This is a simple enum with numbers */ -export const zEnumWithExtensions = z.unknown(); +export const zEnumWithExtensions = z.union([ + z.literal(200), + z.literal(400), + z.literal(500) +]); -export const zEnumWithXEnumNames = z.unknown(); +export const zEnumWithXEnumNames = z.union([ + z.literal(0), + z.literal(1), + z.literal(2) +]); /** * This is a simple array with numbers @@ -311,7 +336,9 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ]).optional(), - bool: z.unknown().optional() + bool: z.union([ + z.literal(true) + ]).optional() }); /** @@ -750,7 +777,9 @@ export const zModelWithConst = z.object({ String: z.enum([ 'String' ]).optional(), - number: z.unknown().optional(), + number: z.union([ + z.literal(0) + ]).optional(), null: z.unknown().optional(), withType: z.enum([ 'Some string' @@ -936,7 +965,15 @@ export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([ ]); export const zModelWithNumericEnumUnion = z.object({ - value: z.unknown().optional() + value: z.union([ + z.literal(-10), + z.literal(-1), + z.literal(0), + z.literal(1), + z.literal(3), + z.literal(6), + z.literal(12) + ]).optional() }); /** diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/default/zod.gen.ts index 2241c0dbc..ea79fda72 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/default/zod.gen.ts @@ -119,17 +119,34 @@ export const zEnumWithStrings = z.enum([ 'Non-ascii: øæåôöØÆÅÔÖ字符串' ]); -export const zEnumWithReplacedCharacters = z.enum([ - "'Single Quote'", - '"Double Quotes"', - 'øæåôöØÆÅÔÖ字符串', - '' +export const zEnumWithReplacedCharacters = z.union([ + z.literal("'Single Quote'"), + z.literal('"Double Quotes"'), + z.literal('øæåôöØÆÅÔÖ字符串'), + z.literal(3.1), + z.literal('') ]); /** * This is a simple enum with numbers */ -export const zEnumWithNumbers = z.unknown(); +export const zEnumWithNumbers = z.union([ + z.literal(1), + z.literal(2), + z.literal(3), + z.literal(1.1), + z.literal(1.2), + z.literal(1.3), + z.literal(100), + z.literal(200), + z.literal(300), + z.literal(-100), + z.literal(-200), + z.literal(-300), + z.literal(-1.1), + z.literal(-1.2), + z.literal(-1.3) +]); /** * Success=1,Warning=2,Error=3 @@ -139,9 +156,17 @@ export const zEnumFromDescription = z.number(); /** * This is a simple enum with numbers */ -export const zEnumWithExtensions = z.unknown(); +export const zEnumWithExtensions = z.union([ + z.literal(200), + z.literal(400), + z.literal(500) +]); -export const zEnumWithXEnumNames = z.unknown(); +export const zEnumWithXEnumNames = z.union([ + z.literal(0), + z.literal(1), + z.literal(2) +]); /** * This is a simple array with numbers @@ -311,7 +336,9 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.unknown()) + bool: z.optional(z.union([ + z.literal(true) + ])) }); /** @@ -752,7 +779,9 @@ export const zModelWithConst = z.object({ String: z.optional(z.enum([ 'String' ])), - number: z.optional(z.unknown()), + number: z.optional(z.union([ + z.literal(0) + ])), null: z.optional(z.unknown()), withType: z.optional(z.enum([ 'Some string' @@ -938,7 +967,15 @@ export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([ ]); export const zModelWithNumericEnumUnion = z.object({ - value: z.optional(z.unknown()) + value: z.optional(z.union([ + z.literal(-10), + z.literal(-1), + z.literal(0), + z.literal(1), + z.literal(3), + z.literal(6), + z.literal(12) + ])) }); /** diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/default/zod.gen.ts index 33b97c228..5296e1e19 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/default/zod.gen.ts @@ -125,17 +125,34 @@ export const zEnumWithStrings = z.enum([ 'Non-ascii: øæåôöØÆÅÔÖ字符串' ]); -export const zEnumWithReplacedCharacters = z.enum([ - "'Single Quote'", - '"Double Quotes"', - 'øæåôöØÆÅÔÖ字符串', - '' +export const zEnumWithReplacedCharacters = z.union([ + z.literal("'Single Quote'"), + z.literal('"Double Quotes"'), + z.literal('øæåôöØÆÅÔÖ字符串'), + z.literal(3.1), + z.literal('') ]); /** * This is a simple enum with numbers */ -export const zEnumWithNumbers = z.unknown(); +export const zEnumWithNumbers = z.union([ + z.literal(1), + z.literal(2), + z.literal(3), + z.literal(1.1), + z.literal(1.2), + z.literal(1.3), + z.literal(100), + z.literal(200), + z.literal(300), + z.literal(-100), + z.literal(-200), + z.literal(-300), + z.literal(-1.1), + z.literal(-1.2), + z.literal(-1.3) +]); /** * Success=1,Warning=2,Error=3 @@ -145,9 +162,17 @@ export const zEnumFromDescription = z.number(); /** * This is a simple enum with numbers */ -export const zEnumWithExtensions = z.unknown(); +export const zEnumWithExtensions = z.union([ + z.literal(200), + z.literal(400), + z.literal(500) +]); -export const zEnumWithXEnumNames = z.unknown(); +export const zEnumWithXEnumNames = z.union([ + z.literal(0), + z.literal(1), + z.literal(2) +]); /** * This is a simple array with numbers @@ -320,7 +345,9 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.unknown()) + bool: z.optional(z.union([ + z.literal(true) + ])) }); /** @@ -944,7 +971,15 @@ export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([ ]); export const zModelWithNumericEnumUnion = z.object({ - value: z.optional(z.unknown()) + value: z.optional(z.union([ + z.literal(-10), + z.literal(-1), + z.literal(0), + z.literal(1), + z.literal(3), + z.literal(6), + z.literal(12) + ])) }); /** diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/default/zod.gen.ts index 968144790..dc8473e99 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/default/zod.gen.ts @@ -125,17 +125,34 @@ export const zEnumWithStrings = z.enum([ 'Non-ascii: øæåôöØÆÅÔÖ字符串' ]); -export const zEnumWithReplacedCharacters = z.enum([ - "'Single Quote'", - '"Double Quotes"', - 'øæåôöØÆÅÔÖ字符串', - '' +export const zEnumWithReplacedCharacters = z.union([ + z.literal("'Single Quote'"), + z.literal('"Double Quotes"'), + z.literal('øæåôöØÆÅÔÖ字符串'), + z.literal(3.1), + z.literal('') ]); /** * This is a simple enum with numbers */ -export const zEnumWithNumbers = z.unknown(); +export const zEnumWithNumbers = z.union([ + z.literal(1), + z.literal(2), + z.literal(3), + z.literal(1.1), + z.literal(1.2), + z.literal(1.3), + z.literal(100), + z.literal(200), + z.literal(300), + z.literal(-100), + z.literal(-200), + z.literal(-300), + z.literal(-1.1), + z.literal(-1.2), + z.literal(-1.3) +]); /** * Success=1,Warning=2,Error=3 @@ -145,9 +162,17 @@ export const zEnumFromDescription = z.number(); /** * This is a simple enum with numbers */ -export const zEnumWithExtensions = z.unknown(); +export const zEnumWithExtensions = z.union([ + z.literal(200), + z.literal(400), + z.literal(500) +]); -export const zEnumWithXEnumNames = z.unknown(); +export const zEnumWithXEnumNames = z.union([ + z.literal(0), + z.literal(1), + z.literal(2) +]); /** * This is a simple array with numbers @@ -320,7 +345,9 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ]).optional(), - bool: z.unknown().optional() + bool: z.union([ + z.literal(true) + ]).optional() }); /** @@ -942,7 +969,15 @@ export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([ ]); export const zModelWithNumericEnumUnion = z.object({ - value: z.unknown().optional() + value: z.union([ + z.literal(-10), + z.literal(-1), + z.literal(0), + z.literal(1), + z.literal(3), + z.literal(6), + z.literal(12) + ]).optional() }); /** diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/default/zod.gen.ts index 63b277d7a..95f3a0e70 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/default/zod.gen.ts @@ -125,17 +125,34 @@ export const zEnumWithStrings = z.enum([ 'Non-ascii: øæåôöØÆÅÔÖ字符串' ]); -export const zEnumWithReplacedCharacters = z.enum([ - "'Single Quote'", - '"Double Quotes"', - 'øæåôöØÆÅÔÖ字符串', - '' +export const zEnumWithReplacedCharacters = z.union([ + z.literal("'Single Quote'"), + z.literal('"Double Quotes"'), + z.literal('øæåôöØÆÅÔÖ字符串'), + z.literal(3.1), + z.literal('') ]); /** * This is a simple enum with numbers */ -export const zEnumWithNumbers = z.unknown(); +export const zEnumWithNumbers = z.union([ + z.literal(1), + z.literal(2), + z.literal(3), + z.literal(1.1), + z.literal(1.2), + z.literal(1.3), + z.literal(100), + z.literal(200), + z.literal(300), + z.literal(-100), + z.literal(-200), + z.literal(-300), + z.literal(-1.1), + z.literal(-1.2), + z.literal(-1.3) +]); /** * Success=1,Warning=2,Error=3 @@ -145,9 +162,17 @@ export const zEnumFromDescription = z.number(); /** * This is a simple enum with numbers */ -export const zEnumWithExtensions = z.unknown(); +export const zEnumWithExtensions = z.union([ + z.literal(200), + z.literal(400), + z.literal(500) +]); -export const zEnumWithXEnumNames = z.unknown(); +export const zEnumWithXEnumNames = z.union([ + z.literal(0), + z.literal(1), + z.literal(2) +]); /** * This is a simple array with numbers @@ -320,7 +345,9 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.unknown()) + bool: z.optional(z.union([ + z.literal(true) + ])) }); /** @@ -944,7 +971,15 @@ export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([ ]); export const zModelWithNumericEnumUnion = z.object({ - value: z.optional(z.unknown()) + value: z.optional(z.union([ + z.literal(-10), + z.literal(-1), + z.literal(0), + z.literal(1), + z.literal(3), + z.literal(6), + z.literal(12) + ])) }); /** diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/default/zod.gen.ts index ee9d8176a..efffc4e5a 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/default/zod.gen.ts @@ -103,7 +103,23 @@ export const zEnumWithStrings = z.enum([ /** * This is a simple enum with numbers */ -export const zEnumWithNumbers = z.unknown(); +export const zEnumWithNumbers = z.union([ + z.literal(1), + z.literal(2), + z.literal(3), + z.literal(1.1), + z.literal(1.2), + z.literal(1.3), + z.literal(100), + z.literal(200), + z.literal(300), + z.literal(-100), + z.literal(-200), + z.literal(-300), + z.literal(-1.1), + z.literal(-1.2), + z.literal(-1.3) +]); /** * Success=1,Warning=2,Error=3 @@ -113,7 +129,11 @@ export const zEnumFromDescription = z.number(); /** * This is a simple enum with numbers */ -export const zEnumWithExtensions = z.unknown(); +export const zEnumWithExtensions = z.union([ + z.literal(200), + z.literal(400), + z.literal(500) +]); /** * This is a simple array with numbers @@ -234,7 +254,9 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.unknown()) + bool: z.optional(z.union([ + z.literal(true) + ])) }); /** diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/default/zod.gen.ts index 69da954a5..9970c33ed 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/default/zod.gen.ts @@ -103,7 +103,23 @@ export const zEnumWithStrings = z.enum([ /** * This is a simple enum with numbers */ -export const zEnumWithNumbers = z.unknown(); +export const zEnumWithNumbers = z.union([ + z.literal(1), + z.literal(2), + z.literal(3), + z.literal(1.1), + z.literal(1.2), + z.literal(1.3), + z.literal(100), + z.literal(200), + z.literal(300), + z.literal(-100), + z.literal(-200), + z.literal(-300), + z.literal(-1.1), + z.literal(-1.2), + z.literal(-1.3) +]); /** * Success=1,Warning=2,Error=3 @@ -113,7 +129,11 @@ export const zEnumFromDescription = z.number(); /** * This is a simple enum with numbers */ -export const zEnumWithExtensions = z.unknown(); +export const zEnumWithExtensions = z.union([ + z.literal(200), + z.literal(400), + z.literal(500) +]); /** * This is a simple array with numbers @@ -234,7 +254,9 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ]).optional(), - bool: z.unknown().optional() + bool: z.union([ + z.literal(true) + ]).optional() }); /** diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/default/zod.gen.ts index fdfcad8c4..515ed69ff 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/default/zod.gen.ts @@ -103,7 +103,23 @@ export const zEnumWithStrings = z.enum([ /** * This is a simple enum with numbers */ -export const zEnumWithNumbers = z.unknown(); +export const zEnumWithNumbers = z.union([ + z.literal(1), + z.literal(2), + z.literal(3), + z.literal(1.1), + z.literal(1.2), + z.literal(1.3), + z.literal(100), + z.literal(200), + z.literal(300), + z.literal(-100), + z.literal(-200), + z.literal(-300), + z.literal(-1.1), + z.literal(-1.2), + z.literal(-1.3) +]); /** * Success=1,Warning=2,Error=3 @@ -113,7 +129,11 @@ export const zEnumFromDescription = z.number(); /** * This is a simple enum with numbers */ -export const zEnumWithExtensions = z.unknown(); +export const zEnumWithExtensions = z.union([ + z.literal(200), + z.literal(400), + z.literal(500) +]); /** * This is a simple array with numbers @@ -234,7 +254,9 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.unknown()) + bool: z.optional(z.union([ + z.literal(true) + ])) }); /** diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/default/zod.gen.ts index c862f31bb..b84e76509 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/default/zod.gen.ts @@ -119,17 +119,34 @@ export const zEnumWithStrings = z.enum([ 'Non-ascii: øæåôöØÆÅÔÖ字符串' ]); -export const zEnumWithReplacedCharacters = z.enum([ - "'Single Quote'", - '"Double Quotes"', - 'øæåôöØÆÅÔÖ字符串', - '' +export const zEnumWithReplacedCharacters = z.union([ + z.literal("'Single Quote'"), + z.literal('"Double Quotes"'), + z.literal('øæåôöØÆÅÔÖ字符串'), + z.literal(3.1), + z.literal('') ]); /** * This is a simple enum with numbers */ -export const zEnumWithNumbers = z.unknown(); +export const zEnumWithNumbers = z.union([ + z.literal(1), + z.literal(2), + z.literal(3), + z.literal(1.1), + z.literal(1.2), + z.literal(1.3), + z.literal(100), + z.literal(200), + z.literal(300), + z.literal(-100), + z.literal(-200), + z.literal(-300), + z.literal(-1.1), + z.literal(-1.2), + z.literal(-1.3) +]); /** * Success=1,Warning=2,Error=3 @@ -139,9 +156,17 @@ export const zEnumFromDescription = z.number(); /** * This is a simple enum with numbers */ -export const zEnumWithExtensions = z.unknown(); +export const zEnumWithExtensions = z.union([ + z.literal(200), + z.literal(400), + z.literal(500) +]); -export const zEnumWithXEnumNames = z.unknown(); +export const zEnumWithXEnumNames = z.union([ + z.literal(0), + z.literal(1), + z.literal(2) +]); /** * This is a simple array with numbers @@ -311,7 +336,9 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.unknown()) + bool: z.optional(z.union([ + z.literal(true) + ])) }); /** @@ -752,7 +779,9 @@ export const zModelWithConst = z.object({ String: z.optional(z.enum([ 'String' ])), - number: z.optional(z.unknown()), + number: z.optional(z.union([ + z.literal(0) + ])), null: z.optional(z.unknown()), withType: z.optional(z.enum([ 'Some string' @@ -938,7 +967,15 @@ export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([ ]); export const zModelWithNumericEnumUnion = z.object({ - value: z.optional(z.unknown()) + value: z.optional(z.union([ + z.literal(-10), + z.literal(-1), + z.literal(0), + z.literal(1), + z.literal(3), + z.literal(6), + z.literal(12) + ])) }); /** diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/default/zod.gen.ts index 4e19fcbfb..5d3031887 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/default/zod.gen.ts @@ -119,17 +119,34 @@ export const zEnumWithStrings = z.enum([ 'Non-ascii: øæåôöØÆÅÔÖ字符串' ]); -export const zEnumWithReplacedCharacters = z.enum([ - "'Single Quote'", - '"Double Quotes"', - 'øæåôöØÆÅÔÖ字符串', - '' +export const zEnumWithReplacedCharacters = z.union([ + z.literal("'Single Quote'"), + z.literal('"Double Quotes"'), + z.literal('øæåôöØÆÅÔÖ字符串'), + z.literal(3.1), + z.literal('') ]); /** * This is a simple enum with numbers */ -export const zEnumWithNumbers = z.unknown(); +export const zEnumWithNumbers = z.union([ + z.literal(1), + z.literal(2), + z.literal(3), + z.literal(1.1), + z.literal(1.2), + z.literal(1.3), + z.literal(100), + z.literal(200), + z.literal(300), + z.literal(-100), + z.literal(-200), + z.literal(-300), + z.literal(-1.1), + z.literal(-1.2), + z.literal(-1.3) +]); /** * Success=1,Warning=2,Error=3 @@ -139,9 +156,17 @@ export const zEnumFromDescription = z.number(); /** * This is a simple enum with numbers */ -export const zEnumWithExtensions = z.unknown(); +export const zEnumWithExtensions = z.union([ + z.literal(200), + z.literal(400), + z.literal(500) +]); -export const zEnumWithXEnumNames = z.unknown(); +export const zEnumWithXEnumNames = z.union([ + z.literal(0), + z.literal(1), + z.literal(2) +]); /** * This is a simple array with numbers @@ -311,7 +336,9 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ]).optional(), - bool: z.unknown().optional() + bool: z.union([ + z.literal(true) + ]).optional() }); /** @@ -750,7 +777,9 @@ export const zModelWithConst = z.object({ String: z.enum([ 'String' ]).optional(), - number: z.unknown().optional(), + number: z.union([ + z.literal(0) + ]).optional(), null: z.unknown().optional(), withType: z.enum([ 'Some string' @@ -936,7 +965,15 @@ export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([ ]); export const zModelWithNumericEnumUnion = z.object({ - value: z.unknown().optional() + value: z.union([ + z.literal(-10), + z.literal(-1), + z.literal(0), + z.literal(1), + z.literal(3), + z.literal(6), + z.literal(12) + ]).optional() }); /** diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/default/zod.gen.ts index ed6c1cefc..0af58af79 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/default/zod.gen.ts @@ -119,17 +119,34 @@ export const zEnumWithStrings = z.enum([ 'Non-ascii: øæåôöØÆÅÔÖ字符串' ]); -export const zEnumWithReplacedCharacters = z.enum([ - "'Single Quote'", - '"Double Quotes"', - 'øæåôöØÆÅÔÖ字符串', - '' +export const zEnumWithReplacedCharacters = z.union([ + z.literal("'Single Quote'"), + z.literal('"Double Quotes"'), + z.literal('øæåôöØÆÅÔÖ字符串'), + z.literal(3.1), + z.literal('') ]); /** * This is a simple enum with numbers */ -export const zEnumWithNumbers = z.unknown(); +export const zEnumWithNumbers = z.union([ + z.literal(1), + z.literal(2), + z.literal(3), + z.literal(1.1), + z.literal(1.2), + z.literal(1.3), + z.literal(100), + z.literal(200), + z.literal(300), + z.literal(-100), + z.literal(-200), + z.literal(-300), + z.literal(-1.1), + z.literal(-1.2), + z.literal(-1.3) +]); /** * Success=1,Warning=2,Error=3 @@ -139,9 +156,17 @@ export const zEnumFromDescription = z.number(); /** * This is a simple enum with numbers */ -export const zEnumWithExtensions = z.unknown(); +export const zEnumWithExtensions = z.union([ + z.literal(200), + z.literal(400), + z.literal(500) +]); -export const zEnumWithXEnumNames = z.unknown(); +export const zEnumWithXEnumNames = z.union([ + z.literal(0), + z.literal(1), + z.literal(2) +]); /** * This is a simple array with numbers @@ -311,7 +336,9 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.unknown()) + bool: z.optional(z.union([ + z.literal(true) + ])) }); /** @@ -752,7 +779,9 @@ export const zModelWithConst = z.object({ String: z.optional(z.enum([ 'String' ])), - number: z.optional(z.unknown()), + number: z.optional(z.union([ + z.literal(0) + ])), null: z.optional(z.unknown()), withType: z.optional(z.enum([ 'Some string' @@ -938,7 +967,15 @@ export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([ ]); export const zModelWithNumericEnumUnion = z.object({ - value: z.optional(z.unknown()) + value: z.optional(z.union([ + z.literal(-10), + z.literal(-1), + z.literal(0), + z.literal(1), + z.literal(3), + z.literal(6), + z.literal(12) + ])) }); /** diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/default/zod.gen.ts index 67cd9d8bf..41bf680f3 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/default/zod.gen.ts @@ -125,17 +125,34 @@ export const zEnumWithStrings = z.enum([ 'Non-ascii: øæåôöØÆÅÔÖ字符串' ]); -export const zEnumWithReplacedCharacters = z.enum([ - "'Single Quote'", - '"Double Quotes"', - 'øæåôöØÆÅÔÖ字符串', - '' +export const zEnumWithReplacedCharacters = z.union([ + z.literal("'Single Quote'"), + z.literal('"Double Quotes"'), + z.literal('øæåôöØÆÅÔÖ字符串'), + z.literal(3.1), + z.literal('') ]); /** * This is a simple enum with numbers */ -export const zEnumWithNumbers = z.unknown(); +export const zEnumWithNumbers = z.union([ + z.literal(1), + z.literal(2), + z.literal(3), + z.literal(1.1), + z.literal(1.2), + z.literal(1.3), + z.literal(100), + z.literal(200), + z.literal(300), + z.literal(-100), + z.literal(-200), + z.literal(-300), + z.literal(-1.1), + z.literal(-1.2), + z.literal(-1.3) +]); /** * Success=1,Warning=2,Error=3 @@ -145,9 +162,17 @@ export const zEnumFromDescription = z.number(); /** * This is a simple enum with numbers */ -export const zEnumWithExtensions = z.unknown(); +export const zEnumWithExtensions = z.union([ + z.literal(200), + z.literal(400), + z.literal(500) +]); -export const zEnumWithXEnumNames = z.unknown(); +export const zEnumWithXEnumNames = z.union([ + z.literal(0), + z.literal(1), + z.literal(2) +]); /** * This is a simple array with numbers @@ -320,7 +345,9 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.unknown()) + bool: z.optional(z.union([ + z.literal(true) + ])) }); /** @@ -944,7 +971,15 @@ export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([ ]); export const zModelWithNumericEnumUnion = z.object({ - value: z.optional(z.unknown()) + value: z.optional(z.union([ + z.literal(-10), + z.literal(-1), + z.literal(0), + z.literal(1), + z.literal(3), + z.literal(6), + z.literal(12) + ])) }); /** diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/default/zod.gen.ts index c4a1f074c..e2c612e01 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/default/zod.gen.ts @@ -125,17 +125,34 @@ export const zEnumWithStrings = z.enum([ 'Non-ascii: øæåôöØÆÅÔÖ字符串' ]); -export const zEnumWithReplacedCharacters = z.enum([ - "'Single Quote'", - '"Double Quotes"', - 'øæåôöØÆÅÔÖ字符串', - '' +export const zEnumWithReplacedCharacters = z.union([ + z.literal("'Single Quote'"), + z.literal('"Double Quotes"'), + z.literal('øæåôöØÆÅÔÖ字符串'), + z.literal(3.1), + z.literal('') ]); /** * This is a simple enum with numbers */ -export const zEnumWithNumbers = z.unknown(); +export const zEnumWithNumbers = z.union([ + z.literal(1), + z.literal(2), + z.literal(3), + z.literal(1.1), + z.literal(1.2), + z.literal(1.3), + z.literal(100), + z.literal(200), + z.literal(300), + z.literal(-100), + z.literal(-200), + z.literal(-300), + z.literal(-1.1), + z.literal(-1.2), + z.literal(-1.3) +]); /** * Success=1,Warning=2,Error=3 @@ -145,9 +162,17 @@ export const zEnumFromDescription = z.number(); /** * This is a simple enum with numbers */ -export const zEnumWithExtensions = z.unknown(); +export const zEnumWithExtensions = z.union([ + z.literal(200), + z.literal(400), + z.literal(500) +]); -export const zEnumWithXEnumNames = z.unknown(); +export const zEnumWithXEnumNames = z.union([ + z.literal(0), + z.literal(1), + z.literal(2) +]); /** * This is a simple array with numbers @@ -320,7 +345,9 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ]).optional(), - bool: z.unknown().optional() + bool: z.union([ + z.literal(true) + ]).optional() }); /** @@ -942,7 +969,15 @@ export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([ ]); export const zModelWithNumericEnumUnion = z.object({ - value: z.unknown().optional() + value: z.union([ + z.literal(-10), + z.literal(-1), + z.literal(0), + z.literal(1), + z.literal(3), + z.literal(6), + z.literal(12) + ]).optional() }); /** diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/default/zod.gen.ts index b74816cd8..44aa066af 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/default/zod.gen.ts @@ -125,17 +125,34 @@ export const zEnumWithStrings = z.enum([ 'Non-ascii: øæåôöØÆÅÔÖ字符串' ]); -export const zEnumWithReplacedCharacters = z.enum([ - "'Single Quote'", - '"Double Quotes"', - 'øæåôöØÆÅÔÖ字符串', - '' +export const zEnumWithReplacedCharacters = z.union([ + z.literal("'Single Quote'"), + z.literal('"Double Quotes"'), + z.literal('øæåôöØÆÅÔÖ字符串'), + z.literal(3.1), + z.literal('') ]); /** * This is a simple enum with numbers */ -export const zEnumWithNumbers = z.unknown(); +export const zEnumWithNumbers = z.union([ + z.literal(1), + z.literal(2), + z.literal(3), + z.literal(1.1), + z.literal(1.2), + z.literal(1.3), + z.literal(100), + z.literal(200), + z.literal(300), + z.literal(-100), + z.literal(-200), + z.literal(-300), + z.literal(-1.1), + z.literal(-1.2), + z.literal(-1.3) +]); /** * Success=1,Warning=2,Error=3 @@ -145,9 +162,17 @@ export const zEnumFromDescription = z.number(); /** * This is a simple enum with numbers */ -export const zEnumWithExtensions = z.unknown(); +export const zEnumWithExtensions = z.union([ + z.literal(200), + z.literal(400), + z.literal(500) +]); -export const zEnumWithXEnumNames = z.unknown(); +export const zEnumWithXEnumNames = z.union([ + z.literal(0), + z.literal(1), + z.literal(2) +]); /** * This is a simple array with numbers @@ -320,7 +345,9 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.unknown()) + bool: z.optional(z.union([ + z.literal(true) + ])) }); /** @@ -944,7 +971,15 @@ export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([ ]); export const zModelWithNumericEnumUnion = z.object({ - value: z.optional(z.unknown()) + value: z.optional(z.union([ + z.literal(-10), + z.literal(-1), + z.literal(0), + z.literal(1), + z.literal(3), + z.literal(6), + z.literal(12) + ])) }); /** -- 2.51.2 From 707cb1a19c449379a7246f674c68164ef16027de Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Sep 2025 19:40:38 +0000 Subject: [PATCH 05/22] Optimize single-member unions to use literal directly Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com> --- .../zod/v3/__snapshots__/2.0.x/mini/default/zod.gen.ts | 4 +--- .../zod/v3/__snapshots__/2.0.x/v3/default/zod.gen.ts | 4 +--- .../zod/v3/__snapshots__/2.0.x/v4/default/zod.gen.ts | 4 +--- .../zod/v3/__snapshots__/3.0.x/mini/default/zod.gen.ts | 8 ++------ .../zod/v3/__snapshots__/3.0.x/v3/default/zod.gen.ts | 8 ++------ .../zod/v3/__snapshots__/3.0.x/v4/default/zod.gen.ts | 8 ++------ .../zod/v3/__snapshots__/3.1.x/mini/default/zod.gen.ts | 4 +--- .../zod/v3/__snapshots__/3.1.x/v3/default/zod.gen.ts | 4 +--- .../zod/v3/__snapshots__/3.1.x/v4/default/zod.gen.ts | 4 +--- .../zod/v4/__snapshots__/2.0.x/mini/default/zod.gen.ts | 4 +--- .../zod/v4/__snapshots__/2.0.x/v3/default/zod.gen.ts | 4 +--- .../zod/v4/__snapshots__/2.0.x/v4/default/zod.gen.ts | 4 +--- .../zod/v4/__snapshots__/3.0.x/mini/default/zod.gen.ts | 8 ++------ .../zod/v4/__snapshots__/3.0.x/v3/default/zod.gen.ts | 8 ++------ .../zod/v4/__snapshots__/3.0.x/v4/default/zod.gen.ts | 8 ++------ .../zod/v4/__snapshots__/3.1.x/mini/default/zod.gen.ts | 4 +--- .../zod/v4/__snapshots__/3.1.x/v3/default/zod.gen.ts | 4 +--- .../zod/v4/__snapshots__/3.1.x/v4/default/zod.gen.ts | 4 +--- packages/openapi-ts/src/plugins/zod/mini/plugin.ts | 3 +++ packages/openapi-ts/src/plugins/zod/v3/plugin.ts | 3 +++ packages/openapi-ts/src/plugins/zod/v4/plugin.ts | 3 +++ 21 files changed, 33 insertions(+), 72 deletions(-) diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/mini/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/mini/default/zod.gen.ts index a5d934eb4..a914024a3 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/mini/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/mini/default/zod.gen.ts @@ -254,9 +254,7 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.union([ - z.literal(true) - ])) + bool: z.optional(z.literal(true)) }); /** diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v3/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v3/default/zod.gen.ts index 341702ba8..fbea7e50b 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v3/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v3/default/zod.gen.ts @@ -254,9 +254,7 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ]).optional(), - bool: z.union([ - z.literal(true) - ]).optional() + bool: z.literal(true).optional() }); /** diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/default/zod.gen.ts index 440c1413b..bfe8ab735 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/default/zod.gen.ts @@ -254,9 +254,7 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.union([ - z.literal(true) - ])) + bool: z.optional(z.literal(true)) }); /** diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/default/zod.gen.ts index 32a249eb8..cbdcfbb53 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/default/zod.gen.ts @@ -336,9 +336,7 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.union([ - z.literal(true) - ])) + bool: z.optional(z.literal(true)) }); /** @@ -779,9 +777,7 @@ export const zModelWithConst = z.object({ String: z.optional(z.enum([ 'String' ])), - number: z.optional(z.union([ - z.literal(0) - ])), + number: z.optional(z.literal(0)), null: z.optional(z.unknown()), withType: z.optional(z.enum([ 'Some string' diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/default/zod.gen.ts index 8ec7c7545..2d2a772a6 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/default/zod.gen.ts @@ -336,9 +336,7 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ]).optional(), - bool: z.union([ - z.literal(true) - ]).optional() + bool: z.literal(true).optional() }); /** @@ -777,9 +775,7 @@ export const zModelWithConst = z.object({ String: z.enum([ 'String' ]).optional(), - number: z.union([ - z.literal(0) - ]).optional(), + number: z.literal(0).optional(), null: z.unknown().optional(), withType: z.enum([ 'Some string' diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/default/zod.gen.ts index ea79fda72..aeb69d39e 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/default/zod.gen.ts @@ -336,9 +336,7 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.union([ - z.literal(true) - ])) + bool: z.optional(z.literal(true)) }); /** @@ -779,9 +777,7 @@ export const zModelWithConst = z.object({ String: z.optional(z.enum([ 'String' ])), - number: z.optional(z.union([ - z.literal(0) - ])), + number: z.optional(z.literal(0)), null: z.optional(z.unknown()), withType: z.optional(z.enum([ 'Some string' diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/default/zod.gen.ts index 5296e1e19..f45f4f952 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/default/zod.gen.ts @@ -345,9 +345,7 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.union([ - z.literal(true) - ])) + bool: z.optional(z.literal(true)) }); /** diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/default/zod.gen.ts index dc8473e99..2005c3692 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/default/zod.gen.ts @@ -345,9 +345,7 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ]).optional(), - bool: z.union([ - z.literal(true) - ]).optional() + bool: z.literal(true).optional() }); /** diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/default/zod.gen.ts index 95f3a0e70..2d383b3ed 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/default/zod.gen.ts @@ -345,9 +345,7 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.union([ - z.literal(true) - ])) + bool: z.optional(z.literal(true)) }); /** diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/default/zod.gen.ts index efffc4e5a..b2bc94a14 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/default/zod.gen.ts @@ -254,9 +254,7 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.union([ - z.literal(true) - ])) + bool: z.optional(z.literal(true)) }); /** diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/default/zod.gen.ts index 9970c33ed..151cc9a84 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/default/zod.gen.ts @@ -254,9 +254,7 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ]).optional(), - bool: z.union([ - z.literal(true) - ]).optional() + bool: z.literal(true).optional() }); /** diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/default/zod.gen.ts index 515ed69ff..54967ed06 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/default/zod.gen.ts @@ -254,9 +254,7 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.union([ - z.literal(true) - ])) + bool: z.optional(z.literal(true)) }); /** diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/default/zod.gen.ts index b84e76509..459ac09e6 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/default/zod.gen.ts @@ -336,9 +336,7 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.union([ - z.literal(true) - ])) + bool: z.optional(z.literal(true)) }); /** @@ -779,9 +777,7 @@ export const zModelWithConst = z.object({ String: z.optional(z.enum([ 'String' ])), - number: z.optional(z.union([ - z.literal(0) - ])), + number: z.optional(z.literal(0)), null: z.optional(z.unknown()), withType: z.optional(z.enum([ 'Some string' diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/default/zod.gen.ts index 5d3031887..83a62aa1c 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/default/zod.gen.ts @@ -336,9 +336,7 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ]).optional(), - bool: z.union([ - z.literal(true) - ]).optional() + bool: z.literal(true).optional() }); /** @@ -777,9 +775,7 @@ export const zModelWithConst = z.object({ String: z.enum([ 'String' ]).optional(), - number: z.union([ - z.literal(0) - ]).optional(), + number: z.literal(0).optional(), null: z.unknown().optional(), withType: z.enum([ 'Some string' diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/default/zod.gen.ts index 0af58af79..9fbb92dbe 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/default/zod.gen.ts @@ -336,9 +336,7 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.union([ - z.literal(true) - ])) + bool: z.optional(z.literal(true)) }); /** @@ -779,9 +777,7 @@ export const zModelWithConst = z.object({ String: z.optional(z.enum([ 'String' ])), - number: z.optional(z.union([ - z.literal(0) - ])), + number: z.optional(z.literal(0)), null: z.optional(z.unknown()), withType: z.optional(z.enum([ 'Some string' diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/default/zod.gen.ts index 41bf680f3..14bef957d 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/default/zod.gen.ts @@ -345,9 +345,7 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.union([ - z.literal(true) - ])) + bool: z.optional(z.literal(true)) }); /** diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/default/zod.gen.ts index e2c612e01..8a9c58819 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/default/zod.gen.ts @@ -345,9 +345,7 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ]).optional(), - bool: z.union([ - z.literal(true) - ]).optional() + bool: z.literal(true).optional() }); /** diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/default/zod.gen.ts index 44aa066af..7ec52bfb3 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/default/zod.gen.ts @@ -345,9 +345,7 @@ export const zModelWithEnum = z.object({ '500 foo.bar', '600 foo&bar' ])), - bool: z.optional(z.union([ - z.literal(true) - ])) + bool: z.optional(z.literal(true)) }); /** diff --git a/packages/openapi-ts/src/plugins/zod/mini/plugin.ts b/packages/openapi-ts/src/plugins/zod/mini/plugin.ts index b51522a0c..d6f6478b1 100644 --- a/packages/openapi-ts/src/plugins/zod/mini/plugin.ts +++ b/packages/openapi-ts/src/plugins/zod/mini/plugin.ts @@ -271,6 +271,9 @@ const enumTypeToZodSchema = ({ }), ], }); + } else if (literalMembers.length === 1) { + // For single-member unions, use the member directly instead of wrapping in z.union() + result.expression = literalMembers[0]; } else { result.expression = tsc.callExpression({ functionName: tsc.propertyAccessExpression({ diff --git a/packages/openapi-ts/src/plugins/zod/v3/plugin.ts b/packages/openapi-ts/src/plugins/zod/v3/plugin.ts index 26bc2c760..1ae78ca28 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/plugin.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/plugin.ts @@ -256,6 +256,9 @@ const enumTypeToZodSchema = ({ }), ], }); + } else if (literalMembers.length === 1) { + // For single-member unions, use the member directly instead of wrapping in z.union() + enumExpression = literalMembers[0]; } else { enumExpression = tsc.callExpression({ functionName: tsc.propertyAccessExpression({ diff --git a/packages/openapi-ts/src/plugins/zod/v4/plugin.ts b/packages/openapi-ts/src/plugins/zod/v4/plugin.ts index c81f5898a..dba3157c1 100644 --- a/packages/openapi-ts/src/plugins/zod/v4/plugin.ts +++ b/packages/openapi-ts/src/plugins/zod/v4/plugin.ts @@ -253,6 +253,9 @@ const enumTypeToZodSchema = ({ }), ], }); + } else if (literalMembers.length === 1) { + // For single-member unions, use the member directly instead of wrapping in z.union() + result.expression = literalMembers[0]; } else { result.expression = tsc.callExpression({ functionName: tsc.propertyAccessExpression({ -- 2.51.2 From 59ea38ea9e47b515c54e55d169591fe6188990b4 Mon Sep 17 00:00:00 2001 From: Lubos Date: Tue, 30 Sep 2025 04:06:29 +0800 Subject: [PATCH 06/22] Fix Zod enum generation for numeric and boolean enums --- .changeset/small-numbers-pull.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/small-numbers-pull.md diff --git a/.changeset/small-numbers-pull.md b/.changeset/small-numbers-pull.md new file mode 100644 index 000000000..a733fae6d --- /dev/null +++ b/.changeset/small-numbers-pull.md @@ -0,0 +1,5 @@ +--- +"@hey-api/openapi-ts": patch +--- + +fix(zod): correct schemas for numeric and boolean enums -- 2.51.2 From 1bf53bb124a3236756b25be6b572d2a8d9f0eeb6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Sep 2025 20:40:13 +0000 Subject: [PATCH 07/22] Fix TypeScript error in Zod v3 plugin for single-member enum optimization Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com> --- packages/openapi-ts/src/plugins/zod/v3/plugin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/openapi-ts/src/plugins/zod/v3/plugin.ts b/packages/openapi-ts/src/plugins/zod/v3/plugin.ts index 1ae78ca28..feeb1fb5d 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/plugin.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/plugin.ts @@ -258,7 +258,7 @@ const enumTypeToZodSchema = ({ }); } else if (literalMembers.length === 1) { // For single-member unions, use the member directly instead of wrapping in z.union() - enumExpression = literalMembers[0]; + enumExpression = literalMembers[0]!; } else { enumExpression = tsc.callExpression({ functionName: tsc.propertyAccessExpression({ -- 2.51.2 From a0cd0fd115cb7505c0249832d8ae077163370f4a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Sep 2025 21:11:50 +0000 Subject: [PATCH 08/22] Update test snapshots for numeric enum Zod schema generation Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com> --- .../test/__snapshots__/3.1.x/webhooks/zod.gen.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/webhooks/zod.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/webhooks/zod.gen.ts index 996228043..016526818 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/webhooks/zod.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/webhooks/zod.gen.ts @@ -630,7 +630,21 @@ export const zSessionUserRoomSystemCalloutFailedWebhookRequest = z.object({ host_id: z.string(), message_id: z.string(), inviter_name: z.string(), - reason_type: z.unknown(), + reason_type: z.union([ + z.literal(0), + z.literal(1), + z.literal(2), + z.literal(3), + z.literal(4), + z.literal(7), + z.literal(8), + z.literal(9), + z.literal(10), + z.literal(11), + z.literal(12), + z.literal(13), + z.literal(14) + ]), participant: z.object({ call_type: z.string(), device_ip: z.string() -- 2.51.2 From f134df319672a4e515da81e1a2d74edc567afa93 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Sep 2025 02:13:16 +0000 Subject: [PATCH 09/22] Initial plan -- 2.51.2 From bbe064b1e36ed905ddf7c7a2bfc706559903dff5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Sep 2025 02:14:24 +0000 Subject: [PATCH 10/22] Initial plan -- 2.51.2 From accfa5a95fd2b0ffd61548911913c7dea73f1e9d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Sep 2025 02:30:49 +0000 Subject: [PATCH 11/22] Fix GitHub issue report enabled by default and --interactive option not working Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com> --- packages/openapi-ts/bin/index.cjs | 17 +-- .../openapi-ts/src/__tests__/error.test.ts | 111 ++++++++++++++++++ 2 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 packages/openapi-ts/src/__tests__/error.test.ts diff --git a/packages/openapi-ts/bin/index.cjs b/packages/openapi-ts/bin/index.cjs index 9889b49ef..3c1fc44b1 100755 --- a/packages/openapi-ts/bin/index.cjs +++ b/packages/openapi-ts/bin/index.cjs @@ -49,6 +49,10 @@ const params = program '--useOptions [value]', 'DEPRECATED. Use options instead of arguments?', ) + .option( + '--interactive [value]', + 'Show an interactive error reporting tool when the program crashes? (default: false)', + ) .parse(process.argv) .opts(); @@ -91,15 +95,14 @@ async function start() { 'experimentalParser', 'exportCore', 'useOptions', + 'interactive', ]); - const isInteractive = - process.stdin.isTTY && - process.stdout.isTTY && - !process.env.CI && - !process.env.NO_INTERACTIVE && - !process.env.NO_INTERACTION; - userConfig.interactive = isInteractive; + // Only set interactive automatically if not explicitly configured by user + // Default should be false according to documentation + if (userConfig.interactive === undefined) { + userConfig.interactive = false; // Default to false as per documentation + } if (params.plugins === true) { userConfig.plugins = []; diff --git a/packages/openapi-ts/src/__tests__/error.test.ts b/packages/openapi-ts/src/__tests__/error.test.ts new file mode 100644 index 000000000..d38215715 --- /dev/null +++ b/packages/openapi-ts/src/__tests__/error.test.ts @@ -0,0 +1,111 @@ +import { describe, expect, it, vi } from 'vitest'; + +import { shouldReportCrash } from '../error'; + +describe('shouldReportCrash', () => { + it('should return false when isInteractive is false', async () => { + const result = await shouldReportCrash({ + error: new Error('test error'), + isInteractive: false, + }); + expect(result).toBe(false); + }); + + it('should return false when isInteractive is undefined', async () => { + const result = await shouldReportCrash({ + error: new Error('test error'), + isInteractive: undefined, + }); + expect(result).toBe(false); + }); + + it('should not prompt when isInteractive is explicitly false', async () => { + // Mock stdin/stdout to ensure we don't wait for user input + const writeSpy = vi + .spyOn(process.stdout, 'write') + .mockImplementation(() => true); + const setEncodingSpy = vi + .spyOn(process.stdin, 'setEncoding') + .mockImplementation(() => {}); + const onceSpy = vi + .spyOn(process.stdin, 'once') + .mockImplementation(() => process.stdin); + + const result = await shouldReportCrash({ + error: new Error('test error'), + isInteractive: false, + }); + + expect(result).toBe(false); + expect(writeSpy).not.toHaveBeenCalled(); + expect(setEncodingSpy).not.toHaveBeenCalled(); + expect(onceSpy).not.toHaveBeenCalled(); + + writeSpy.mockRestore(); + setEncodingSpy.mockRestore(); + onceSpy.mockRestore(); + }); + + it('should prompt when isInteractive is true', async () => { + // Mock stdin/stdout for interactive session + const writeSpy = vi + .spyOn(process.stdout, 'write') + .mockImplementation(() => true); + const setEncodingSpy = vi + .spyOn(process.stdin, 'setEncoding') + .mockImplementation(() => {}); + const onceSpy = vi + .spyOn(process.stdin, 'once') + .mockImplementation((event, callback) => { + // Simulate user typing 'n' + setTimeout(() => { + (callback as any)('n'); + }, 0); + return process.stdin; + }); + + const result = await shouldReportCrash({ + error: new Error('test error'), + isInteractive: true, + }); + + expect(result).toBe(false); // User said 'n' + expect(writeSpy).toHaveBeenCalledWith( + expect.stringContaining('📢 Open a GitHub issue with crash details?'), + ); + + writeSpy.mockRestore(); + setEncodingSpy.mockRestore(); + onceSpy.mockRestore(); + }); + + it('should handle user saying yes to crash report', async () => { + // Mock stdin/stdout for interactive session + const writeSpy = vi + .spyOn(process.stdout, 'write') + .mockImplementation(() => true); + const setEncodingSpy = vi + .spyOn(process.stdin, 'setEncoding') + .mockImplementation(() => {}); + const onceSpy = vi + .spyOn(process.stdin, 'once') + .mockImplementation((event, callback) => { + // Simulate user typing 'y' + setTimeout(() => { + (callback as any)('y'); + }, 0); + return process.stdin; + }); + + const result = await shouldReportCrash({ + error: new Error('test error'), + isInteractive: true, + }); + + expect(result).toBe(true); // User said 'y' + + writeSpy.mockRestore(); + setEncodingSpy.mockRestore(); + onceSpy.mockRestore(); + }); +}); -- 2.51.2 From c19afbf86942ba77e3483b15960f52df1e3ac1f3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Sep 2025 02:34:14 +0000 Subject: [PATCH 12/22] fix(client-ofetch): add credentials property support to buildOfetchOptions Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com> --- .../src/client/client.gen.ts | 13 +- .../src/client/client/client.gen.ts | 126 ++++++++++++------ .../src/client/client/types.gen.ts | 41 +++++- .../src/client/client/utils.gen.ts | 41 +++--- .../openapi-ts-ofetch/src/client/index.ts | 2 +- .../openapi-ts-ofetch/src/client/sdk.gen.ts | 4 +- .../openapi-ts-ofetch/src/client/types.gen.ts | 8 +- .../client-ofetch/__tests__/utils.test.ts | 58 +++++++- .../@hey-api/client-ofetch/bundle/utils.ts | 1 + 9 files changed, 217 insertions(+), 77 deletions(-) diff --git a/examples/openapi-ts-ofetch/src/client/client.gen.ts b/examples/openapi-ts-ofetch/src/client/client.gen.ts index f1e680045..069f4daba 100644 --- a/examples/openapi-ts-ofetch/src/client/client.gen.ts +++ b/examples/openapi-ts-ofetch/src/client/client.gen.ts @@ -1,12 +1,12 @@ // This file is auto-generated by @hey-api/openapi-ts import { - type ClientOptions as DefaultClientOptions, + type ClientOptions, type Config, createClient, createConfig, } from './client'; -import type { ClientOptions } from './types.gen'; +import type { ClientOptions as ClientOptions2 } from './types.gen'; /** * The `createClientConfig()` function will be called on client initialization @@ -16,13 +16,12 @@ import type { ClientOptions } from './types.gen'; * `setConfig()`. This is useful for example if you're using Next.js * to ensure your client always has the correct values. */ -export type CreateClientConfig = - ( - override?: Config, - ) => Config & T>; +export type CreateClientConfig = ( + override?: Config, +) => Config & T>; export const client = createClient( - createConfig({ + createConfig({ baseUrl: 'https://petstore3.swagger.io/api/v3', }), ); diff --git a/examples/openapi-ts-ofetch/src/client/client/client.gen.ts b/examples/openapi-ts-ofetch/src/client/client/client.gen.ts index d2482df58..e0e3c2a41 100644 --- a/examples/openapi-ts-ofetch/src/client/client/client.gen.ts +++ b/examples/openapi-ts-ofetch/src/client/client/client.gen.ts @@ -28,7 +28,7 @@ import { } from './utils.gen'; type ReqInit = Omit & { - body?: any; + body?: BodyInit | null | undefined; headers: ReturnType; }; @@ -49,7 +49,8 @@ export const createClient = (config: Config = {}): Client => { ResolvedRequestOptions >(); - const beforeRequest = async (options: RequestOptions) => { + // precompute serialized / network body + const resolveOptions = async (options: RequestOptions) => { const opts = { ..._config, ...options, @@ -72,12 +73,44 @@ export const createClient = (config: Config = {}): Client => { opts.serializedBody = opts.bodySerializer(opts.body); } - // remove Content-Type header if body is empty to avoid sending invalid requests + // remove Content-Type if body is empty to avoid invalid requests if (opts.body === undefined || opts.serializedBody === '') { opts.headers.delete('Content-Type'); } - // Precompute network body for retries and consistent handling + // if a raw body is provided (no serializer), adjust Content-Type only when it + // equals the default JSON value to better match the concrete body type + if ( + opts.body !== undefined && + opts.bodySerializer === null && + (opts.headers.get('Content-Type') || '').toLowerCase() === + 'application/json' + ) { + const b: unknown = opts.body; + if (typeof FormData !== 'undefined' && b instanceof FormData) { + // let the runtime set the multipart boundary + opts.headers.delete('Content-Type'); + } else if ( + typeof URLSearchParams !== 'undefined' && + b instanceof URLSearchParams + ) { + // standard urlencoded content type (+ charset) + opts.headers.set( + 'Content-Type', + 'application/x-www-form-urlencoded;charset=UTF-8', + ); + } else if (typeof Blob !== 'undefined' && b instanceof Blob) { + const t = b.type?.trim(); + if (t) { + opts.headers.set('Content-Type', t); + } else { + // unknown blob type: avoid sending a misleading JSON header + opts.headers.delete('Content-Type'); + } + } + } + + // precompute network body (stability for retries and interceptors) const networkBody = getValidRequestBody(opts) as | RequestInit['body'] | null @@ -88,20 +121,52 @@ export const createClient = (config: Config = {}): Client => { return { networkBody, opts, url }; }; + // apply request interceptors and mirror header/method/signal back to opts + const applyRequestInterceptors = async ( + request: Request, + opts: ResolvedRequestOptions, + ) => { + for (const fn of interceptors.request.fns) { + if (fn) { + request = await fn(request, opts); + } + } + // reflect interceptor changes into opts used by the network layer + opts.headers = request.headers; + opts.method = request.method as Uppercase; + // ignore request.body changes to avoid turning serialized bodies into streams + // body comes only from getValidRequestBody(options) + // reflect signal if present + opts.signal = (request as any).signal as AbortSignal | undefined; + return request; + }; + + // build ofetch options with stable retry logic based on body repeatability + const buildNetworkOptions = ( + opts: ResolvedRequestOptions, + body: BodyInit | null | undefined, + responseType: OfetchResponseType | undefined, + ) => { + const effectiveRetry = isRepeatableBody(body) + ? (opts.retry as any) + : (0 as any); + return buildOfetchOptions(opts, body, responseType, effectiveRetry); + }; + const request: Client['request'] = async (options) => { const { networkBody: initialNetworkBody, opts, url, - } = await beforeRequest(options as any); - // Compute response type mapping once + } = await resolveOptions(options as any); + // map parseAs -> ofetch responseType once per request const ofetchResponseType: OfetchResponseType | undefined = mapParseAsToResponseType(opts.parseAs, opts.responseType); const $ofetch = opts.ofetch ?? ofetch; - // Always create Request pre-network (align with client-fetch) - let networkBody = initialNetworkBody; + // create Request before network to run middleware consistently + const networkBody = initialNetworkBody; const requestInit: ReqInit = { body: networkBody, headers: opts.headers as Headers, @@ -111,37 +176,14 @@ export const createClient = (config: Config = {}): Client => { }; let request = new Request(url, requestInit); - for (const fn of interceptors.request.fns) { - if (fn) { - request = await fn(request, opts); - } - } - - // Reflect any interceptor changes into opts used for network and downstream - opts.headers = request.headers; - opts.method = request.method as Uppercase; - // Attempt to reflect possible signal/body changes (safely) - - const reqBody = (request as any).body as unknown; - let effectiveRetry = opts.retry; - if (reqBody !== undefined && reqBody !== null) { - if (isRepeatableBody(reqBody)) { - networkBody = reqBody as BodyInit; - } else { - networkBody = reqBody as BodyInit; - // Disable retries for non-repeatable bodies - effectiveRetry = 0 as any; - } - } - - opts.signal = (request as any).signal as AbortSignal | undefined; + request = await applyRequestInterceptors(request, opts); const finalUrl = request.url; - // Build ofetch options and perform the request - const responseOptions = buildOfetchOptions( + // build ofetch options and perform the request (.raw keeps the Response) + const responseOptions = buildNetworkOptions( opts as ResolvedRequestOptions, - networkBody ?? undefined, - effectiveRetry as any, + networkBody, + ofetchResponseType, ); let response = await $ofetch.raw(finalUrl, responseOptions); @@ -167,7 +209,7 @@ export const createClient = (config: Config = {}): Client => { } } - // Ensure error is never undefined after interceptors + // ensure error is never undefined after interceptors finalError = (finalError as any) || ({} as string); if (opts.throwOnError) { @@ -183,9 +225,9 @@ export const createClient = (config: Config = {}): Client => { const makeSseFn = (method: Uppercase) => async (options: RequestOptions) => { - const { networkBody, opts, url } = await beforeRequest(options); + const { networkBody, opts, url } = await resolveOptions(options); const optsForSse: any = { ...opts }; - delete optsForSse.body; + delete optsForSse.body; // body is provided via serializedBody below return createSseClient({ ...optsForSse, fetch: opts.fetch, @@ -193,11 +235,7 @@ export const createClient = (config: Config = {}): Client => { method, onRequest: async (url, init) => { let request = new Request(url, init); - for (const fn of interceptors.request.fns) { - if (fn) { - request = await fn(request, opts); - } - } + request = await applyRequestInterceptors(request, opts); return request; }, serializedBody: networkBody as BodyInit | null | undefined, diff --git a/examples/openapi-ts-ofetch/src/client/client/types.gen.ts b/examples/openapi-ts-ofetch/src/client/client/types.gen.ts index e4925b81b..b44644598 100644 --- a/examples/openapi-ts-ofetch/src/client/client/types.gen.ts +++ b/examples/openapi-ts-ofetch/src/client/client/types.gen.ts @@ -22,15 +22,31 @@ export type ResponseStyle = 'data' | 'fields'; export interface Config extends Omit, CoreConfig { + /** + * HTTP(S) agent configuration (Node.js only). Passed through to ofetch. + */ agent?: OfetchOptions['agent']; /** * Base URL for all requests made by this client. */ baseUrl?: T['baseUrl']; - /** Node-only proxy/agent options */ + /** + * Node-only proxy/agent options. + */ dispatcher?: OfetchOptions['dispatcher']; - /** Optional fetch instance used for SSE streaming */ + /** + * Fetch API implementation. Used for SSE streaming. You can use this option + * to provide a custom fetch instance. + * + * @default globalThis.fetch + */ fetch?: typeof fetch; + /** + * Controls the native ofetch behaviour that throws `FetchError` when + * `response.ok === false`. We default to suppressing it to match the fetch + * client semantics and let `throwOnError` drive the outcome. + */ + ignoreResponseError?: OfetchOptions['ignoreResponseError']; // No custom fetch option: provide custom instance via `ofetch` instead /** * Please don't use the Fetch client for Next.js applications. The `next` @@ -44,10 +60,23 @@ export interface Config * be used for requests instead of the default `ofetch` export. */ ofetch?: typeof ofetch; - /** ofetch interceptors and runtime options */ + /** + * ofetch hook called before a request is sent. + */ onRequest?: OfetchOptions['onRequest']; + /** + * ofetch hook called when a request fails before receiving a response + * (e.g., network errors or aborted requests). + */ onRequestError?: OfetchOptions['onRequestError']; + /** + * ofetch hook called after a successful response is received and parsed. + */ onResponse?: OfetchOptions['onResponse']; + /** + * ofetch hook called when the response indicates an error (non-ok status) + * or when response parsing fails. + */ onResponseError?: OfetchOptions['onResponseError']; /** * Return the response data parsed in a specified format. By default, `auto` @@ -82,7 +111,13 @@ export interface Config * Automatically retry failed requests. */ retry?: OfetchOptions['retry']; + /** + * Delay (in ms) between retry attempts. + */ retryDelay?: OfetchOptions['retryDelay']; + /** + * HTTP status codes that should trigger a retry. + */ retryStatusCodes?: OfetchOptions['retryStatusCodes']; /** * Throw an error instead of returning it in the response? diff --git a/examples/openapi-ts-ofetch/src/client/client/utils.gen.ts b/examples/openapi-ts-ofetch/src/client/client/utils.gen.ts index 17c601b39..a871fdf8a 100644 --- a/examples/openapi-ts-ofetch/src/client/client/utils.gen.ts +++ b/examples/openapi-ts-ofetch/src/client/client/utils.gen.ts @@ -316,34 +316,34 @@ export const wrapErrorReturn = ( export const buildOfetchOptions = ( opts: ResolvedRequestOptions, body: BodyInit | null | undefined, + responseType: OfetchResponseType | undefined, retryOverride?: OfetchOptions['retry'], -): OfetchOptions => { - const responseType = mapParseAsToResponseType( - opts.parseAs, - opts.responseType, - ); - return { +): OfetchOptions => + ({ agent: opts.agent as OfetchOptions['agent'], - body: body as any, + body, + credentials: opts.credentials as OfetchOptions['credentials'], dispatcher: opts.dispatcher as OfetchOptions['dispatcher'], headers: opts.headers as Headers, + ignoreResponseError: + (opts.ignoreResponseError as OfetchOptions['ignoreResponseError']) ?? + true, method: opts.method, onRequest: opts.onRequest as OfetchOptions['onRequest'], onRequestError: opts.onRequestError as OfetchOptions['onRequestError'], onResponse: opts.onResponse as OfetchOptions['onResponse'], onResponseError: opts.onResponseError as OfetchOptions['onResponseError'], parseResponse: opts.parseResponse as OfetchOptions['parseResponse'], - query: undefined, // URL already includes query + // URL already includes query + query: undefined, responseType, - retry: (retryOverride ?? - (opts.retry as OfetchOptions['retry'])) as OfetchOptions['retry'], + retry: retryOverride ?? (opts.retry as OfetchOptions['retry']), retryDelay: opts.retryDelay as OfetchOptions['retryDelay'], retryStatusCodes: opts.retryStatusCodes as OfetchOptions['retryStatusCodes'], signal: opts.signal, timeout: opts.timeout as number | undefined, - } as OfetchOptions; -}; + }) as OfetchOptions; /** * Parse a successful response, handling empty bodies and stream cases. @@ -382,17 +382,27 @@ export const parseSuccess = async ( } } - // Prefer ofetch-populated data + // Prefer ofetch-populated data unless we explicitly need raw `formData` let data: unknown = (response as any)._data; - if (typeof data === 'undefined') { + if (inferredParseAs === 'formData' || typeof data === 'undefined') { switch (inferredParseAs) { case 'arrayBuffer': case 'blob': case 'formData': - case 'json': case 'text': data = await (response as any)[inferredParseAs](); break; + case 'json': { + // Some servers return 200 with no Content-Length and empty body. + // response.json() would throw; detect empty via clone().text() first. + const txt = await response.clone().text(); + if (!txt) { + data = {}; + } else { + data = await (response as any).json(); + } + break; + } case 'stream': return response.body; } @@ -526,6 +536,7 @@ export const createConfig = ( ): Config & T> => ({ ...jsonBodySerializer, headers: defaultHeaders, + ignoreResponseError: true, parseAs: 'auto', querySerializer: defaultQuerySerializer, ...override, diff --git a/examples/openapi-ts-ofetch/src/client/index.ts b/examples/openapi-ts-ofetch/src/client/index.ts index f796d2cc8..57ed02bf5 100644 --- a/examples/openapi-ts-ofetch/src/client/index.ts +++ b/examples/openapi-ts-ofetch/src/client/index.ts @@ -1,4 +1,4 @@ // This file is auto-generated by @hey-api/openapi-ts export * from './sdk.gen'; -export * from './types.gen'; +export type * from './types.gen'; diff --git a/examples/openapi-ts-ofetch/src/client/sdk.gen.ts b/examples/openapi-ts-ofetch/src/client/sdk.gen.ts index 214fbf715..4bb50da39 100644 --- a/examples/openapi-ts-ofetch/src/client/sdk.gen.ts +++ b/examples/openapi-ts-ofetch/src/client/sdk.gen.ts @@ -1,6 +1,6 @@ // This file is auto-generated by @hey-api/openapi-ts -import type { Client, Options as ClientOptions, TDataShape } from './client'; +import type { Client, Options as Options2, TDataShape } from './client'; import { client } from './client.gen'; import type { AddPetData, @@ -65,7 +65,7 @@ import type { export type Options< TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, -> = ClientOptions & { +> = Options2 & { /** * You can provide a client instance returned by `createClient()` instead of * individual options. This might be also useful if you want to implement a diff --git a/examples/openapi-ts-ofetch/src/client/types.gen.ts b/examples/openapi-ts-ofetch/src/client/types.gen.ts index 992c17fb2..a2e6be0fa 100644 --- a/examples/openapi-ts-ofetch/src/client/types.gen.ts +++ b/examples/openapi-ts-ofetch/src/client/types.gen.ts @@ -1,5 +1,9 @@ // This file is auto-generated by @hey-api/openapi-ts +export type ClientOptions = { + baseUrl: 'https://petstore3.swagger.io/api/v3' | (string & {}); +}; + export type Order = { complete?: boolean; id?: number; @@ -693,7 +697,3 @@ export type UpdateUserResponses = { */ 200: unknown; }; - -export type ClientOptions = { - baseUrl: 'https://petstore3.swagger.io/api/v3' | (string & {}); -}; diff --git a/packages/openapi-ts/src/plugins/@hey-api/client-ofetch/__tests__/utils.test.ts b/packages/openapi-ts/src/plugins/@hey-api/client-ofetch/__tests__/utils.test.ts index 19e1b6336..05626ae3b 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/client-ofetch/__tests__/utils.test.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/client-ofetch/__tests__/utils.test.ts @@ -1,7 +1,12 @@ import { describe, expect, it, vi } from 'vitest'; import type { Auth } from '../../client-core/bundle/auth'; -import { mergeHeaders, setAuthParams } from '../bundle/utils'; +import type { ResolvedRequestOptions } from '../bundle/types'; +import { + buildOfetchOptions, + mergeHeaders, + setAuthParams, +} from '../bundle/utils'; describe('mergeHeaders', () => { it('merges plain objects into Headers', () => { @@ -200,3 +205,54 @@ describe('setAuthParams', () => { expect(Object.keys(query).length).toBe(0); }); }); + +describe('buildOfetchOptions', () => { + it('passes through credentials property when provided', () => { + const opts: ResolvedRequestOptions = { + baseUrl: 'https://api.example.com', + credentials: 'include' as const, + headers: new Headers({ 'Content-Type': 'application/json' }), + method: 'GET', + url: '/test', + }; + + const result = buildOfetchOptions(opts, null, undefined); + + expect(result.credentials).toBe('include'); + }); + + it('passes through undefined credentials when not provided', () => { + const opts: ResolvedRequestOptions = { + baseUrl: 'https://api.example.com', + headers: new Headers({ 'Content-Type': 'application/json' }), + method: 'GET', + url: '/test', + }; + + const result = buildOfetchOptions(opts, null, undefined); + + expect(result.credentials).toBeUndefined(); + }); + + it('passes through different credential values', () => { + const testCases: Array = [ + 'omit', + 'same-origin', + 'include', + ]; + + testCases.forEach((credentialValue) => { + const opts: ResolvedRequestOptions = { + baseUrl: 'https://api.example.com', + credentials: credentialValue, + headers: new Headers({ 'Content-Type': 'application/json' }), + method: 'GET', + url: '/test', + }; + + const result = buildOfetchOptions(opts, null, undefined); + + expect(result.credentials).toBe(credentialValue); + }); + }); +}); diff --git a/packages/openapi-ts/src/plugins/@hey-api/client-ofetch/bundle/utils.ts b/packages/openapi-ts/src/plugins/@hey-api/client-ofetch/bundle/utils.ts index b2f1d5552..b488b8d55 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/client-ofetch/bundle/utils.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/client-ofetch/bundle/utils.ts @@ -320,6 +320,7 @@ export const buildOfetchOptions = ( ({ agent: opts.agent as OfetchOptions['agent'], body, + credentials: opts.credentials as OfetchOptions['credentials'], dispatcher: opts.dispatcher as OfetchOptions['dispatcher'], headers: opts.headers as Headers, ignoreResponseError: -- 2.51.2 From 319fea7a51667a8d26778acc94c58965af546f7b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Sep 2025 06:10:02 +0000 Subject: [PATCH 13/22] Fix interactive config not being respected - removed TTY auto-detection override Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com> --- packages/openapi-ts/bin/index.cjs | 11 ------ .../src/__tests__/interactive.test.ts | 34 +++++++++++++++++++ 2 files changed, 34 insertions(+), 11 deletions(-) create mode 100644 packages/openapi-ts/src/__tests__/interactive.test.ts diff --git a/packages/openapi-ts/bin/index.cjs b/packages/openapi-ts/bin/index.cjs index 3c1fc44b1..0621b156e 100755 --- a/packages/openapi-ts/bin/index.cjs +++ b/packages/openapi-ts/bin/index.cjs @@ -49,10 +49,6 @@ const params = program '--useOptions [value]', 'DEPRECATED. Use options instead of arguments?', ) - .option( - '--interactive [value]', - 'Show an interactive error reporting tool when the program crashes? (default: false)', - ) .parse(process.argv) .opts(); @@ -95,15 +91,8 @@ async function start() { 'experimentalParser', 'exportCore', 'useOptions', - 'interactive', ]); - // Only set interactive automatically if not explicitly configured by user - // Default should be false according to documentation - if (userConfig.interactive === undefined) { - userConfig.interactive = false; // Default to false as per documentation - } - if (params.plugins === true) { userConfig.plugins = []; } else if (params.plugins) { diff --git a/packages/openapi-ts/src/__tests__/interactive.test.ts b/packages/openapi-ts/src/__tests__/interactive.test.ts new file mode 100644 index 000000000..b84ba96c4 --- /dev/null +++ b/packages/openapi-ts/src/__tests__/interactive.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, it } from 'vitest'; + +import { initConfigs } from '../config/init'; + +describe('interactive config', () => { + it('should default to false when not provided', async () => { + const result = await initConfigs({ + input: 'test.json', + output: './test', + }); + + expect(result.results[0].config.interactive).toBe(false); + }); + + it('should respect user config when set to true', async () => { + const result = await initConfigs({ + input: 'test.json', + interactive: true, + output: './test', + }); + + expect(result.results[0].config.interactive).toBe(true); + }); + + it('should respect user config when set to false', async () => { + const result = await initConfigs({ + input: 'test.json', + interactive: false, + output: './test', + }); + + expect(result.results[0].config.interactive).toBe(false); + }); +}); -- 2.51.2 From 089bdcb4a3bdae35d0a26d389869384a20a6402b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Sep 2025 06:11:04 +0000 Subject: [PATCH 14/22] test: update snapshots with credentials property Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com> --- .../@hey-api/client-ofetch/base-url-false/client/utils.gen.ts | 1 + .../@hey-api/client-ofetch/base-url-number/client/utils.gen.ts | 1 + .../@hey-api/client-ofetch/base-url-strict/client/utils.gen.ts | 1 + .../@hey-api/client-ofetch/base-url-string/client/utils.gen.ts | 1 + .../@hey-api/client-ofetch/clean-false/client/utils.gen.ts | 1 + .../clients/@hey-api/client-ofetch/default/client/utils.gen.ts | 1 + .../client-ofetch/sdk-client-optional/client/utils.gen.ts | 1 + .../client-ofetch/sdk-client-required/client/utils.gen.ts | 1 + .../client-ofetch/tsconfig-nodenext-sdk/client/utils.gen.ts | 1 + .../main/test/__snapshots__/3.1.x/sse-ofetch/client/utils.gen.ts | 1 + 10 files changed, 10 insertions(+) diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/base-url-false/client/utils.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/base-url-false/client/utils.gen.ts index 1d6d23856..a871fdf8a 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/base-url-false/client/utils.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/base-url-false/client/utils.gen.ts @@ -322,6 +322,7 @@ export const buildOfetchOptions = ( ({ agent: opts.agent as OfetchOptions['agent'], body, + credentials: opts.credentials as OfetchOptions['credentials'], dispatcher: opts.dispatcher as OfetchOptions['dispatcher'], headers: opts.headers as Headers, ignoreResponseError: diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/base-url-number/client/utils.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/base-url-number/client/utils.gen.ts index 1d6d23856..a871fdf8a 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/base-url-number/client/utils.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/base-url-number/client/utils.gen.ts @@ -322,6 +322,7 @@ export const buildOfetchOptions = ( ({ agent: opts.agent as OfetchOptions['agent'], body, + credentials: opts.credentials as OfetchOptions['credentials'], dispatcher: opts.dispatcher as OfetchOptions['dispatcher'], headers: opts.headers as Headers, ignoreResponseError: diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/base-url-strict/client/utils.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/base-url-strict/client/utils.gen.ts index 1d6d23856..a871fdf8a 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/base-url-strict/client/utils.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/base-url-strict/client/utils.gen.ts @@ -322,6 +322,7 @@ export const buildOfetchOptions = ( ({ agent: opts.agent as OfetchOptions['agent'], body, + credentials: opts.credentials as OfetchOptions['credentials'], dispatcher: opts.dispatcher as OfetchOptions['dispatcher'], headers: opts.headers as Headers, ignoreResponseError: diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/base-url-string/client/utils.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/base-url-string/client/utils.gen.ts index 1d6d23856..a871fdf8a 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/base-url-string/client/utils.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/base-url-string/client/utils.gen.ts @@ -322,6 +322,7 @@ export const buildOfetchOptions = ( ({ agent: opts.agent as OfetchOptions['agent'], body, + credentials: opts.credentials as OfetchOptions['credentials'], dispatcher: opts.dispatcher as OfetchOptions['dispatcher'], headers: opts.headers as Headers, ignoreResponseError: diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/clean-false/client/utils.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/clean-false/client/utils.gen.ts index 1d6d23856..a871fdf8a 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/clean-false/client/utils.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/clean-false/client/utils.gen.ts @@ -322,6 +322,7 @@ export const buildOfetchOptions = ( ({ agent: opts.agent as OfetchOptions['agent'], body, + credentials: opts.credentials as OfetchOptions['credentials'], dispatcher: opts.dispatcher as OfetchOptions['dispatcher'], headers: opts.headers as Headers, ignoreResponseError: diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/default/client/utils.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/default/client/utils.gen.ts index 1d6d23856..a871fdf8a 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/default/client/utils.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/default/client/utils.gen.ts @@ -322,6 +322,7 @@ export const buildOfetchOptions = ( ({ agent: opts.agent as OfetchOptions['agent'], body, + credentials: opts.credentials as OfetchOptions['credentials'], dispatcher: opts.dispatcher as OfetchOptions['dispatcher'], headers: opts.headers as Headers, ignoreResponseError: diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/sdk-client-optional/client/utils.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/sdk-client-optional/client/utils.gen.ts index 1d6d23856..a871fdf8a 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/sdk-client-optional/client/utils.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/sdk-client-optional/client/utils.gen.ts @@ -322,6 +322,7 @@ export const buildOfetchOptions = ( ({ agent: opts.agent as OfetchOptions['agent'], body, + credentials: opts.credentials as OfetchOptions['credentials'], dispatcher: opts.dispatcher as OfetchOptions['dispatcher'], headers: opts.headers as Headers, ignoreResponseError: diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/sdk-client-required/client/utils.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/sdk-client-required/client/utils.gen.ts index 1d6d23856..a871fdf8a 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/sdk-client-required/client/utils.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/sdk-client-required/client/utils.gen.ts @@ -322,6 +322,7 @@ export const buildOfetchOptions = ( ({ agent: opts.agent as OfetchOptions['agent'], body, + credentials: opts.credentials as OfetchOptions['credentials'], dispatcher: opts.dispatcher as OfetchOptions['dispatcher'], headers: opts.headers as Headers, ignoreResponseError: diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/tsconfig-nodenext-sdk/client/utils.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/tsconfig-nodenext-sdk/client/utils.gen.ts index b42a0a97c..85e841f36 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/tsconfig-nodenext-sdk/client/utils.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-ofetch/tsconfig-nodenext-sdk/client/utils.gen.ts @@ -322,6 +322,7 @@ export const buildOfetchOptions = ( ({ agent: opts.agent as OfetchOptions['agent'], body, + credentials: opts.credentials as OfetchOptions['credentials'], dispatcher: opts.dispatcher as OfetchOptions['dispatcher'], headers: opts.headers as Headers, ignoreResponseError: diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/sse-ofetch/client/utils.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/sse-ofetch/client/utils.gen.ts index 1d6d23856..a871fdf8a 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/sse-ofetch/client/utils.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/sse-ofetch/client/utils.gen.ts @@ -322,6 +322,7 @@ export const buildOfetchOptions = ( ({ agent: opts.agent as OfetchOptions['agent'], body, + credentials: opts.credentials as OfetchOptions['credentials'], dispatcher: opts.dispatcher as OfetchOptions['dispatcher'], headers: opts.headers as Headers, ignoreResponseError: -- 2.51.2 From ba7e6dc1af3a8e64082bd101de6c1cd6e0e8fc17 Mon Sep 17 00:00:00 2001 From: Lubos Date: Tue, 30 Sep 2025 14:15:00 +0800 Subject: [PATCH 15/22] Fix missing credentials property support Removed unnecessary patch entries and added support for missing credentials property in client-ofetch. --- .changeset/breezy-dodos-jog.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/breezy-dodos-jog.md diff --git a/.changeset/breezy-dodos-jog.md b/.changeset/breezy-dodos-jog.md new file mode 100644 index 000000000..52c9f36cb --- /dev/null +++ b/.changeset/breezy-dodos-jog.md @@ -0,0 +1,5 @@ +--- +"@hey-api/openapi-ts": patch +--- + +fix(client-ofetch): add missing credentials property support -- 2.51.2 From 769269f42cd5e4606d879c78a895bd73b91366f3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Sep 2025 06:24:10 +0000 Subject: [PATCH 16/22] Add test demonstrating the config merge behavior that would fail with the bug Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com> --- .../src/__tests__/interactive.test.ts | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/packages/openapi-ts/src/__tests__/interactive.test.ts b/packages/openapi-ts/src/__tests__/interactive.test.ts index b84ba96c4..ae4a6d77f 100644 --- a/packages/openapi-ts/src/__tests__/interactive.test.ts +++ b/packages/openapi-ts/src/__tests__/interactive.test.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from 'vitest'; import { initConfigs } from '../config/init'; +import { mergeConfigs } from '../config/merge'; describe('interactive config', () => { it('should default to false when not provided', async () => { @@ -31,4 +32,38 @@ describe('interactive config', () => { expect(result.results[0].config.interactive).toBe(false); }); + + it('should allow file config to set interactive when CLI does not provide it', () => { + // This simulates what happens when: + // 1. User has a config file with interactive: false + // 2. CLI doesn't provide interactive (undefined) + // 3. The bug was: bin script would set interactive = isInteractive (true in TTY) + + const fileConfig = { + input: 'test.json', + interactive: false, + output: './test', + }; + + // CLI config without interactive (correct behavior after fix) + const cliConfigWithoutInteractive = { + input: 'test.json', + output: './test', + }; + + // CLI config with interactive set to true (simulating the bug) + const cliConfigWithInteractiveBug = { + input: 'test.json', + interactive: true, + output: './test', // Bug: bin script was setting this even when user didn't provide it + }; + + // After fix: file config's interactive should be preserved + const mergedCorrect = mergeConfigs(fileConfig, cliConfigWithoutInteractive); + expect(mergedCorrect.interactive).toBe(false); + + // Before fix: CLI's auto-detected interactive would override file config + const mergedWithBug = mergeConfigs(fileConfig, cliConfigWithInteractiveBug); + expect(mergedWithBug.interactive).toBe(true); // This was the bug - it overrode the file config + }); }); -- 2.51.2 From 801532b09293386e95d0bfc1e2abebcd37f1c2ef Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Sep 2025 06:52:31 +0000 Subject: [PATCH 17/22] Move TTY detection logic to src with environment variable support Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com> --- .../src/__tests__/interactive.test.ts | 112 +++++++++++++++++- packages/openapi-ts/src/config/init.ts | 21 +++- 2 files changed, 129 insertions(+), 4 deletions(-) diff --git a/packages/openapi-ts/src/__tests__/interactive.test.ts b/packages/openapi-ts/src/__tests__/interactive.test.ts index ae4a6d77f..934cbb944 100644 --- a/packages/openapi-ts/src/__tests__/interactive.test.ts +++ b/packages/openapi-ts/src/__tests__/interactive.test.ts @@ -1,15 +1,16 @@ -import { describe, expect, it } from 'vitest'; +import { afterEach, describe, expect, it } from 'vitest'; -import { initConfigs } from '../config/init'; +import { detectInteractiveSession, initConfigs } from '../config/init'; import { mergeConfigs } from '../config/merge'; describe('interactive config', () => { - it('should default to false when not provided', async () => { + it('should use detectInteractiveSession when not provided', async () => { const result = await initConfigs({ input: 'test.json', output: './test', }); + // In test environment, TTY is typically not available, so it should be false expect(result.results[0].config.interactive).toBe(false); }); @@ -67,3 +68,108 @@ describe('interactive config', () => { expect(mergedWithBug.interactive).toBe(true); // This was the bug - it overrode the file config }); }); + +describe('detectInteractiveSession', () => { + const originalEnv = process.env; + const originalStdin = process.stdin; + const originalStdout = process.stdout; + + afterEach(() => { + process.env = originalEnv; + Object.defineProperty(process, 'stdin', { value: originalStdin }); + Object.defineProperty(process, 'stdout', { value: originalStdout }); + }); + + it('should return false when CI environment variable is set', () => { + process.env = { ...originalEnv, CI: 'true' }; + Object.defineProperty(process.stdin, 'isTTY', { + configurable: true, + value: true, + }); + Object.defineProperty(process.stdout, 'isTTY', { + configurable: true, + value: true, + }); + + expect(detectInteractiveSession()).toBe(false); + }); + + it('should return false when NO_INTERACTIVE environment variable is set', () => { + process.env = { ...originalEnv, NO_INTERACTIVE: '1' }; + Object.defineProperty(process.stdin, 'isTTY', { + configurable: true, + value: true, + }); + Object.defineProperty(process.stdout, 'isTTY', { + configurable: true, + value: true, + }); + + expect(detectInteractiveSession()).toBe(false); + }); + + it('should return false when NO_INTERACTION environment variable is set', () => { + process.env = { ...originalEnv, NO_INTERACTION: '1' }; + Object.defineProperty(process.stdin, 'isTTY', { + configurable: true, + value: true, + }); + Object.defineProperty(process.stdout, 'isTTY', { + configurable: true, + value: true, + }); + + expect(detectInteractiveSession()).toBe(false); + }); + + it('should return false when stdin is not TTY', () => { + process.env = { ...originalEnv }; + delete process.env.CI; + delete process.env.NO_INTERACTIVE; + delete process.env.NO_INTERACTION; + Object.defineProperty(process.stdin, 'isTTY', { + configurable: true, + value: false, + }); + Object.defineProperty(process.stdout, 'isTTY', { + configurable: true, + value: true, + }); + + expect(detectInteractiveSession()).toBe(false); + }); + + it('should return false when stdout is not TTY', () => { + process.env = { ...originalEnv }; + delete process.env.CI; + delete process.env.NO_INTERACTIVE; + delete process.env.NO_INTERACTION; + Object.defineProperty(process.stdin, 'isTTY', { + configurable: true, + value: true, + }); + Object.defineProperty(process.stdout, 'isTTY', { + configurable: true, + value: false, + }); + + expect(detectInteractiveSession()).toBe(false); + }); + + it('should return true when TTY is available and no blocking env vars are set', () => { + process.env = { ...originalEnv }; + delete process.env.CI; + delete process.env.NO_INTERACTIVE; + delete process.env.NO_INTERACTION; + Object.defineProperty(process.stdin, 'isTTY', { + configurable: true, + value: true, + }); + Object.defineProperty(process.stdout, 'isTTY', { + configurable: true, + value: true, + }); + + expect(detectInteractiveSession()).toBe(true); + }); +}); diff --git a/packages/openapi-ts/src/config/init.ts b/packages/openapi-ts/src/config/init.ts index e779a8b12..2b354086e 100644 --- a/packages/openapi-ts/src/config/init.ts +++ b/packages/openapi-ts/src/config/init.ts @@ -13,6 +13,20 @@ import { getProjectDependencies } from './packages'; import { getParser } from './parser'; import { getPlugins } from './plugins'; +/** + * Detect if the current session is interactive based on TTY status and environment variables. + * This is used as a fallback when the user doesn't explicitly set the interactive option. + * @internal + */ +export const detectInteractiveSession = (): boolean => + !!( + process.stdin.isTTY && + process.stdout.isTTY && + !process.env.CI && + !process.env.NO_INTERACTIVE && + !process.env.NO_INTERACTION + ); + /** * @internal */ @@ -59,12 +73,17 @@ export const initConfigs = async ( dryRun = false, experimentalParser = true, exportCore = true, - interactive = false, name, request, useOptions = true, } = userConfig; + // Use environment-aware detection only when user doesn't explicitly set interactive + const interactive = + userConfig.interactive !== undefined + ? userConfig.interactive + : detectInteractiveSession(); + const errors: Array = []; const logs = getLogs(userConfig); -- 2.51.2 From 2c64ad407ebf6cebe6aef553c9fa837da9d78f05 Mon Sep 17 00:00:00 2001 From: Lubos Date: Tue, 30 Sep 2025 15:02:07 +0800 Subject: [PATCH 18/22] Update init.ts --- packages/openapi-ts/src/config/init.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/openapi-ts/src/config/init.ts b/packages/openapi-ts/src/config/init.ts index 2b354086e..b7427bd27 100644 --- a/packages/openapi-ts/src/config/init.ts +++ b/packages/openapi-ts/src/config/init.ts @@ -19,7 +19,7 @@ import { getPlugins } from './plugins'; * @internal */ export const detectInteractiveSession = (): boolean => - !!( + Boolean( process.stdin.isTTY && process.stdout.isTTY && !process.env.CI && @@ -78,7 +78,6 @@ export const initConfigs = async ( useOptions = true, } = userConfig; - // Use environment-aware detection only when user doesn't explicitly set interactive const interactive = userConfig.interactive !== undefined ? userConfig.interactive -- 2.51.2 From 21e9fa089d2305714f37c1a16cb3e6f9fedb49b9 Mon Sep 17 00:00:00 2001 From: Lubos Date: Tue, 30 Sep 2025 15:04:04 +0800 Subject: [PATCH 19/22] Fix CLI config override for interactive settings --- .changeset/lovely-eels-pretend.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/lovely-eels-pretend.md diff --git a/.changeset/lovely-eels-pretend.md b/.changeset/lovely-eels-pretend.md new file mode 100644 index 000000000..c35b3b897 --- /dev/null +++ b/.changeset/lovely-eels-pretend.md @@ -0,0 +1,5 @@ +--- +"@hey-api/openapi-ts": patch +--- + +fix(config): do not override interactive config from CLI if defined in config file -- 2.51.2 From 1d09c1d889e8382284078941c967a3ac52cb2e28 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Sep 2025 09:45:12 +0000 Subject: [PATCH 20/22] Fix linting issues - correct indentation in detectInteractiveSession Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com> --- packages/openapi-ts/src/config/init.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/openapi-ts/src/config/init.ts b/packages/openapi-ts/src/config/init.ts index b7427bd27..0a7b8c535 100644 --- a/packages/openapi-ts/src/config/init.ts +++ b/packages/openapi-ts/src/config/init.ts @@ -21,10 +21,10 @@ import { getPlugins } from './plugins'; export const detectInteractiveSession = (): boolean => Boolean( process.stdin.isTTY && - process.stdout.isTTY && - !process.env.CI && - !process.env.NO_INTERACTIVE && - !process.env.NO_INTERACTION + process.stdout.isTTY && + !process.env.CI && + !process.env.NO_INTERACTIVE && + !process.env.NO_INTERACTION, ); /** -- 2.51.2 From bfae15d58092390e4a418c5f1fe06e497c0fa05d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Sep 2025 11:01:08 +0000 Subject: [PATCH 21/22] Fix typecheck issues in test files Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com> --- packages/openapi-ts/src/__tests__/error.test.ts | 10 +++++----- packages/openapi-ts/src/__tests__/interactive.test.ts | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/openapi-ts/src/__tests__/error.test.ts b/packages/openapi-ts/src/__tests__/error.test.ts index d38215715..91f4c86fa 100644 --- a/packages/openapi-ts/src/__tests__/error.test.ts +++ b/packages/openapi-ts/src/__tests__/error.test.ts @@ -26,7 +26,7 @@ describe('shouldReportCrash', () => { .mockImplementation(() => true); const setEncodingSpy = vi .spyOn(process.stdin, 'setEncoding') - .mockImplementation(() => {}); + .mockImplementation(() => process.stdin as any); const onceSpy = vi .spyOn(process.stdin, 'once') .mockImplementation(() => process.stdin); @@ -53,10 +53,10 @@ describe('shouldReportCrash', () => { .mockImplementation(() => true); const setEncodingSpy = vi .spyOn(process.stdin, 'setEncoding') - .mockImplementation(() => {}); + .mockImplementation(() => process.stdin as any); const onceSpy = vi .spyOn(process.stdin, 'once') - .mockImplementation((event, callback) => { + .mockImplementation((_event, callback) => { // Simulate user typing 'n' setTimeout(() => { (callback as any)('n'); @@ -86,10 +86,10 @@ describe('shouldReportCrash', () => { .mockImplementation(() => true); const setEncodingSpy = vi .spyOn(process.stdin, 'setEncoding') - .mockImplementation(() => {}); + .mockImplementation(() => process.stdin as any); const onceSpy = vi .spyOn(process.stdin, 'once') - .mockImplementation((event, callback) => { + .mockImplementation((_event, callback) => { // Simulate user typing 'y' setTimeout(() => { (callback as any)('y'); diff --git a/packages/openapi-ts/src/__tests__/interactive.test.ts b/packages/openapi-ts/src/__tests__/interactive.test.ts index 934cbb944..e5b2efc60 100644 --- a/packages/openapi-ts/src/__tests__/interactive.test.ts +++ b/packages/openapi-ts/src/__tests__/interactive.test.ts @@ -11,7 +11,7 @@ describe('interactive config', () => { }); // In test environment, TTY is typically not available, so it should be false - expect(result.results[0].config.interactive).toBe(false); + expect(result.results[0]?.config.interactive).toBe(false); }); it('should respect user config when set to true', async () => { @@ -21,7 +21,7 @@ describe('interactive config', () => { output: './test', }); - expect(result.results[0].config.interactive).toBe(true); + expect(result.results[0]?.config.interactive).toBe(true); }); it('should respect user config when set to false', async () => { @@ -31,7 +31,7 @@ describe('interactive config', () => { output: './test', }); - expect(result.results[0].config.interactive).toBe(false); + expect(result.results[0]?.config.interactive).toBe(false); }); it('should allow file config to set interactive when CLI does not provide it', () => { -- 2.51.2 From 9ba9e7dc2c01fcec86c1de56cadbc62eb39b8b27 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 30 Sep 2025 12:08:06 +0000 Subject: [PATCH 22/22] ci: release --- .changeset/breezy-dodos-jog.md | 5 ----- .changeset/lovely-eels-pretend.md | 5 ----- .changeset/small-numbers-pull.md | 5 ----- packages/openapi-ts/CHANGELOG.md | 10 ++++++++++ packages/openapi-ts/package.json | 2 +- 5 files changed, 11 insertions(+), 16 deletions(-) delete mode 100644 .changeset/breezy-dodos-jog.md delete mode 100644 .changeset/lovely-eels-pretend.md delete mode 100644 .changeset/small-numbers-pull.md diff --git a/.changeset/breezy-dodos-jog.md b/.changeset/breezy-dodos-jog.md deleted file mode 100644 index 52c9f36cb..000000000 --- a/.changeset/breezy-dodos-jog.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@hey-api/openapi-ts": patch ---- - -fix(client-ofetch): add missing credentials property support diff --git a/.changeset/lovely-eels-pretend.md b/.changeset/lovely-eels-pretend.md deleted file mode 100644 index c35b3b897..000000000 --- a/.changeset/lovely-eels-pretend.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@hey-api/openapi-ts": patch ---- - -fix(config): do not override interactive config from CLI if defined in config file diff --git a/.changeset/small-numbers-pull.md b/.changeset/small-numbers-pull.md deleted file mode 100644 index a733fae6d..000000000 --- a/.changeset/small-numbers-pull.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@hey-api/openapi-ts": patch ---- - -fix(zod): correct schemas for numeric and boolean enums diff --git a/packages/openapi-ts/CHANGELOG.md b/packages/openapi-ts/CHANGELOG.md index 678a540da..893a74c5a 100644 --- a/packages/openapi-ts/CHANGELOG.md +++ b/packages/openapi-ts/CHANGELOG.md @@ -1,5 +1,15 @@ # @hey-api/openapi-ts +## 0.84.4 + +### Patch Changes + +- fix(client-ofetch): add missing credentials property support ([#2710](https://github.com/hey-api/openapi-ts/pull/2710)) ([`ba7e6dc`](https://github.com/hey-api/openapi-ts/commit/ba7e6dc1af3a8e64082bd101de6c1cd6e0e8fc17)) by [@copilot-swe-agent](https://github.com/apps/copilot-swe-agent) + +- fix(config): do not override interactive config from CLI if defined in config file ([#2708](https://github.com/hey-api/openapi-ts/pull/2708)) ([`21e9fa0`](https://github.com/hey-api/openapi-ts/commit/21e9fa089d2305714f37c1a16cb3e6f9fedb49b9)) by [@copilot-swe-agent](https://github.com/apps/copilot-swe-agent) + +- fix(zod): correct schemas for numeric and boolean enums ([#2704](https://github.com/hey-api/openapi-ts/pull/2704)) ([`59ea38e`](https://github.com/hey-api/openapi-ts/commit/59ea38ea9e47b515c54e55d169591fe6188990b4)) by [@copilot-swe-agent](https://github.com/apps/copilot-swe-agent) + ## 0.84.3 ### Patch Changes diff --git a/packages/openapi-ts/package.json b/packages/openapi-ts/package.json index cbd386880..e802b2141 100644 --- a/packages/openapi-ts/package.json +++ b/packages/openapi-ts/package.json @@ -1,6 +1,6 @@ { "name": "@hey-api/openapi-ts", - "version": "0.84.3", + "version": "0.84.4", "description": "🚀 The OpenAPI to TypeScript codegen. Generate clients, SDKs, validators, and more.", "homepage": "https://heyapi.dev/", "repository": { -- 2.51.2