diff --git a/package.json b/package.json index 6e5fc8c..221100d 100644 --- a/package.json +++ b/package.json @@ -16,11 +16,11 @@ "test": "NODE_ENV=test mocha --exit" }, "dependencies": { - "@asteasolutions/zod-to-openapi": "^3.4.0" + "@asteasolutions/zod-to-openapi": "^4.8.0" }, "peerDependencies": { "express": "^5.0.0-beta.1", - "openapi3-ts": "^3.2.0", + "openapi3-ts": "^4.1.2", "zod": "^3" }, "devDependencies": { @@ -40,7 +40,7 @@ "express": "^5.0.0-beta.1", "husky": "^9.1.7", "mocha": "^10.8.2", - "openapi3-ts": "^3.2.0", + "openapi3-ts": "^4.1.2", "pinst": "^3.0.0", "semantic-release": "^24.2.0", "ts-node": "^10.9.2", diff --git a/src/openAPI.test.ts b/src/openAPI.test.ts index d8d7f14..c0fdd04 100644 --- a/src/openAPI.test.ts +++ b/src/openAPI.test.ts @@ -1,6 +1,7 @@ import { expect, spy, use } from "chai"; import chaiSpies from "chai-spies"; import { Router } from "express"; +import type { PathItemObject } from "openapi3-ts/oas30"; import * as schemas from "../mocks/schemas"; import { buildOpenAPIDocument } from "./openAPI"; import { openAPIRoute } from "./openAPIRoute"; @@ -104,9 +105,11 @@ describe("buildOpenAPIDocument", () => { expect(document.paths).to.be.an("object"); for (const path in document.paths) { - for (const method in document.paths[path]) { - expect(document.paths[path][method].responses).to.have.property("401"); - expect(document.paths[path][method].responses).to.have.property("403"); + for (const key in document.paths[path]) { + const method = key as keyof PathItemObject; + const { responses } = document.paths[path][method]; + expect(responses).to.have.property("401"); + expect(responses).to.have.property("403"); } } }); @@ -157,7 +160,8 @@ describe("buildOpenAPIDocument", () => { const errors = { 401: "Unauthorized", 403: "Forbidden" }; const document = buildOpenAPIDocument({ config, routers, schemaPaths, errors, openApiVersion }); - const responseSchema = document.paths["/test"].get.responses["200"].content["application/json"].schema; + const method = document.paths["/test"].get; + const responseSchema = method!.responses["200"].content["application/json"].schema; expect(responseSchema.$ref.includes("ResponseSchema")).to.be.true; }); @@ -182,7 +186,9 @@ describe("buildOpenAPIDocument", () => { const errors = { 401: "Unauthorized", 403: "Forbidden" }; const document = buildOpenAPIDocument({ config, routers, schemaPaths, errors, openApiVersion }); - const requestBodySchema = document.paths["/test"].get.requestBody.content["application/json"].schema; + const method = document.paths["/test"].get; + // @ts-ignore + const requestBodySchema = method!.requestBody?.content["application/json"].schema; expect(requestBodySchema.$ref.includes("BodySchema")).to.be.true; }); diff --git a/src/openAPI.ts b/src/openAPI.ts index ec7d30b..6481f02 100644 --- a/src/openAPI.ts +++ b/src/openAPI.ts @@ -6,7 +6,7 @@ import { RouteConfig, } from "@asteasolutions/zod-to-openapi"; import { RequestHandler, Router } from "express"; -import type { ComponentsObject } from "openapi3-ts"; +import type { ComponentsObject } from "openapi3-ts/oas30"; import { z, ZodArray, ZodEffects, ZodObject } from "zod"; import { getSchemaOfOpenAPIRoute } from "./openAPIRoute"; import { ErrorResponse } from "./schemas"; @@ -201,7 +201,8 @@ export function buildOpenAPIDocument(args: { // Verify that none of the "parameters" are appearing as optional, which is invalid // in the official OpenAPI spec and unsupported by readme.io for (const [route, impl] of Object.entries(openapiJSON.paths)) { - for (const method of Object.keys(impl)) { + for (const key of Object.keys(impl)) { + const method = key as keyof typeof impl; for (const param of impl[method].parameters || []) { if (param.required === false && param.in === "path") { param.required = true; diff --git a/yarn.lock b/yarn.lock index b06a1c3..fa3c167 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,12 +2,12 @@ # yarn lockfile v1 -"@asteasolutions/zod-to-openapi@^3.4.0": - version "3.4.0" - resolved "https://registry.yarnpkg.com/@asteasolutions/zod-to-openapi/-/zod-to-openapi-3.4.0.tgz#7b74b1c32b102048a856b990577f1ebe1861aa18" - integrity sha512-xilC2RmsAoJoD0RqZrqArNuC8ByzBIkElIQWEIwreCwSGPHbv2my3d4mnY4x0qQWmSpVnpphEU3Cjl73MpOHjQ== +"@asteasolutions/zod-to-openapi@^4.8.0": + version "4.8.0" + resolved "https://registry.yarnpkg.com/@asteasolutions/zod-to-openapi/-/zod-to-openapi-4.8.0.tgz#34c29228c5cd0098a534b3536c9f486fafca2cc1" + integrity sha512-FQlBeHIhSoEhjddAWD1v2zbeBESfTdaAVQuUr0RY9t0rN8ogoEaGirv2Ne8kQQTAVGydJzUMAOIlPULEOQDoeA== dependencies: - openapi3-ts "^3.1.1" + openapi3-ts "^4.1.2" "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.22.13": version "7.26.2" @@ -3432,12 +3432,12 @@ onetime@^6.0.0: dependencies: mimic-fn "^4.0.0" -openapi3-ts@^3.1.1, openapi3-ts@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/openapi3-ts/-/openapi3-ts-3.2.0.tgz#7e30d33c480e938e67e809ab16f419bc9beae3f8" - integrity sha512-/ykNWRV5Qs0Nwq7Pc0nJ78fgILvOT/60OxEmB3v7yQ8a8Bwcm43D4diaYazG/KBn6czA+52XYy931WFLMCUeSg== +openapi3-ts@^4.1.2: + version "4.4.0" + resolved "https://registry.yarnpkg.com/openapi3-ts/-/openapi3-ts-4.4.0.tgz#eff29958e601deec24459ea811989a4fb59d4116" + integrity sha512-9asTNB9IkKEzWMcHmVZE7Ts3kC9G7AFHfs8i7caD8HbI76gEjdkId4z/AkP83xdZsH7PLAnnbl47qZkXuxpArw== dependencies: - yaml "^2.2.1" + yaml "^2.5.0" p-each-series@^3.0.0: version "3.0.0" @@ -4804,7 +4804,7 @@ yallist@^5.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-5.0.0.tgz#00e2de443639ed0d78fd87de0d27469fbcffb533" integrity sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw== -yaml@^2.2.1: +yaml@^2.5.0: version "2.6.1" resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.6.1.tgz#42f2b1ba89203f374609572d5349fb8686500773" integrity sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==