UNPKG

@nestjsvn/swagger-sse

Version:

OpenAPI documentation and interactive Swagger UI for NestJS Server-Sent Events endpoints

523 lines (373 loc) 11.8 kB
# API Reference Complete reference for all `@nestjsvn/swagger-sse` APIs, interfaces, and configuration options. ## Table of Contents 1. [Decorators](#decorators) 2. [Interfaces](#interfaces) 3. [Functions](#functions) 4. [Plugin Configuration](#plugin-configuration) 5. [UI Components](#ui-components) 6. [Type Definitions](#type-definitions) ## Decorators ### @ApiSse The main decorator for documenting Server-Sent Events endpoints. ```typescript @ApiSse(options: ApiSseOptions): MethodDecorator ``` #### Parameters - `options` - Configuration object of type [`ApiSseOptions`](#apisseoptionsinterface) #### Features - **Automatic Model Registration**: The decorator automatically registers all model types from the `events` parameter using `@ApiExtraModels`, eliminating the need for manual registration - **Type Safety**: Full TypeScript support with compile-time type checking - **Schema Generation**: Automatically generates OpenAPI schemas with oneOf/discriminator patterns #### Example ```typescript @ApiSse({ summary: 'User events stream', description: 'Real-time stream of user-related events', events: { 'user-created': UserCreatedDto, // Automatically registered with @ApiExtraModels 'user-updated': UserUpdatedDto, // Automatically registered with @ApiExtraModels }, tags: ['users', 'events'], deprecated: false, }) @Sse('user-stream') streamUserEvents(): Observable<MessageEvent> { // Implementation } ``` > **Note**: You no longer need to manually add `@ApiExtraModels(UserCreatedDto, UserUpdatedDto)` to your controller or method. The `@ApiSse` decorator handles this automatically. ## Interfaces ### ApiSseOptions Interface Configuration options for the `@ApiSse` decorator. ```typescript interface ApiSseOptions { /** Map of event names to their corresponding DTO types */ events: { [eventName: string]: Type<unknown> | Function | [Function] | string }; /** Default event type for messages without explicit event name */ defaultEvent?: Type<unknown> | Function | [Function] | string; /** Response content type (defaults to 'text/event-stream') */ produces?: string; /** Short summary of the operation */ summary?: string; /** Detailed description of the operation */ description?: string; /** Unique operation identifier */ operationId?: string; /** Tags for grouping operations */ tags?: string[]; /** Mark operation as deprecated */ deprecated?: boolean; /** Security requirements for the operation */ security?: SecurityRequirementObject[]; } ``` #### Properties ##### events (required) Maps event names to their corresponding TypeScript types or DTO classes. **Type**: `{ [eventName: string]: Type<unknown> | Function | [Function] | string }` **Examples**: ```typescript // Using DTO classes events: { 'user-created': UserCreatedDto, 'user-updated': UserUpdatedDto, } // Using inline types events: { 'simple-event': { message: string }, 'complex-event': ComplexEventDto, } // Using arrays for array types events: { 'batch-update': [UserDto], } ``` ##### defaultEvent (optional) Default event type for messages that don't specify an event type. **Type**: `Type<unknown> | Function | [Function] | string` **Example**: ```typescript defaultEvent: GenericEventDto ``` ##### produces (optional) Response content type. Defaults to `'text/event-stream'`. **Type**: `string` **Default**: `'text/event-stream'` ##### summary (optional) Short summary of the SSE endpoint operation. **Type**: `string` ##### description (optional) Detailed description of the SSE endpoint operation. **Type**: `string` ##### operationId (optional) Unique identifier for the operation. Used by code generators. **Type**: `string` ##### tags (optional) Array of tags for grouping operations in Swagger UI. **Type**: `string[]` ##### deprecated (optional) Mark the operation as deprecated. **Type**: `boolean` **Default**: `false` ##### security (optional) Security requirements for the operation. **Type**: `SecurityRequirementObject[]` **Example**: ```typescript security: [{ bearer: [] }] ``` ### SsePluginOptions Interface Configuration options for the CLI plugin. ```typescript interface SsePluginOptions { /** Event naming convention for auto-generated event names */ eventNamingConvention?: 'kebab-case' | 'camelCase' | 'PascalCase'; /** Whether to introspect JSDoc comments for documentation */ introspectComments?: boolean; /** Whether to auto-generate operation IDs */ autoGenerateOperationId?: boolean; /** Custom event type mappings */ customEventMappings?: { [typeName: string]: string }; } ``` #### Properties ##### eventNamingConvention (optional) Convention for auto-generated event names from TypeScript types. **Type**: `'kebab-case' | 'camelCase' | 'PascalCase'` **Default**: `'kebab-case'` **Examples**: - `'kebab-case'`: `UserCreatedDto``'user-created'` - `'camelCase'`: `UserCreatedDto``'userCreated'` - `'PascalCase'`: `UserCreatedDto``'UserCreated'` ##### introspectComments (optional) Whether to extract documentation from JSDoc comments. **Type**: `boolean` **Default**: `true` ##### autoGenerateOperationId (optional) Whether to automatically generate operation IDs. **Type**: `boolean` **Default**: `false` ##### customEventMappings (optional) Custom mappings from TypeScript type names to event names. **Type**: `{ [typeName: string]: string }` **Example**: ```typescript customEventMappings: { 'UserCreatedDto': 'user.created', 'OrderProcessedDto': 'order.processed', } ``` ## Functions ### setupSsePlugin Sets up Swagger UI with SSE plugin support. ```typescript function setupSsePlugin( app: INestApplication, document: OpenAPIObject, path: string, options?: SwaggerCustomOptions ): void ``` #### Parameters - `app` - NestJS application instance - `document` - OpenAPI document generated by SwaggerModule - `path` - Path where Swagger UI will be served - `options` - Optional Swagger UI customization options #### Example ```typescript import { setupSsePlugin } from '@nestjsvn/swagger-sse'; const document = SwaggerModule.createDocument(app, config); setupSsePlugin(app, document, 'api-docs', { customSiteTitle: 'My API Documentation', customCss: '.swagger-ui .topbar { display: none }', }); ``` ### generateSseSchema Generates OpenAPI schema for SSE events (internal function). ```typescript function generateSseSchema(options: ApiSseOptions): SchemaObject ``` #### Parameters - `options` - SSE configuration options #### Returns OpenAPI schema object with oneOf/discriminator pattern for event types. ## Plugin Configuration ### nest-cli.json Configuration Configure the CLI plugin in your `nest-cli.json` file: ```json { "collection": "@nestjs/schematics", "sourceRoot": "src", "compilerOptions": { "deleteOutDir": true, "plugins": [ "@nestjs/swagger", { "name": "@nestjsvn/swagger-sse/plugin", "options": { "eventNamingConvention": "kebab-case", "introspectComments": true, "autoGenerateOperationId": false, "customEventMappings": { "UserCreatedDto": "user.created" } } } ] } } ``` ### Plugin Behavior The CLI plugin automatically: 1. **Detects SSE endpoints** decorated with `@Sse()` 2. **Analyzes return types** to extract event types from `Observable<MessageEvent<T>>` 3. **Generates event mappings** based on TypeScript union types 4. **Adds @ApiSse decorators** with inferred configuration 5. **Extracts JSDoc comments** for documentation ## UI Components ### SSE Connection Interface The Swagger UI plugin adds these interactive elements: #### Connection Controls - **Connect Button**: Establishes SSE connection - **Disconnect Button**: Closes SSE connection - **Status Indicator**: Shows connection state (connected/disconnected/error) #### Event Display - **Event Log**: Scrollable list of received events - **Event Filtering**: Filter events by type - **Clear Button**: Clear event history - **Timestamp Display**: Shows when each event was received #### Event Format Events are displayed with: - **Event Type**: The event name/type - **Timestamp**: When the event was received - **Data**: JSON-formatted event payload - **Raw Data**: Toggle to show raw event data ### CSS Classes The plugin adds these CSS classes for styling: ```css .sse-plugin-container { /* Main container */ } .sse-connection-controls { /* Connection buttons area */ } .sse-status-indicator { /* Connection status */ } .sse-event-log { /* Event log container */ } .sse-event-item { /* Individual event */ } .sse-event-type { /* Event type label */ } .sse-event-timestamp { /* Event timestamp */ } .sse-event-data { /* Event data content */ } ``` ## Type Definitions ### MessageEvent Extension The library extends the standard MessageEvent interface: ```typescript interface MessageEvent<T = any> { data: string; // JSON stringified event data type: string; // Event type name lastEventId?: string; origin?: string; ports?: MessagePort[]; source?: EventSource; } ``` ### Event Schema Types ```typescript type EventTypeMapping = { [eventName: string]: Type<unknown> | Function | [Function] | string; }; type EventSchema = { oneOf: SchemaObject[]; discriminator: { propertyName: string; mapping: { [eventName: string]: string }; }; }; ``` ### Plugin Types ```typescript type EventNamingConvention = 'kebab-case' | 'camelCase' | 'PascalCase'; type CustomEventMapping = { [typeName: string]: string; }; ``` ## Error Handling ### Common Error Types #### SSE Connection Errors ```typescript interface SseConnectionError { type: 'connection_error'; message: string; code?: number; timestamp: Date; } ``` #### Schema Generation Errors ```typescript interface SchemaGenerationError { type: 'schema_error'; message: string; context: { eventName: string; eventType: string; }; } ``` #### Plugin Transformation Errors ```typescript interface PluginError { type: 'plugin_error'; message: string; file: string; line: number; } ``` ## Best Practices ### Event Naming - Use consistent naming conventions - Prefer kebab-case for event names - Use descriptive, action-oriented names - Group related events with prefixes ```typescript // Good events: { 'user-created': UserCreatedDto, 'user-updated': UserUpdatedDto, 'user-deleted': UserDeletedDto, } // Avoid events: { 'user1': UserDto, 'userStuff': UserDto, 'u_created': UserDto, } ``` ### Type Safety - Always use TypeScript classes or interfaces for event types - Avoid `any` types in event definitions - Use union types for complex event scenarios ```typescript // Good type UserEvent = | { type: 'created'; data: UserCreatedDto } | { type: 'updated'; data: UserUpdatedDto }; // Avoid events: { 'user-event': any, } ``` ### Performance - Limit event log size in UI - Use event filtering for high-frequency streams - Implement proper error handling - Consider connection cleanup on component unmount ## Migration Guide ### From Standard SSE If you're migrating from standard NestJS SSE endpoints: 1. **Add the package**: `npm install @nestjsvn/swagger-sse` 2. **Replace setup**: Use `setupSsePlugin()` instead of `SwaggerModule.setup()` 3. **Add decorators**: Add `@ApiSse()` to your SSE endpoints 4. **Update types**: Ensure your DTOs are properly typed 5. **Test documentation**: Verify Swagger UI shows SSE interfaces ### Version Compatibility - **NestJS**: v9.0.0+ (v10.0.0+ recommended) - **@nestjs/swagger**: v6.0.0+ (v7.0.0+ recommended) - **TypeScript**: v4.5+ (v5.0+ recommended) - **Node.js**: v16+ (v18+ recommended)