npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

yak-payload-swagger

v1.4.2

Published

Swagger plugin for payload cms

Downloads

7

Readme

created by snyk downloads npm version license

payload-swagger

Swagger plugin for payload cms:

  • generate openAPI 3 documentation from your payload config
  • adds routes for:
    • openAPI document
    • Swagger UI
    • LICENSE file, if available

payload-swagger uses payload-openapi, which documents ALL your payload openapi endpoints and includes:

  • collection endpoints
  • global endpoints
  • custom endpoints
  • authentication endpoints
  • preferences endpoints
  • fully typed schema definitions for all requests, parameters and responses
  • authentication requirements for all your endpoints
  • extension points to merge your custom openapi definitions into the schema

Alternatives:

Installation

With yarn:

yarn add payload-swagger

With npm:

npm install payload-swagger

Usage

import { buildConfig } from 'payload/config';
import path from 'path';
import { swagger } from 'payload-swagger';

export default buildConfig({
  plugins: [
    swagger({
      /* see options section */
    }),
  ],
  // The rest of your config goes here
});

Extend the openAPI document

The openAPI document generated by payload-swagger includes information from the following external sources:

  • package.json: payload-swagger uses the information in the fields shown below. In openapi a partial openapi document can be included;
{
  "name": "my payload cms",
  "version": "1.2.3",
  "description": "My awesome cms",
  "license": "MIT",
  "openapi": {}
}
  • .openapi: optional file with partial openapi document in JSON format.

The data from all these source is recursively merged into the final document.

Options

payload-swagger has the following options:

interface Options {
  /**
   * By default the access functions on all collections in the config are called to determine
   * the access level of the operations.
   * Provide an array of collection slugs to disable this for the given collections,
   * or `true` to disable for all.
   */
  disableAccessAnalysis?: boolean | string[];

  /**
   * Exclude parts of the payload config from the openapi document
   */
  exclude?: {
    authPaths?: boolean;
    authCollection?: boolean;
    passwordRecovery: boolean; // default true, set to `false` to include
    preferences?: boolean; // default true, set to `false` to include
    custom?: boolean;
  };

  /**
   * Customize the payload-swagger routes
   */
  routes?: {
    /**
     * Swagger ui route
     * @default /api-docs
     */
    swagger?: string;
    /**
     * Openapi specs route
     * @default /api-docs/specs
     */
    specs?: string;
    /**
     * License route (requires LICENSE file in root of repository or explicit license url in openapi document)
     * @default /api-docs/license
     */
    license?: string;
  };

  /**
   * Swagger ui options (see swagger-ui documentation)
   */
  ui?: Omit<SwaggerUiOptions, 'swaggerUrl' | 'swaggerUrls'>;

  /**
   * Throw on error
   * @default false
   * @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.
   */
  throwOnError?: boolean;
}

Descriptions

Endpoint 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:

  • docs
  • en
  • first value found that is a string

This makes it possible to set a custom description for the docs:

import { CollectionConfig } from 'payload/types';

const Media: CollectionConfig = {
  slug: 'media',
  admin: {
    description: {
      docs: 'Description used in openapi docs',
      en: 'Description used in the admin panel',
    },
  },
  labels: {
    singular: 'Single value used everywhere',
    plural: {
      docs: 'Plural value used in docs',
      en: 'Plural value used in admin panel',
    },
  },
  // ... Rest of collection config
};

Documentation of custom endpoints

Custom endpoints on all levels can be fully documented, either by using the defineEndpoint helper:

import { CollectionConfig } from 'payload/types';
import { defineEndpoint } from 'payload-swagger';

const Post: CollectionConfig = {
  slug: 'posts',
  endpoints: [
    defineEndpoint({
      summary: 'media by category',
      description: 'gets the media of the given category',
      path: '/category/:category',
      method: 'get',
      responseSchema: 'posts',
      errorResponseSchemas: {
        404: 'error',
      },
      queryParameters: {
        limit: { schema: { type: 'number' } },
        page: { schema: { type: 'number' } },
        sort: { scema: { type: 'string' } },
      },
      handler: (req, res) => {
        // ... handler implementation
      },
    }),
  ],
  // ... Rest of collection config
};

or by setting the custom.openapi property:

import { CollectionConfig } from 'payload/types';
import type { EndpointDocumentation } from 'payload-swagger';

const documentation: EndpointDocumentation = {
  summary: 'media by category',
  description: 'gets the media of the given category',
  responseSchema: 'posts',
  errorResponseSchemas: {
    404: { type: 'object', properties: { message: { type: 'string' } }, required: ['message'] },
  },
  queryParameters: {
    limit: { schema: { type: 'number' } },
    page: { schema: { type: 'number' } },
    sort: { scema: { type: 'string' } },
  },
};

const Post: CollectionConfig = {
  slug: 'posts',
  endpoints: [
    {
      path: '/category/:category',
      method: 'get',
      handler: (req, res) => {
        // ... handler implementation
      },
      custom: {
        openapi: documentation,
      },
    },
  ],
  // ... Rest of collection config
};

Response 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.

To exclude a custom endpoint from the documentation, set the custom.openapi property to false.

Adding examples

Examples can be added on collections and globals using the defineCollection or defineGlobal helper:

import { defineCollection } from 'payload-openapi';

const Categories = defineCollection({
  slug: 'categories',
  example: {
    name: 'Example Category',
    archived: false,
  },
  // ... Rest of collection config
});

Or by setting the custom.openapi property:

import { CollectionConfig } from 'payload/types';

const Categories: CollectionConfig = {
  slug: 'categories',
  custom: {
    openapi: {
      example: {
        name: 'Example Category',
        archived: false,
      },
    },
  },
  // ... Rest of collection config
};

It's also possible to set multiple examples:

import { defineCollection } from 'payload-openapi';

const Categories = defineCollection({
  slug: 'categories',
  examples: {
    active: {
      value: {
        name: 'Active Category',
        archived: false,
      },
      summary: 'Example of an active category',
    },
    archive: {
      value: {
        name: 'Archived Category',
        archived: true,
      },
      summary: 'Example of an archived category',
    },
  },
  // ... Rest of collection config
});

Openapi 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.

Excluding unused endpoints

In 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.

To also remove the endpoint from the openapi documentation, you can use payload-rbac:

import { CollectionConfig } from 'payload/types';
import { blockAll } from 'payload-rbac';

const Media: CollectionConfig: {
  slug: 'media',
  access: {
    delete: blockAll(), // Use block all to exclude endpoint from docs
  },
  // ... Rest of collection config
}

Version history

See changelog