{"_id":"@bitkraken/payload-swagger","_rev":"2-7cdd71d07a0ccd84fa94bbbdb9455914","name":"@bitkraken/payload-swagger","dist-tags":{"latest":"1.4.2"},"versions":{"1.4.0":{"name":"@bitkraken/payload-swagger","version":"1.4.0","keywords":["swagger","payload","payloadcms","payload-plugin","openAPI"],"author":{"name":"Teun Mooij"},"license":"MIT","_id":"@bitkraken/payload-swagger@1.4.0","maintainers":[{"name":"givemeurcookies","email":"skaug@bitkraken.no"}],"homepage":"https://github.com/teunmooij/payload-tools/#readme","bugs":{"url":"https://github.com/teunmooij/payload-tools/issues"},"dist":{"shasum":"9f15fcfd4e4ef3936784867f55667af77c6260fb","tarball":"https://registry.npmjs.org/@bitkraken/payload-swagger/-/payload-swagger-1.4.0.tgz","fileCount":18,"integrity":"sha512-O+FWfgSvuAE8v1W50IuDpQFfWQpQ377NZOcNydCd73qI+9z9MlHGTmhTB5galqhHhtMOArGxyB8UehcQ2T0lGA==","signatures":[{"sig":"MEQCICydcnGfIKdSuOesbxfH7lqNuZ2SS2dIuhSJGsZ7sAoiAiAK+jndmLNMYAmsDw1qDVjOuFQ+DBiscIhkCB29/CUqtA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":21996},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"34e44a73ce4bd2336f73107d0fed90d6bd11f6fa","scripts":{"lint":"eslint src/","test":"jest -c jest.config.ts","build":"rimraf dist && tsc --sourceMap false","lint:fix":"eslint src/ --quiet --fix","typecheck":"tsc --noEmit","test:coverage":"jest -c jest.config.ts --verbose --collectCoverage"},"_npmUser":{"name":"givemeurcookies","email":"skaug@bitkraken.no"},"repository":{"url":"git+https://github.com/teunmooij/payload-tools.git","type":"git"},"_npmVersion":"10.7.0","description":"Swagger plugin for payload cms","directories":{},"_nodeVersion":"18.20.4","dependencies":{"payload-openapi":"^1.4.0","swagger-ui-express":"^5.0.1"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","husky":"^8.0.3","eslint":"^8.35.0","rimraf":"^4.4.0","payload":"^1.9.0","ts-jest":"^29.1.0","ts-node":"^10.9.1","prettier":"^2.8.4","typescript":"^5.5.4","@types/jest":"^29.4.0","lint-staged":"^13.1.2","@types/express":"^4.17.17","eslint-plugin-jest":"^27.2.1","eslint-plugin-import":"^2.27.5","eslint-plugin-promise":"^6.1.1","eslint-config-prettier":"^8.7.0","eslint-plugin-prettier":"^4.2.1","@types/lodash.mergewith":"^4.6.7","@types/swagger-ui-express":"^4.1.6","@typescript-eslint/parser":"^5.54.1","@typescript-eslint/eslint-plugin":"^5.54.1","eslint-plugin-sort-class-members":"^1.16.0"},"peerDependencies":{"payload":"^1.6.22"},"_npmOperationalInternal":{"tmp":"tmp/payload-swagger_1.4.0_1723389303172_0.06902031141518084","host":"s3://npm-registry-packages"}},"1.4.1":{"name":"@bitkraken/payload-swagger","version":"1.4.1","keywords":["swagger","payload","payloadcms","payload-plugin","openAPI"],"author":{"name":"Teun Mooij"},"license":"MIT","_id":"@bitkraken/payload-swagger@1.4.1","maintainers":[{"name":"givemeurcookies","email":"skaug@bitkraken.no"}],"homepage":"https://github.com/teunmooij/payload-tools/#readme","bugs":{"url":"https://github.com/teunmooij/payload-tools/issues"},"dist":{"shasum":"1139276b8f80a9bfd13bb2cf36f6ca3679ddedbe","tarball":"https://registry.npmjs.org/@bitkraken/payload-swagger/-/payload-swagger-1.4.1.tgz","fileCount":18,"integrity":"sha512-RW8X6gyDgG3F0CFcaV8gEbOr5LyyzGL4ZOFOYl+UAMiiCKdWArD1p3JusCemM4ml2rTe5GYqNAYH9i/smiAglw==","signatures":[{"sig":"MEUCICeDhBA6yaXEdUNUs77BB3iweh5fkkblaU0DW8EFUqtPAiEA2dv7ScY7GtdUVO4UX0MpW56wV9D5GX+ez1t7azW8bxU=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":22017},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"fdbe0ad2e299efccfb6cad1001b866ebd2750578","scripts":{"lint":"eslint src/","test":"jest -c jest.config.ts","build":"rimraf dist && tsc --sourceMap false","lint:fix":"eslint src/ --quiet --fix","typecheck":"tsc --noEmit","test:coverage":"jest -c jest.config.ts --verbose --collectCoverage"},"_npmUser":{"name":"givemeurcookies","email":"skaug@bitkraken.no"},"repository":{"url":"git+https://github.com/teunmooij/payload-tools.git","type":"git"},"_npmVersion":"10.7.0","description":"Swagger plugin for payload cms","directories":{},"_nodeVersion":"18.20.4","dependencies":{"swagger-ui-express":"^5.0.1","@bitkraken/payload-openapi":"^1.4.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","husky":"^8.0.3","eslint":"^8.35.0","rimraf":"^4.4.0","payload":"^1.9.0","ts-jest":"^29.1.0","ts-node":"^10.9.1","prettier":"^2.8.4","typescript":"^5.5.4","@types/jest":"^29.4.0","lint-staged":"^13.1.2","@types/express":"^4.17.17","eslint-plugin-jest":"^27.2.1","eslint-plugin-import":"^2.27.5","eslint-plugin-promise":"^6.1.1","eslint-config-prettier":"^8.7.0","eslint-plugin-prettier":"^4.2.1","@types/lodash.mergewith":"^4.6.7","@types/swagger-ui-express":"^4.1.6","@typescript-eslint/parser":"^5.54.1","@typescript-eslint/eslint-plugin":"^5.54.1","eslint-plugin-sort-class-members":"^1.16.0"},"peerDependencies":{"payload":"^1.6.22"},"_npmOperationalInternal":{"tmp":"tmp/payload-swagger_1.4.1_1723390556440_0.3994807315032216","host":"s3://npm-registry-packages"}},"1.4.2":{"name":"@bitkraken/payload-swagger","version":"1.4.2","description":"Swagger plugin for payload cms","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"rimraf dist && tsc --sourceMap false","lint":"eslint src/","lint:fix":"eslint src/ --quiet --fix","test":"jest -c jest.config.ts","test:coverage":"jest -c jest.config.ts --verbose --collectCoverage","typecheck":"tsc --noEmit"},"dependencies":{"@bitkraken/payload-openapi":"^1.4.0","swagger-ui-express":"^5.0.1"},"peerDependencies":{"payload":"^1.6.22"},"devDependencies":{"@types/express":"^4.17.17","@types/jest":"^29.4.0","@types/lodash.mergewith":"^4.6.7","@types/swagger-ui-express":"^4.1.6","@typescript-eslint/eslint-plugin":"^5.54.1","@typescript-eslint/parser":"^5.54.1","eslint":"^8.35.0","eslint-config-prettier":"^8.7.0","eslint-plugin-import":"^2.27.5","eslint-plugin-jest":"^27.2.1","eslint-plugin-prettier":"^4.2.1","eslint-plugin-promise":"^6.1.1","eslint-plugin-sort-class-members":"^1.16.0","husky":"^8.0.3","jest":"^29.5.0","lint-staged":"^13.1.2","payload":"^1.9.0","prettier":"^2.8.4","rimraf":"^4.4.0","ts-jest":"^29.1.0","ts-node":"^10.9.1","typescript":"^5.5.4"},"repository":{"type":"git","url":"git+https://github.com/teunmooij/payload-tools.git"},"keywords":["swagger","payload","payloadcms","payload-plugin","openAPI"],"author":{"name":"Teun Mooij"},"license":"MIT","bugs":{"url":"https://github.com/teunmooij/payload-tools/issues"},"homepage":"https://github.com/teunmooij/payload-tools/#readme","_id":"@bitkraken/payload-swagger@1.4.2","gitHead":"71c02e2b9325cdd3646d9f814d381a8766163334","_nodeVersion":"18.20.4","_npmVersion":"10.7.0","dist":{"integrity":"sha512-rdNXxRdO1Wqi6/RgAQJ1X3rbGQcE0wb7uzUMIOR2IXQUVi91nmeP2KzS/mzNPXW4NnkoWfHEFVWVa89Hhkeeaw==","shasum":"44405158afafe89f43c2232dd6be0a7d930a0b5a","tarball":"https://registry.npmjs.org/@bitkraken/payload-swagger/-/payload-swagger-1.4.2.tgz","fileCount":18,"unpackedSize":22059,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDYgpwOY9wJA0KLCDMlbN4fOLG+wxYXATOehkxiEiEpcwIhALb4EF3KomIVnKbUHNd4SA0dY02eeAo23YKdO97eGhUu"}]},"_npmUser":{"name":"givemeurcookies","email":"skaug@bitkraken.no"},"directories":{},"maintainers":[{"name":"givemeurcookies","email":"skaug@bitkraken.no"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/payload-swagger_1.4.2_1723391668043_0.6501435574967649"},"_hasShrinkwrap":false}},"time":{"created":"2024-08-11T15:15:03.062Z","modified":"2024-08-11T15:54:28.366Z","1.4.0":"2024-08-11T15:15:03.386Z","1.4.1":"2024-08-11T15:35:56.584Z","1.4.2":"2024-08-11T15:54:28.190Z"},"bugs":{"url":"https://github.com/teunmooij/payload-tools/issues"},"author":{"name":"Teun Mooij"},"license":"MIT","homepage":"https://github.com/teunmooij/payload-tools/#readme","keywords":["swagger","payload","payloadcms","payload-plugin","openAPI"],"repository":{"type":"git","url":"git+https://github.com/teunmooij/payload-tools.git"},"description":"Swagger plugin for payload cms","maintainers":[{"name":"givemeurcookies","email":"skaug@bitkraken.no"}],"readme":"[![created by](https://img.shields.io/badge/author-Teun%20Mooij-blue)](https://www.linkedin.com/in/teunmooij/)\n[![snyk](https://snyk.io/test/github/teunmooij/payload-tools/badge.svg)](https://snyk.io/test/github/teunmooij/payload-tools)\n[![downloads](https://img.shields.io/npm/dt/payload-swagger?color=blue)](https://www.npmjs.com/package/payload-swagger)\n[![npm version](https://badge.fury.io/js/payload-swagger.svg)](https://www.npmjs.com/package/payload-swagger)\n[![license](https://img.shields.io/npm/l/payload-swagger?color=blue)](https://img.shields.io/npm/l/payload-swagger)\n\n# payload-swagger\n\nSwagger plugin for payload cms:\n\n- generate openAPI 3 documentation from your payload config\n- adds routes for:\n  - openAPI document\n  - Swagger UI\n  - LICENSE file, if available\n\n`payload-swagger` uses `payload-openapi`, which documents ALL your payload openapi endpoints and includes:\n\n- collection endpoints\n- global endpoints\n- custom endpoints\n- authentication endpoints\n- preferences endpoints\n- fully typed schema definitions for all requests, parameters and responses\n- authentication requirements for all your endpoints\n- extension points to merge your custom openapi definitions into the schema\n\nAlternatives:\n\n- [payload-openapi](https://www.npmjs.com/package/payload-openapi) if you just want to openapi document\n- [create-payload-api-docs](https://www.npmjs.com/package/create-payload-api-docs) if you want a cli version (eg to build the openapi doc in your build pipeline)\n\n## Installation\n\nWith yarn:\n\n```shell\nyarn add payload-swagger\n```\n\nWith npm:\n\n```shell\nnpm install payload-swagger\n```\n\n## Usage\n\n```typescript\nimport { buildConfig } from 'payload/config';\nimport path from 'path';\nimport { swagger } from 'payload-swagger';\n\nexport default buildConfig({\n  plugins: [\n    swagger({\n      /* see options section */\n    }),\n  ],\n  // The rest of your config goes here\n});\n```\n\n## Extend the openAPI document\n\nThe openAPI document generated by `payload-swagger` includes information from the following external sources:\n\n- `package.json`: `payload-swagger` uses the information in the fields shown below. In `openapi` a partial openapi document can be included;\n\n```json\n{\n  \"name\": \"my payload cms\",\n  \"version\": \"1.2.3\",\n  \"description\": \"My awesome cms\",\n  \"license\": \"MIT\",\n  \"openapi\": {}\n}\n```\n\n- `.openapi`: optional file with partial openapi document in JSON format.\n\nThe data from all these source is recursively merged into the final document.\n\n## Options\n\n`payload-swagger` has the following options:\n\n```typescript\ninterface Options {\n  /**\n   * By default the access functions on all collections in the config are called to determine\n   * the access level of the operations.\n   * Provide an array of collection slugs to disable this for the given collections,\n   * or `true` to disable for all.\n   */\n  disableAccessAnalysis?: boolean | string[];\n\n  /**\n   * Exclude parts of the payload config from the openapi document\n   */\n  exclude?: {\n    authPaths?: boolean;\n    authCollection?: boolean;\n    passwordRecovery: boolean; // default true, set to `false` to include\n    preferences?: boolean; // default true, set to `false` to include\n    custom?: boolean;\n  };\n\n  /**\n   * Customize the payload-swagger routes\n   */\n  routes?: {\n    /**\n     * Swagger ui route\n     * @default /api-docs\n     */\n    swagger?: string;\n    /**\n     * Openapi specs route\n     * @default /api-docs/specs\n     */\n    specs?: string;\n    /**\n     * License route (requires LICENSE file in root of repository or explicit license url in openapi document)\n     * @default /api-docs/license\n     */\n    license?: string;\n  };\n\n  /**\n   * Swagger ui options (see swagger-ui documentation)\n   */\n  ui?: Omit<SwaggerUiOptions, 'swaggerUrl' | 'swaggerUrls'>;\n\n  /**\n   * Throw on error\n   * @default false\n   * @description If set to true, the plugin will throw the error if any error occurs while generating the openapi document, causing Payload to fail to start.\n   */\n  throwOnError?: boolean;\n}\n```\n\n## Descriptions\n\nEndpoint descriptions and summaries are generated from the `description` and `label`/`labels.{singular/plural}` fields of your globals and collections. If a multilanguage (`Record<string, string>) value is found, the order of priority for picking the language is as follows:\n\n- docs\n- en\n- first value found that is a string\n\nThis makes it possible to set a custom description for the docs:\n\n```ts\nimport { CollectionConfig } from 'payload/types';\n\nconst Media: CollectionConfig = {\n  slug: 'media',\n  admin: {\n    description: {\n      docs: 'Description used in openapi docs',\n      en: 'Description used in the admin panel',\n    },\n  },\n  labels: {\n    singular: 'Single value used everywhere',\n    plural: {\n      docs: 'Plural value used in docs',\n      en: 'Plural value used in admin panel',\n    },\n  },\n  // ... Rest of collection config\n};\n```\n\n## Documentation of custom endpoints\n\nCustom endpoints on all levels can be fully documented, either by using the `defineEndpoint` helper:\n\n```ts\nimport { CollectionConfig } from 'payload/types';\nimport { defineEndpoint } from 'payload-swagger';\n\nconst Post: CollectionConfig = {\n  slug: 'posts',\n  endpoints: [\n    defineEndpoint({\n      summary: 'media by category',\n      description: 'gets the media of the given category',\n      path: '/category/:category',\n      method: 'get',\n      responseSchema: 'posts',\n      errorResponseSchemas: {\n        404: 'error',\n      },\n      queryParameters: {\n        limit: { schema: { type: 'number' } },\n        page: { schema: { type: 'number' } },\n        sort: { scema: { type: 'string' } },\n      },\n      handler: (req, res) => {\n        // ... handler implementation\n      },\n    }),\n  ],\n  // ... Rest of collection config\n};\n```\n\nor by setting the `custom.openapi` property:\n\n```ts\nimport { CollectionConfig } from 'payload/types';\nimport type { EndpointDocumentation } from 'payload-swagger';\n\nconst documentation: EndpointDocumentation = {\n  summary: 'media by category',\n  description: 'gets the media of the given category',\n  responseSchema: 'posts',\n  errorResponseSchemas: {\n    404: { type: 'object', properties: { message: { type: 'string' } }, required: ['message'] },\n  },\n  queryParameters: {\n    limit: { schema: { type: 'number' } },\n    page: { schema: { type: 'number' } },\n    sort: { scema: { type: 'string' } },\n  },\n};\n\nconst Post: CollectionConfig = {\n  slug: 'posts',\n  endpoints: [\n    {\n      path: '/category/:category',\n      method: 'get',\n      handler: (req, res) => {\n        // ... handler implementation\n      },\n      custom: {\n        openapi: documentation,\n      },\n    },\n  ],\n  // ... Rest of collection config\n};\n```\n\nResponse schemas can be defined as openapi schema objects or as string, referencing any of the schemas defined in the schema section of the openapi document.\n\nTo exclude a custom endpoint from the documentation, set the `custom.openapi` property to `false`.\n\n## Adding examples\n\nExamples can be added on collections and globals using the `defineCollection` or `defineGlobal` helper:\n\n```ts\nimport { defineCollection } from 'payload-openapi';\n\nconst Categories = defineCollection({\n  slug: 'categories',\n  example: {\n    name: 'Example Category',\n    archived: false,\n  },\n  // ... Rest of collection config\n});\n```\n\nOr by setting the `custom.openapi` property:\n\n```ts\nimport { CollectionConfig } from 'payload/types';\n\nconst Categories: CollectionConfig = {\n  slug: 'categories',\n  custom: {\n    openapi: {\n      example: {\n        name: 'Example Category',\n        archived: false,\n      },\n    },\n  },\n  // ... Rest of collection config\n};\n```\n\nIt's also possible to set multiple examples:\n\n```ts\nimport { defineCollection } from 'payload-openapi';\n\nconst Categories = defineCollection({\n  slug: 'categories',\n  examples: {\n    active: {\n      value: {\n        name: 'Active Category',\n        archived: false,\n      },\n      summary: 'Example of an active category',\n    },\n    archive: {\n      value: {\n        name: 'Archived Category',\n        archived: true,\n      },\n      summary: 'Example of an archived category',\n    },\n  },\n  // ... Rest of collection config\n});\n```\n\nOpenapi supports examples at lots of different levels. To add examples add other levels, you can define theme in a separate partial openapi document, as described [here](#extend-the-openapi-document).\n\n## Excluding unused endpoints\n\nIn Payload `collections` and `globals` have a standard set of available endpoints. In some situations you might not want to use some of these endpoints. In those situations you probably have used an access method that looks something like this: `() => false;`. This blocks all traffic, but the endpoint is still part of the openapi documentation.\n\nTo also remove the endpoint from the openapi documentation, you can use [payload-rbac](https://www.npmjs.com/package/payload-rbac):\n\n```ts\nimport { CollectionConfig } from 'payload/types';\nimport { blockAll } from 'payload-rbac';\n\nconst Media: CollectionConfig: {\n  slug: 'media',\n  access: {\n    delete: blockAll(), // Use block all to exclude endpoint from docs\n  },\n  // ... Rest of collection config\n}\n```\n\n## Version history\n\nSee [changelog](./CHANGELOG.md)\n","readmeFilename":"README.md"}