{"_id":"@alex8628/trpc-swagger","_rev":"4-ea79f1de7b8c78ba126eb5c9c07054bf","name":"@alex8628/trpc-swagger","dist-tags":{"latest":"1.2.5"},"versions":{"1.2.1":{"name":"@alex8628/trpc-swagger","private":false,"license":"MIT","version":"1.2.1","description":"tRPC Swagger Wrapper","author":{"name":"https://github.com/giftedunicorn"},"homepage":"https://github.com/giftedunicorn/trpc-swagger","bugs":{"url":"https://github.com/giftedunicorn/trpc-swagger/issues"},"keywords":["trpc","openapi","swagger"],"typings":"build/index.d.ts","main":"build/index.js","repository":{"type":"git","url":"git+https://github.com/giftedunicorn/trpc-swagger.git"},"scripts":{"test":"tsc --noEmit && jest --verbose","build":"rimraf dist && tsc -p tsconfig.build.json","format":"eslint --fix \"./packages/**/*.{js,jsx,ts,tsx}\"","lint:fix":"eslint --fix \"./packages/**/*.{js,jsx,ts,tsx}\"","lint":"eslint \"./packages/**/*.{js,jsx,ts,tsx}\""},"workspaces":[".","examples/with-express","examples/with-fastify","examples/with-interop","examples/with-nextjs","examples/with-nextjs-app","examples/with-nuxtjs","examples/with-serverless"],"peerDependencies":{"@trpc/server":"11.0.0-next-beta.281","zod":"^3.14.4"},"dependencies":{"co-body":"^6.1.0","h3":"^1.11.1","lodash.clonedeep":"^4.5.0","node-mocks-http":"^1.14.1","openapi-types":"^12.1.3","zod-to-json-schema":"^3.22.5"},"devDependencies":{"@trpc/client":"11.0.0-next-beta.281","@trpc/server":"11.0.0-next-beta.281","@types/aws-lambda":"^8.10.136","@types/co-body":"^6.1.3","@types/express":"^4.17.21","@types/jest":"^29.5.12","@types/lodash.clonedeep":"^4.5.9","@types/node":"^20.11.30","@types/node-fetch":"^2.6.11","@typescript-eslint/eslint-plugin":"^7.3.1","@typescript-eslint/parser":"^7.3.1","aws-lambda":"^1.0.7","eslint":"^8.57.0","eslint-config-airbnb":"19.0.4","eslint-plugin-import":"^2.29.1","eslint-plugin-jsx-a11y":"^6.8.0","eslint-plugin-promise":"^6.1.1","eslint-plugin-react":"^7.34.1","eslint-plugin-react-hooks":"^4.6.0","express":"^4.19.1","fastify":"^4.26.2","jest":"^29.7.0","next":"^14.1.4","node-fetch":"^2.7.0","openapi-schema-validator":"^12.1.3","rimraf":"^5.0.5","semver":"^7.6.0","superjson":"^1.13.3","ts-jest":"^29.1.2","ts-node":"^10.9.2","typescript":"^5.4.3","zod":"^3.22.4"},"directories":{"example":"examples","test":"test"},"_id":"@alex8628/trpc-swagger@1.2.1","gitHead":"6bb228f51c8fb28b24ad4fd6bb71d9adeb1e04c2","_nodeVersion":"20.11.1","_npmVersion":"10.2.4","dist":{"integrity":"sha512-EucqreHnNjMVRiOx5UuTIq6bMrIskyfMl9gOqtvUOvhWNfHpB6XYC03S5zEdq7KyL3Fae0NsMNVfl6B3fTOr+Q==","shasum":"47679949d43b6daa64b9adff65a289c540636ad3","tarball":"https://registry.npmjs.org/@alex8628/trpc-swagger/-/trpc-swagger-1.2.1.tgz","fileCount":87,"unpackedSize":139611,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFocwNUtE4vdvZ6SRuntqF0mPmx41imh4/PiPBGtjV89AiEAjzu2cqNImbymSgTE/pvtMeUqnJlWnwyAxl1kKEMNkDU="}]},"_npmUser":{"name":"giftedunicorn","email":"shenjian8628@gmail.com"},"maintainers":[{"name":"giftedunicorn","email":"shenjian8628@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/trpc-swagger_1.2.1_1711616595372_0.598933861255146"},"_hasShrinkwrap":false},"1.2.2":{"name":"@alex8628/trpc-swagger","private":false,"license":"MIT","version":"1.2.2","description":"tRPC Swagger Wrapper","author":{"name":"https://github.com/giftedunicorn"},"homepage":"https://github.com/giftedunicorn/trpc-swagger","bugs":{"url":"https://github.com/giftedunicorn/trpc-swagger/issues"},"keywords":["trpc","openapi","swagger"],"typings":"build/index.d.ts","main":"build/index.js","repository":{"type":"git","url":"git+https://github.com/giftedunicorn/trpc-swagger.git"},"scripts":{"test":"tsc --noEmit && jest --verbose","build":"rimraf dist && tsc -p tsconfig.build.json","format":"eslint --fix \"./packages/**/*.{js,jsx,ts,tsx}\"","lint:fix":"eslint --fix \"./packages/**/*.{js,jsx,ts,tsx}\"","lint":"eslint \"./packages/**/*.{js,jsx,ts,tsx}\""},"workspaces":[".","examples/with-express","examples/with-fastify","examples/with-interop","examples/with-nextjs","examples/with-nextjs-app","examples/with-nuxtjs","examples/with-serverless"],"peerDependencies":{"@trpc/server":"11.0.0-next-beta.281","zod":"^3.14.4"},"dependencies":{"co-body":"^6.1.0","h3":"^1.11.1","lodash.clonedeep":"^4.5.0","node-mocks-http":"^1.14.1","openapi-types":"^12.1.3","zod-to-json-schema":"^3.22.5"},"devDependencies":{"@trpc/client":"11.0.0-next-beta.281","@trpc/server":"11.0.0-next-beta.281","@types/aws-lambda":"^8.10.136","@types/co-body":"^6.1.3","@types/express":"^4.17.21","@types/jest":"^29.5.12","@types/lodash.clonedeep":"^4.5.9","@types/node":"^20.11.30","@types/node-fetch":"^2.6.11","@typescript-eslint/eslint-plugin":"^7.3.1","@typescript-eslint/parser":"^7.3.1","aws-lambda":"^1.0.7","eslint":"^8.57.0","eslint-config-airbnb":"19.0.4","eslint-plugin-import":"^2.29.1","eslint-plugin-jsx-a11y":"^6.8.0","eslint-plugin-promise":"^6.1.1","eslint-plugin-react":"^7.34.1","eslint-plugin-react-hooks":"^4.6.0","express":"^4.19.1","fastify":"^4.26.2","jest":"^29.7.0","next":"^14.1.4","node-fetch":"^2.7.0","openapi-schema-validator":"^12.1.3","rimraf":"^5.0.5","semver":"^7.6.0","superjson":"^1.13.3","ts-jest":"^29.1.2","ts-node":"^10.9.2","typescript":"^5.4.3","zod":"^3.22.4"},"directories":{"example":"examples","test":"test"},"_id":"@alex8628/trpc-swagger@1.2.2","gitHead":"9a8c2155bbcdadd50e9b6f65e0d5775a8429a552","_nodeVersion":"20.11.1","_npmVersion":"10.2.4","dist":{"integrity":"sha512-VeRX8In8PwoXncYCmMxMrWQpO/UYwydRAzmB1Avyx/J33Bfe/UTEpgaVOhWZ4DpmxnCLocQNBu9TVek+0yD8pg==","shasum":"ddefa2362eb8aa081b961b8d5e3075340599ff55","tarball":"https://registry.npmjs.org/@alex8628/trpc-swagger/-/trpc-swagger-1.2.2.tgz","fileCount":87,"unpackedSize":139611,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD+fqIfdVtZWGSveFzR9SwQWffaEgXi6N7oweuePHpcpQIhAJwEnbGqDEGKwzF20jsmYHnVsoxdZyU3b5v12AHqEOxi"}]},"_npmUser":{"name":"giftedunicorn","email":"shenjian8628@gmail.com"},"maintainers":[{"name":"giftedunicorn","email":"shenjian8628@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/trpc-swagger_1.2.2_1711617151727_0.6872554395621273"},"_hasShrinkwrap":false},"1.2.3":{"name":"@alex8628/trpc-swagger","private":false,"license":"MIT","version":"1.2.3","description":"tRPC Swagger Wrapper","author":{"name":"https://github.com/giftedunicorn"},"homepage":"https://github.com/giftedunicorn/trpc-swagger","bugs":{"url":"https://github.com/giftedunicorn/trpc-swagger/issues"},"keywords":["trpc","openapi","swagger"],"typings":"build/index.d.ts","main":"build/index.js","repository":{"type":"git","url":"git+https://github.com/giftedunicorn/trpc-swagger.git"},"scripts":{"test":"tsc --noEmit && jest --verbose","build":"rimraf dist && tsc -p tsconfig.build.json","format":"eslint --fix \"./packages/**/*.{js,jsx,ts,tsx}\"","lint:fix":"eslint --fix \"./packages/**/*.{js,jsx,ts,tsx}\"","lint":"eslint \"./packages/**/*.{js,jsx,ts,tsx}\""},"workspaces":[".","examples/with-express","examples/with-fastify","examples/with-interop","examples/with-nextjs","examples/with-nextjs-app","examples/with-nuxtjs","examples/with-serverless"],"peerDependencies":{"@trpc/server":"11.0.0-next-beta.281","zod":"^3.14.4"},"dependencies":{"co-body":"^6.1.0","h3":"^1.11.1","lodash.clonedeep":"^4.5.0","node-mocks-http":"^1.14.1","openapi-types":"^12.1.3","zod-to-json-schema":"^3.22.5"},"devDependencies":{"@trpc/client":"11.0.0-next-beta.281","@trpc/server":"11.0.0-next-beta.281","@types/aws-lambda":"^8.10.136","@types/co-body":"^6.1.3","@types/express":"^4.17.21","@types/jest":"^29.5.12","@types/lodash.clonedeep":"^4.5.9","@types/node":"^20.11.30","@types/node-fetch":"^2.6.11","@typescript-eslint/eslint-plugin":"^7.3.1","@typescript-eslint/parser":"^7.3.1","aws-lambda":"^1.0.7","eslint":"^8.57.0","eslint-config-airbnb":"19.0.4","eslint-plugin-import":"^2.29.1","eslint-plugin-jsx-a11y":"^6.8.0","eslint-plugin-promise":"^6.1.1","eslint-plugin-react":"^7.34.1","eslint-plugin-react-hooks":"^4.6.0","express":"^4.19.1","fastify":"^4.26.2","jest":"^29.7.0","next":"^14.1.4","node-fetch":"^2.7.0","openapi-schema-validator":"^12.1.3","rimraf":"^5.0.5","semver":"^7.6.0","superjson":"^1.13.3","ts-jest":"^29.1.2","ts-node":"^10.9.2","typescript":"^5.4.3","zod":"^3.22.4"},"directories":{"example":"examples","test":"test"},"_id":"@alex8628/trpc-swagger@1.2.3","gitHead":"2b79b5059ce61d826af60b84f10d64555e65d1b2","_nodeVersion":"20.11.1","_npmVersion":"10.2.4","dist":{"integrity":"sha512-6cvVeaOCwpEgjWXN4B4jFiQr4tg2DoFHeE1Hj6vO3es8n8nEAWTqhKhoBL7em983V9jIf4AiVoUpCYsAheZ3VA==","shasum":"fe3aabb791d7f1ce750c034fde64a5939780df33","tarball":"https://registry.npmjs.org/@alex8628/trpc-swagger/-/trpc-swagger-1.2.3.tgz","fileCount":87,"unpackedSize":139611,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDzsUCjCCvYzYzXMpRwgr7+1tcMJEfuU3LQMV6/WzaY7QIhANWlc+v8NR7mWZBfzgJPsLtj+MlbqEmnGFaSHQyr5u7G"}]},"_npmUser":{"name":"giftedunicorn","email":"shenjian8628@gmail.com"},"maintainers":[{"name":"giftedunicorn","email":"shenjian8628@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/trpc-swagger_1.2.3_1711619359176_0.6087532711960297"},"_hasShrinkwrap":false},"1.2.4":{"name":"@alex8628/trpc-swagger","private":false,"license":"MIT","version":"1.2.4","description":"tRPC Swagger Wrapper","author":{"name":"https://github.com/giftedunicorn"},"homepage":"https://github.com/giftedunicorn/trpc-swagger","bugs":{"url":"https://github.com/giftedunicorn/trpc-swagger/issues"},"keywords":["trpc","openapi","swagger"],"typings":"build/index.d.ts","main":"build/index.js","repository":{"type":"git","url":"git+https://github.com/giftedunicorn/trpc-swagger.git"},"scripts":{"test":"tsc --noEmit && jest --verbose","build":"rimraf dist && tsc -p tsconfig.build.json","format":"eslint --fix \"./packages/**/*.{js,jsx,ts,tsx}\"","lint:fix":"eslint --fix \"./packages/**/*.{js,jsx,ts,tsx}\"","lint":"eslint \"./packages/**/*.{js,jsx,ts,tsx}\""},"workspaces":[".","examples/with-express","examples/with-fastify","examples/with-interop","examples/with-nextjs","examples/with-nextjs-app","examples/with-nuxtjs","examples/with-serverless"],"peerDependencies":{"@trpc/server":"11.0.0-next-beta.281","zod":"^3.14.4"},"dependencies":{"co-body":"^6.1.0","h3":"^1.11.1","lodash.clonedeep":"^4.5.0","node-mocks-http":"^1.14.1","openapi-types":"^12.1.3","zod-to-json-schema":"^3.22.5"},"devDependencies":{"@trpc/client":"11.0.0-next-beta.281","@trpc/server":"11.0.0-next-beta.281","@types/aws-lambda":"^8.10.136","@types/co-body":"^6.1.3","@types/express":"^4.17.21","@types/jest":"^29.5.12","@types/lodash.clonedeep":"^4.5.9","@types/node":"^20.11.30","@types/node-fetch":"^2.6.11","@typescript-eslint/eslint-plugin":"^7.3.1","@typescript-eslint/parser":"^7.3.1","aws-lambda":"^1.0.7","eslint":"^8.57.0","eslint-config-airbnb":"19.0.4","eslint-plugin-import":"^2.29.1","eslint-plugin-jsx-a11y":"^6.8.0","eslint-plugin-promise":"^6.1.1","eslint-plugin-react":"^7.34.1","eslint-plugin-react-hooks":"^4.6.0","express":"^4.19.1","fastify":"^4.26.2","jest":"^29.7.0","next":"^14.1.4","node-fetch":"^2.7.0","openapi-schema-validator":"^12.1.3","rimraf":"^5.0.5","semver":"^7.6.0","superjson":"^1.13.3","ts-jest":"^29.1.2","ts-node":"^10.9.2","typescript":"^5.4.3","zod":"^3.22.4"},"directories":{"example":"examples","test":"test"},"_id":"@alex8628/trpc-swagger@1.2.4","gitHead":"2b79b5059ce61d826af60b84f10d64555e65d1b2","_nodeVersion":"20.11.1","_npmVersion":"10.2.4","dist":{"integrity":"sha512-Frxh90aa2NtsRV531V5OAdKyt3Jn8/yRrgPnhArF3FAcRXWGsTxUEf4doiOhsbRlb47L63UZeg6JHBP2I0bfsw==","shasum":"2c659e8d9be8d906a28ecea42bfc32da5be244ce","tarball":"https://registry.npmjs.org/@alex8628/trpc-swagger/-/trpc-swagger-1.2.4.tgz","fileCount":87,"unpackedSize":139611,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDipcnBgAH+p8WZJddgAE8v5d6Q72TXJp6ipaRBxKaXlQIhAIjOrXGpoePQ7W+2+P6RvhU7lUYiHzwigGVyGyD2+UHx"}]},"_npmUser":{"name":"giftedunicorn","email":"shenjian8628@gmail.com"},"maintainers":[{"name":"giftedunicorn","email":"shenjian8628@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/trpc-swagger_1.2.4_1711620431885_0.420770641272872"},"_hasShrinkwrap":false},"1.2.5":{"name":"@alex8628/trpc-swagger","private":false,"license":"MIT","version":"1.2.5","description":"tRPC Swagger Wrapper","author":{"name":"https://github.com/giftedunicorn"},"homepage":"https://github.com/giftedunicorn/trpc-swagger","bugs":{"url":"https://github.com/giftedunicorn/trpc-swagger/issues"},"keywords":["trpc","openapi","swagger"],"typings":"build/index.d.ts","main":"build/index.js","repository":{"type":"git","url":"git+https://github.com/giftedunicorn/trpc-swagger.git"},"scripts":{"test":"tsc --noEmit && jest --verbose","build":"rimraf dist && tsc -p tsconfig.build.json","format":"eslint --fix \"./packages/**/*.{js,jsx,ts,tsx}\"","lint:fix":"eslint --fix \"./packages/**/*.{js,jsx,ts,tsx}\"","lint":"eslint \"./packages/**/*.{js,jsx,ts,tsx}\""},"workspaces":[".","examples/with-express","examples/with-fastify","examples/with-interop","examples/with-nextjs","examples/with-nextjs-app","examples/with-nuxtjs","examples/with-serverless"],"peerDependencies":{"@trpc/server":"11.0.0-next-beta.281","zod":"^3.14.4"},"dependencies":{"co-body":"^6.1.0","h3":"^1.11.1","lodash.clonedeep":"^4.5.0","node-mocks-http":"^1.14.1","openapi-types":"^12.1.3","zod-to-json-schema":"^3.22.5"},"devDependencies":{"@trpc/client":"11.0.0-next-beta.281","@trpc/server":"11.0.0-next-beta.281","@types/aws-lambda":"^8.10.136","@types/co-body":"^6.1.3","@types/express":"^4.17.21","@types/jest":"^29.5.12","@types/lodash.clonedeep":"^4.5.9","@types/node":"^20.11.30","@types/node-fetch":"^2.6.11","@typescript-eslint/eslint-plugin":"^7.3.1","@typescript-eslint/parser":"^7.3.1","aws-lambda":"^1.0.7","eslint":"^8.57.0","eslint-config-airbnb":"19.0.4","eslint-plugin-import":"^2.29.1","eslint-plugin-jsx-a11y":"^6.8.0","eslint-plugin-promise":"^6.1.1","eslint-plugin-react":"^7.34.1","eslint-plugin-react-hooks":"^4.6.0","express":"^4.19.1","fastify":"^4.26.2","jest":"^29.7.0","next":"^14.1.4","node-fetch":"^2.7.0","openapi-schema-validator":"^12.1.3","rimraf":"^5.0.5","semver":"^7.6.0","superjson":"^1.13.3","ts-jest":"^29.1.2","ts-node":"^10.9.2","typescript":"^5.4.3","zod":"^3.22.4"},"directories":{"example":"examples","test":"test"},"_id":"@alex8628/trpc-swagger@1.2.5","gitHead":"2b79b5059ce61d826af60b84f10d64555e65d1b2","_nodeVersion":"20.11.1","_npmVersion":"10.2.4","dist":{"integrity":"sha512-SH/x15aRV6JpFRYlAkHqjlRFNbY/m/IrdDa0zt7/h+s1YQU4cQmOXThUl3K29zuMbQVhloUMo6Q85HwRHwemgw==","shasum":"3a2eddef33305d5e40430c7ef8e5b9f04e2a5f9b","tarball":"https://registry.npmjs.org/@alex8628/trpc-swagger/-/trpc-swagger-1.2.5.tgz","fileCount":87,"unpackedSize":139541,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCDcsp7ZSPHZrgCTpICFUFh5Ea/dVB6iwhC/MMAX1Cy3wIhAOYgH+6g8ifclfcYyY0hW9S3DOejigZqiSPmfhR0WJ5d"}]},"_npmUser":{"name":"giftedunicorn","email":"shenjian8628@gmail.com"},"maintainers":[{"name":"giftedunicorn","email":"shenjian8628@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/trpc-swagger_1.2.5_1711620685888_0.2742997421378979"},"_hasShrinkwrap":false}},"time":{"created":"2024-03-28T09:03:15.260Z","1.2.1":"2024-03-28T09:03:15.577Z","modified":"2024-03-28T10:11:26.226Z","1.2.2":"2024-03-28T09:12:31.898Z","1.2.3":"2024-03-28T09:49:19.326Z","1.2.4":"2024-03-28T10:07:12.026Z","1.2.5":"2024-03-28T10:11:26.061Z"},"maintainers":[{"name":"giftedunicorn","email":"shenjian8628@gmail.com"}],"description":"tRPC Swagger Wrapper","homepage":"https://github.com/giftedunicorn/trpc-swagger","keywords":["trpc","openapi","swagger"],"repository":{"type":"git","url":"git+https://github.com/giftedunicorn/trpc-swagger.git"},"author":{"name":"https://github.com/giftedunicorn"},"bugs":{"url":"https://github.com/giftedunicorn/trpc-swagger/issues"},"license":"MIT","readme":"![trpc-swagger](assets/trpc-swagger-readme.png)\n\n<div align=\"center\">\n  <h1>trpc-swagger</h1>\n  <a href=\"https://www.npmjs.com/package/trpc-swagger\"><img src=\"https://img.shields.io/npm/v/trpc-swagger.svg?style=flat&color=brightgreen\" target=\"_blank\" /></a>\n  <a href=\"./LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-black\" /></a>\n  <a href=\"https://trpc.io/discord\" target=\"_blank\"><img src=\"https://img.shields.io/badge/chat-discord-blue.svg\" /></a>\n  <br />\n  <hr />\n</div>\n\n\n## **[Swagger](https://swagger.io/specification/) intigration for [tRPC](https://trpc.io/)** \n\n- Easy REST endpoints for your tRPC procedures.\n- Perfect for incremental adoption.\n- OpenAPI version 3.0.3.\n\n## Fork Notice\nThe original repo [trpc-openapi](https://github.com/James/trpc-openapi) no longer appears to be maintained. \nThe goal of this fork is to add more control for error responses, support more frameworks, and support the new procedure types in @trpc v11.x.x.\nPRs Are welcome\n\n## Local Examples\nIf you've pulled the repo. you can run any of the example projects by first running these 2 commands:\n```\nyarn install\n```\n```\nyarn build\n```\nThen select a workspace\n```bash\nyarn workspace with-[WORKSPACE_NAME] run dev\n```\nErgo\n```yaml\nyarn workspace with-nextjs-app run dev\n```\n\n## Usage\n\n**1. Install `trpc-swagger`**\n\n```bash\nnpm install trpc-swagger --save\n```\n```bash\nyarn add trpc-swagger\n```\n```bash\npnpm add trpc-swagger\n```\n```bash\nbun add trpc-swagger\n```\n\n**2. Add `OpenApiMeta` to your tRPC instance**\n\n```typescript\n// @/server/trpc.ts\nimport { initTRPC } from '@trpc/server'\nimport { OpenApiMeta } from 'trpc-swagger'\n\n// VERC: This\nconst t = initTRPC.create()\n\n// VERC: Becomes\nconst t = initTRPC.meta<OpenApiMeta>().create()\n\n// VERC: Advanced create configs\nconst t = initTRPC.meta<OpenApiMeta>().create({ ... })\n```\n\n**3. Enable `openapi` support for a procedure.**\n\n\n```typescript\n// @/server/index.ts\nexport const appRouter = t.router({\n  sayHello: t.procedure\n    .meta({ \n      openapi: { method: 'GET', path: '/say-hello' } \n    })\n    .input(z.object({ \n      name: z.string() \n    }))\n    .output(z.object({ \n      greeting: z.string() \n    }))\n    .query(({ input }) => {\n      return { greeting: `Hello ${input.name}!` }\n    })\n})\n```\n\n**4. Generate an OpenAPI document.**\n\n```typescript\n// @/server/swagger.ts\nimport { generateOpenApiDocument } from 'trpc-swagger'\nimport { appRouter } from './appRouter'\n\n/* 👇 */\nexport const openApiDocument = generateOpenApiDocument(appRouter, {\n  title: 'tRPC Swagger',\n  version: '1.0.0', // consider making this pull version from package.json\n  baseUrl: 'http://localhost:3000', // consider making this dynamic\n  docsUrl: \"https://github.com/vercjames/trpc-swagger\",\n  tags: [\"tag1\", \"tag2\", \"tag3\", \"posts\"],\n})\n```\n\n**5. Add an `trpc-swagger` handler to your app.**\n\nWe currently support adapters for [`Express`](http://expressjs.com/), [`Next.js`](https://nextjs.org/),  [`Next.js 14`](https://nextjs.org/), [`Serverless`](https://www.serverless.com/), [`Fastify`](https://www.fastify.io/), [`Nuxt`](https://nuxtjs.org/) & [`Node:HTTP`](https://nodejs.org/api/http.html).\n\n```typescript\nimport http from 'http'\nimport { createOpenApiHttpHandler } from 'trpc-swagger'\n\nimport { appRouter } from '../appRouter'\n\nconst server = http.createServer(createOpenApiHttpHandler({ router: appRouter })) /* 👈 */\n\nserver.listen(3000)\n```\n\n**6. Profit 🤑**\n\n```typescript\n// client.ts\nconst res = await fetch('http://localhost:3000/say-hello?name=Verc', { method: 'GET' })\nconst body = await res.json() /* { greeting: 'Hello Verc!' } */\n```\n\n## Requirements\n\n**Peer dependencies**\n\nYour application requires these 2 packages installed\n- [`tRPC`](https://github.com/trpc/trpc) Server v11 (`@trpc/server`) must be installed.\n- [`Zod`](https://github.com/colinhacks/zod) v3 (`zod@^3.14.4`) must be installed (recommended `^3.20.0`).\n\n\n**Procedure support**\n\nFor a procedure to support OpenAPI the following _must_ be true:\n\n- Both `input` and `output` parsers are present AND use `Zod` validation.\n- Query `input` parsers extend `Object<{ [string]: String | Number | BigInt | Date }>` or `Void`.\n- Mutation `input` parsers extend `Object<{ [string]: AnyType }>` or `Void`.\n- `meta.openapi.method` is `GET`, `POST`, `PATCH`, `PUT` or `DELETE`.\n- `meta.openapi.path` is a string starting with `/`.\n- `meta.openapi.path` parameters exist in `input` parser as `String | Number | BigInt | Date`\n\nPlease note:\n\n- Data [`transformers`](https://trpc.io/docs/data-transformers) (such as `superjson`) are ignored.\n- Trailing slashes are ignored.\n- Routing is case-insensitive.\n\n## HTTP Requests\n\nProcedures with a `GET`/`DELETE` method will accept inputs via URL `query parameters`. Procedures with a `POST`/`PATCH`/`PUT` method will accept inputs via the `request body` with a `application/json` or `application/x-www-form-urlencoded` content type.\n\n### Path parameters\n\nA procedure can accept a set of inputs via URL path parameters. You can add a path parameter to any OpenAPI procedure by using curly brackets around an input name as a path segment in the `meta.openapi.path` field.\n\n### Query parameters\n\nQuery & path parameter inputs are always accepted as a `string`. This library will attempt to [coerce](https://github.com/colinhacks/zod#coercion-for-primitives) your input values to the following primitive types out of the box: `number`, `boolean`, `bigint` and `date`. If you wish to support others such as `object`, `array` etc. please use [`z.preprocess()`](https://github.com/colinhacks/zod#preprocess).\n\n```typescript\n// Router\nexport const appRouter = t.router({\n  sayHello: t.procedure\n    .meta({ openapi: { method: 'GET', path: '/say-hello/{name}' /* 👈 */ } })\n    .input(z.object({ name: z.string() /* 👈 */, greeting: z.string() }))\n    .output(z.object({ greeting: z.string() }))\n    .query(({ input }) => {\n      return { greeting: `${input.greeting} ${input.name}!` }\n    })\n})\n\n// Client\nconst res = await fetch('http://localhost:3000/say-hello/Verc?greeting=Hello' /* 👈 */, {\n  method: 'GET',\n})\nconst body = await res.json() /* { greeting: 'Hello Verc!' } */\n```\n\n### Request body\n\n```typescript\n// Router\nexport const appRouter = t.router({\n  sayHello: t.procedure\n    .meta({ openapi: { method: 'POST', path: '/say-hello/{name}' /* 👈 */ } })\n    .input(z.object({ name: z.string() /* 👈 */, greeting: z.string() }))\n    .output(z.object({ greeting: z.string() }))\n    .mutation(({ input }) => {\n      return { greeting: `${input.greeting} ${input.name}!` }\n    })\n})\n\n// Client\nconst res = await fetch('http://localhost:3000/say-hello/Verc' /* 👈 */, {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: JSON.stringify({ greeting: 'Hello' }),\n})\nconst body = await res.json() /* { greeting: 'Hello Verc!' } */\n```\n\n### Custom headers\n\nAny custom headers can be specified in the `meta.openapi.headers` array, these headers will not be validated on request. Please consider using [Authorization](#authorization) for first-class OpenAPI auth/security support.\n\n## HTTP Responses\n\nStatus codes will be `200` by default for any successful requests. In the case of an error, the status code will be derived from the thrown `TRPCError` or fallback to `500`.\n\nYou can modify the status code or headers for any response using the `responseMeta` function. Extra responses can be documented in the `meta.openapi.extraResponses` field.\n\n```typescript\n// Router\nexport const appRouter = t.router({\n  sayHello: t.procedure\n    .meta({ openapi: {\n      method: 'POST',\n      path: '/say-hello/{name}',\n      extraResponses: {\n          400: {\n            description: 'Bad request',\n            content: z.object({ reason: z.string().describe(\"The reason\") }),\n          },\n      }\n    }})\n    .input(z.object({ name: z.string(), greeting: z.string() }))\n    .output(z.object({ greeting: z.string() }))\n    .mutation(({ input }) => {\n      return { greeting: `${input.greeting} ${input.name}!` }\n    })\n})\n\n```\n\nPlease see [error status codes here](packages/adapters/node-http/errors.ts).\n\n## Authorization\n\nTo create protected endpoints, add `protect: true` to the `meta.openapi` object of each tRPC procedure. By default, you can then authenticate each request with the `createContext` function using the `Authorization` header with the `Bearer` scheme. If you wish to authenticate requests using a different/additional methods (such as custom headers, or cookies) this can be overwritten by specifying `securitySchemes` object.\n\nExplore a [complete example here](examples/with-nextjs/src/server/router.ts).\n\n#### Server\n\n```typescript\nimport { TRPCError, initTRPC } from '@trpc/server'\nimport { OpenApiMeta } from 'trpc-swagger'\n\ntype User = { id: string, name: string }\n\nconst users: User[] = [\n  {\n    id: 'usr_123',\n    name: 'Verc',\n  },\n]\n\nexport type Context = { user: User | null }\n\nexport const createContext = async ({ req, res }): Promise<Context> => {\n  let user: User | null = null\n  if (req.headers.authorization) {\n    const userId = req.headers.authorization.split(' ')[1]\n    user = users.find((_user) => _user.id === userId)\n  }\n  return { user }\n}\n\nconst t = initTRPC.context<Context>().meta<OpenApiMeta>().create()\n\nexport const appRouter = t.router({\n  sayHello: t.procedure\n    .meta({ openapi: { method: 'GET', path: '/say-hello', protect: true /* 👈 */ } })\n    .input(z.void()) // no input expected\n    .output(z.object({ greeting: z.string() }))\n    .query(({ input, ctx }) => {\n      if (!ctx.user) {\n        throw new TRPCError({ message: 'User not found', code: 'UNAUTHORIZED' })\n      }\n      return { greeting: `Hello ${ctx.user.name}!` }\n    }),\n})\n```\n\n#### Client\n\n```typescript\nconst res = await fetch('http://localhost:3000/say-hello', {\n  method: 'GET',\n  headers: { Authorization: 'Bearer usr_123' } /* 👈 */,\n})\nconst body = await res.json() /* { greeting: 'Hello Verc!' } */\n```\n\n## Examples\n\n_For advanced use-cases, please find examples in our [complete test suite](test)._\n\n#### With Express\n\nPlease see [full example here](examples/with-express).\n\n```typescript\nimport { createExpressMiddleware } from '@trpc/server/adapters/express'\nimport express from 'express'\nimport { createOpenApiExpressMiddleware } from 'trpc-swagger'\n\nimport { appRouter } from '../appRouter'\n\nconst app = express()\n\napp.use('/api/trpc', createExpressMiddleware({ router: appRouter }))\napp.use('/api', createOpenApiExpressMiddleware({ router: appRouter })) /* 👈 */\n\napp.listen(3000)\n```\n\n#### With Next.js\n\nPlease see [full example here](examples/with-nextjs).\n\n```typescript\n// pages/api/[...trpc].ts\nimport { createOpenApiNextHandler } from 'trpc-swagger'\n\nimport { appRouter } from '../../server/appRouter'\n\nexport default createOpenApiNextHandler({ router: appRouter })\n```\n\n#### With AWS Lambda\n\nPlease see [full example here](examples/with-serverless).\n\n```typescript\nimport { createOpenApiAwsLambdaHandler } from 'trpc-swagger'\n\nimport { appRouter } from './appRouter'\n\nexport const openApi = createOpenApiAwsLambdaHandler({ router: appRouter })\n```\n\n#### With Fastify\n\nPlease see [full example here](examples/with-fastify).\n\n```typescript\nimport { fastifyTRPCPlugin } from '@trpc/server/adapters/fastify'\nimport Fastify from 'fastify'\nimport { fastifyTRPCOpenApiPlugin } from 'trpc-swagger'\n\nimport { appRouter } from './router'\n\nconst fastify = Fastify()\n\nasync function main() {\n  await fastify.register(fastifyTRPCPlugin, { router: appRouter })\n  await fastify.register(fastifyTRPCOpenApiPlugin, { router: appRouter }) /* 👈 */\n\n  await fastify.listen({ port: 3000 })\n}\n\nmain()\n```\n\n## Types\n\n#### GenerateOpenApiDocumentOptions\n\nPlease see [full typings here](packages/generator/index.ts).\n\n| Property          | Type                                   | Description                                             | Required |\n| ----------------- | -------------------------------------- | ------------------------------------------------------- | -------- |\n| `title`           | `string`                               | The title of the API.                                   | `true`   |\n| `description`     | `string`                               | A short description of the API.                         | `false`  |\n| `version`         | `string`                               | The version of the OpenAPI document.                    | `true`   |\n| `baseUrl`         | `string`                               | The base URL of the target server.                      | `true`   |\n| `docsUrl`         | `string`                               | A URL to any external documentation.                    | `false`  |\n| `tags`            | `string[]`                             | A list for ordering endpoint groups.                    | `false`  |\n| `securitySchemes` | `Record<string, SecuritySchemeObject>` | Defaults to `Authorization` header with `Bearer` scheme | `false`  |\n\n#### OpenApiMeta\n\nPlease see [full typings here](packages/types.ts).\n\n| Property         | Type                               | Description                                                                                                        | Required | Default                |\n| ---------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------ | -------- | ---------------------- |\n| `enabled`        | `boolean`                          | Exposes this procedure to `trpc-swagger` adapters and on the OpenAPI document.                                     | `false`  | `true`                 |\n| `method`         | `HttpMethod`                       | HTTP method this endpoint is exposed on. Value can be `GET`, `POST`, `PATCH`, `PUT` or `DELETE`.                   | `true`   | `undefined`            |\n| `path`           | `string`                           | Pathname this endpoint is exposed on. Value must start with `/`, specify path parameters using `{}`.               | `true`   | `undefined`            |\n| `protect`        | `boolean`                          | Requires this endpoint to use a security scheme.                                                                   | `false`  | `false`                |\n| `summary`        | `string`                           | A short summary of the endpoint included in the OpenAPI document.                                                  | `false`  | `undefined`            |\n| `description`    | `string`                           | A verbose description of the endpoint included in the OpenAPI document.                                            | `false`  | `undefined`            |\n| `tags`           | `string[]`                         | A list of tags used for logical grouping of endpoints in the OpenAPI document.                                     | `false`  | `undefined`            |\n| `headers`        | `ParameterObject[]`                | An array of custom headers to add for this endpoint in the OpenAPI document.                                       | `false`  | `undefined`            |\n| `contentTypes`   | `ContentType[]`                    | A set of content types specified as accepted in the OpenAPI document.                                              | `false`  | `['application/json']` |\n| `extraResponses` | `ResponsesObject`* | An array of custom responses to add for this endpoint in the OpenAPI document in addition to the default response. | `false`  | `undefined`            |\n| `deprecated`     | `boolean`                          | Whether or not to mark an endpoint as deprecated                                                                   | `false`  | `false`                |\n\n* _The `content` field in ResponsesObject is expected to be a `z.ZodType`_\n\n#### CreateOpenApiNodeHttpHandlerOptions\n\nPlease see [full typings here](packages/adapters/node-http/core.ts).\n\n| Property        | Type       | Description                                            | Required |\n| --------------- | ---------- | ------------------------------------------------------ | -------- |\n| `router`        | `Router`   | Your application tRPC router.                          | `true`   |\n| `createContext` | `Function` | Passes contextual (`ctx`) data to procedure resolvers. | `false`  |\n| `responseMeta`  | `Function` | Returns any modifications to statusCode & headers.     | `false`  |\n| `onError`       | `Function` | Called if error occurs inside handler.                 | `false`  |\n| `maxBodySize`   | `number`   | Maximum request body size in bytes (default: 100kb).   | `false`  |\n\n---\n\n_Still using tRPC v9? See our [`.interop()`](examples/with-interop) example._\n\n## License\n\nDistributed under the MIT License. See LICENSE for more information.\n","readmeFilename":"README.md"}