Skip to content

dexsper/swagger-custom-badges

Repository files navigation

swagger-custom-badges

NPM version License Downloads

A Swagger UI plugin that displays custom badges for API operations based on OpenAPI extension fields.

Screenshot

Features

  • 🏷️ Custom badges for any OpenAPI extension field
  • 🎨 Configurable styling with custom icons, colors, and backgrounds
  • πŸ”§ Flexible parsing support for strings, arrays, and objects
  • πŸ“Š Multiple badge types per operation
  • 🌐 Framework agnostic - works with any Swagger UI implementation
  • ⚑ Zero dependencies (peer dependency on swagger-ui-dist only)

Installation

npm install swagger-custom-badges
yarn add swagger-custom-badges
pnpm add swagger-custom-badges

Quick Start

Basic Usage

import { CustomBadgePlugin } from 'swagger-custom-badges';

// Configure Swagger UI with the plugin
SwaggerUIBundle({
  url: './openapi.json',
  dom_id: '#swagger-ui',
  plugins: [
    CustomBadgePlugin({
      fields: [
        {
          fieldName: 'x-roles',
          badge: {
            icon: 'πŸ‘€',
            background: '#007bff',
            color: 'white'
          }
        }
      ]
    })
  ]
});

OpenAPI Specification

Add extension fields to your OpenAPI operations:

paths:
  /users:
    get:
      summary: Get users
      x-roles: "admin"
      responses:
        '200':
          description: Success

Configuration

Plugin Configuration

interface PluginConfig {
  fields: FieldConfig[];           // Array of field configurations
  defaultIcon?: string;            // Default icon for all badges
  defaultColor?: string;           // Default text color
  defaultBackground?: string;      // Default background color
}

Field Configuration

Single Badge Field

interface SingleBadgeField {
  fieldName: string;               // OpenAPI extension field name (e.g., 'x-roles')
  badge: BadgeConfig;              // Badge styling configuration
  parser?: BadgeParser;            // Optional custom parser function
}

interface BadgeConfig {
  icon?: string;                   // Emoji or text icon
  color?: string;                  // Text color (CSS color value)
  background?: string;             // Background color (CSS color value)
}

Multi Badge Field

interface MultiBadgeField {
  fieldName: string;               // OpenAPI extension field name
  badges: { [key: string]: BadgeConfig }; // Mapping of badge keys to configurations
  parser?: BadgeParser;            // Optional custom parser function
}

Custom Parsers

Create custom parsing logic for complex field values:

interface BadgeParser {
  (value: any): Array<{ key: string; value: any }>;
}

// Example: Custom parser for deprecated fields
const deprecatedParser = (value: { reason: string; since: string; until: string }) => [
  {
    key: 'deprecated',
    value: `${value.reason} (${value.since} - ${value.until})`
  }
];

Framework Integration

NestJS

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { CustomBadgePlugin } from 'swagger-custom-badges';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const config = new DocumentBuilder()
    .setTitle('API Documentation')
    .setDescription('API with custom badges')
    .setVersion('1.0')
    .build();

  const documentFactory = () => SwaggerModule.createDocument(app, config);
  
  SwaggerModule.setup('docs', app, documentFactory, {
    swaggerOptions: {
      plugins: [
        CustomBadgePlugin({
          fields: [
            {
              fieldName: 'x-roles',
              badges: {
                admin: { icon: 'πŸ‘‘', background: '#dc3545' },
                user: { icon: 'πŸ‘€', background: '#28a745' },
                guest: { icon: '🌐', background: '#6c757d' }
              }
            },
            {
              fieldName: 'x-deprecated',
              badge: {
                icon: '⚠️',
                background: '#ffc107',
                color: '#000'
              }
            }
          ],
          defaultIcon: '🏷️',
          defaultColor: 'white',
          defaultBackground: '#6f42c1'
        })
      ]
    }
  });

  await app.listen(3000);
}
bootstrap();

Controller Example

import { Controller, Get } from '@nestjs/common';
import { ApiExtension, ApiOperation } from '@nestjs/swagger';

@Controller('users')
export class UsersController {
  @Get()
  @ApiOperation({ summary: 'Get all users' })
  @ApiExtension('x-roles', ['admin', 'user'])
  getUsers() {
    return [];
  }

  @Get('profile')
  @ApiOperation({ summary: 'Get user profile' })
  @ApiExtension('x-roles', { admin: true, user: true })
  getProfile() {
    return {};
  }

  @Get('legacy')
  @ApiOperation({ summary: 'Legacy endpoint' })
  @ApiExtension('x-deprecated', {
    reason: 'Use /users instead',
    since: '1.0.0',
    until: '2.0.0'
  })
  getLegacy() {
    return {};
  }
}

Express + swagger-ui-express

const express = require('express');
const swaggerUi = require('swagger-ui-express');
const { CustomBadgePlugin } = require('swagger-custom-badges');
const swaggerDocument = require('./openapi.json');

const app = express();

app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument, {
  swaggerOptions: {
    plugins: [
      CustomBadgePlugin({
        fields: [
          {
            fieldName: 'x-security-level',
            badges: {
              high: { icon: 'πŸ”’', background: '#dc3545' },
              medium: { icon: '🟑', background: '#ffc107' },
              low: { icon: '🟒', background: '#28a745' }
            }
          }
        ]
      })
    ]
  }
}));

Standalone Swagger UI

<!DOCTYPE html>
<html>
<head>
  <title>API Documentation</title>
  <link rel="stylesheet" type="text/css" href="./swagger-ui-bundle.css" />
</head>
<body>
  <div id="swagger-ui"></div>
  <script src="./swagger-ui-bundle.js"></script>
  <script src="./swagger-custom-badges.js"></script>
  <script>
    SwaggerUIBundle({
      url: './openapi.json',
      dom_id: '#swagger-ui',
      plugins: [
        SwaggerUIBundle.plugins.DownloadUrl,
        CustomBadgePlugin({
          fields: [
            {
              fieldName: 'x-team',
              badge: {
                icon: 'πŸ‘₯',
                background: '#17a2b8'
              }
            }
          ]
        })
      ]
    });
  </script>
</body>
</html>

Examples

Role-based Badges

CustomBadgePlugin({
  fields: [
    {
      fieldName: 'x-auth',
      badges: {
        admin: { icon: 'πŸ‘‘', background: '#dc3545' },
        moderator: { icon: 'πŸ›‘οΈ', background: '#fd7e14' },
        user: { icon: 'πŸ‘€', background: '#28a745' },
        guest: { icon: '🌐', background: '#6c757d' }
      }
    }
  ]
})

OpenAPI specification:

paths:
  /admin/users:
    get:
      x-auth: ["admin"]
  /posts:
    get:
      x-auth: ["admin", "moderator", "user"]
    post:
      x-auth: { admin: true, user: true }

Deprecation Badges

CustomBadgePlugin({
  fields: [
    {
      fieldName: 'x-deprecated',
      badge: {
        icon: '⚠️',
        background: '#ffc107',
        color: '#000'
      },
      parser: (value) => [
        {
          key: 'deprecated',
          value: `Deprecated since ${value.since}`
        }
      ]
    }
  ]
})

Environment Badges

CustomBadgePlugin({
  fields: [
    {
      fieldName: 'x-environment',
      badges: {
        production: { icon: 'πŸš€', background: '#dc3545' },
        staging: { icon: 'πŸ§ͺ', background: '#ffc107' },
        development: { icon: 'πŸ”§', background: '#28a745' }
      }
    }
  ]
})

Custom Parser Example

CustomBadgePlugin({
  fields: [
    {
      fieldName: 'x-rate-limit',
      badge: {
        icon: '⏱️',
        background: '#6f42c1'
      },
      parser: (value) => [
        {
          key: 'rate-limit',
          value: `${value.requests}/${value.window}`
        }
      ]
    }
  ]
})

Data Format Support

The plugin automatically parses different data formats:

String Values

x-roles: "admin,user,guest"  # Comma-separated values

Array Values

x-roles: ["admin", "user", "guest"]

Object Values

x-roles:
  admin: true
  user: false
  guest: true

Complex Objects

x-metadata:
  team: "backend"
  priority: "high"
  version: "v2"

Styling

The plugin automatically injects CSS styles, but you can override them:

.operation-with-badges {
  /* Container for operations with badges */
}

.badges {
  /* Container for badge row */
}

.swagger-custom-badge {
  /* Individual badge styling */
  display: inline-block;
  padding: 2px 6px;
  margin: 2px 4px 2px 0;
  font-size: 11px;
  font-weight: bold;
  border-radius: 3px;
  color: white;
}

API Reference

CustomBadgePlugin(config: PluginConfig)

Creates a new instance of the custom badge plugin.

Parameters:

  • config - Plugin configuration object

Returns: Swagger UI plugin object

Default Configuration

const defaultConfig = {
  fields: [],
  defaultIcon: '🏷️',
  defaultColor: 'white',
  defaultBackground: '#50e3c2'
};

Compatibility

  • Swagger UI: 5.21.0+ (peer dependency)
  • Node.js: 16+
  • TypeScript: 5.0+ (optional)

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Setup

# Clone the repository
git clone https://github.com/Dexsper/swagger-custom-badges.git
cd swagger-custom-badges

# Install dependencies
npm install

# Build the project
npm run build

# Run the example
cd examples/nestjs
npm install
npm run start:dev

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

Changelog

1.0.0

  • Initial release
  • Support for custom badges on Swagger UI operations
  • Configurable styling options
  • Multiple data format support
  • NestJS example

Made with ❀️ by Dexsper

About

A Swagger UI plugin to display custom badges for API operations using OpenAPI extension fields

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors