mirror of
https://github.com/LukeHagar/prettier-plugin-openapi.git
synced 2025-12-06 04:21:03 +00:00
800 lines
24 KiB
Markdown
800 lines
24 KiB
Markdown
# Prettier Plugin OpenAPI
|
|
|
|
A Prettier plugin for formatting OpenAPI/Swagger JSON and YAML files with intelligent key sorting, proper indentation, and support for modular OpenAPI file structures.
|
|
|
|
## Features
|
|
|
|
- 🎯 **OpenAPI/Swagger Support**: Formats both JSON and YAML OpenAPI specifications
|
|
- 🔄 **Smart Key Sorting**: Automatically sorts OpenAPI keys in the recommended order
|
|
- 📁 **Modular File Support**: Handles both monolithic and modular OpenAPI file structures
|
|
- 🧩 **Component Files**: Supports individual component files (schemas, parameters, responses, etc.)
|
|
- 📝 **YAML & JSON**: Supports both `.yaml/.yml` and `.json` file formats
|
|
- 🎨 **Consistent Formatting**: Applies consistent indentation and line breaks
|
|
- 🔌 **Vendor Extensions**: Programmatic loading of vendor-specific extensions
|
|
- ⚡ **Fast**: Built with performance in mind using modern JavaScript
|
|
- 🧪 **Comprehensive Testing**: 142 tests with 95.69% line coverage
|
|
- 🚀 **CI/CD Ready**: Automated testing, building, and publishing
|
|
- 🔒 **Strict Validation**: Properly rejects non-OpenAPI content
|
|
- 📊 **High Quality**: Biome, Prettier, and TypeScript for code quality
|
|
|
|
## Current Status
|
|
|
|
✅ **Production Ready**: Version 1.0.1 with comprehensive test coverage
|
|
✅ **Modern Tooling**: Updated to use Biome for fast linting and formatting
|
|
✅ **Comprehensive Testing**: 142 tests covering all major functionality
|
|
✅ **High Performance**: Optimized for large OpenAPI files
|
|
✅ **Active Development**: Regular updates and improvements
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
npm install --save-dev prettier-plugin-openapi
|
|
# or
|
|
pnpm add --dev prettier-plugin-openapi
|
|
# or
|
|
yarn add --dev prettier-plugin-openapi
|
|
# or
|
|
bun add --dev prettier-plugin-openapi
|
|
```
|
|
|
|
## Usage
|
|
|
|
### Command Line
|
|
|
|
```bash
|
|
# Format a single file
|
|
pnpx prettier --write api.yaml
|
|
|
|
# Format all OpenAPI files in a directory
|
|
pnpx prettier --write "**/*.{openapi.json,openapi.yaml,swagger.json,swagger.yaml}"
|
|
|
|
# Format with specific options
|
|
pnpx prettier --write api.yaml --tab-width 4 --print-width 100
|
|
```
|
|
|
|
### Configuration
|
|
|
|
Add the plugin to your Prettier configuration:
|
|
|
|
**package.json**
|
|
```json
|
|
{
|
|
"prettier": {
|
|
"plugins": ["prettier-plugin-openapi"]
|
|
}
|
|
}
|
|
```
|
|
|
|
**.prettierrc**
|
|
```json
|
|
{
|
|
"plugins": ["prettier-plugin-openapi"],
|
|
"tabWidth": 2,
|
|
"printWidth": 80
|
|
}
|
|
```
|
|
|
|
**.prettierrc.js**
|
|
```javascript
|
|
module.exports = {
|
|
plugins: ['prettier-plugin-openapi'],
|
|
tabWidth: 2,
|
|
printWidth: 80,
|
|
};
|
|
```
|
|
|
|
## Supported File Extensions
|
|
|
|
- `.openapi.json`
|
|
- `.openapi.yaml`
|
|
- `.openapi.yml`
|
|
- `.swagger.json`
|
|
- `.swagger.yaml`
|
|
- `.swagger.yml`
|
|
- `.json` (for component files)
|
|
- `.yaml` / `.yml` (for component files)
|
|
|
|
## Modular File Structure Support
|
|
|
|
The plugin supports both monolithic and modular OpenAPI file structures:
|
|
|
|
### Monolithic Structure
|
|
```
|
|
api.yaml # Single file with everything
|
|
```
|
|
|
|
### Modular Structure
|
|
```
|
|
├─ openapi.yaml # Root document
|
|
├─ paths/ # Path files
|
|
│ ├─ users.yaml
|
|
│ ├─ users_{id}.yaml
|
|
│ └─ auth_login.yaml
|
|
├─ components/ # Component files
|
|
│ ├─ schemas/
|
|
│ │ ├─ User.yaml
|
|
│ │ ├─ UserCreate.yaml
|
|
│ │ └─ Error.yaml
|
|
│ ├─ parameters/
|
|
│ │ ├─ CommonPagination.yaml
|
|
│ │ └─ UserId.yaml
|
|
│ ├─ responses/
|
|
│ │ ├─ ErrorResponse.yaml
|
|
│ │ └─ UserResponse.yaml
|
|
│ ├─ requestBodies/
|
|
│ │ └─ UserCreateBody.yaml
|
|
│ ├─ headers/
|
|
│ │ └─ RateLimitHeaders.yaml
|
|
│ ├─ examples/
|
|
│ │ └─ UserExample.yaml
|
|
│ ├─ securitySchemes/
|
|
│ │ └─ BearerAuth.yaml
|
|
│ ├─ links/
|
|
│ │ └─ UserCreatedLink.yaml
|
|
│ └─ callbacks/
|
|
│ └─ NewMessageCallback.yaml
|
|
└─ webhooks/ # Webhook files
|
|
└─ messageCreated.yaml
|
|
```
|
|
|
|
## Key Sorting
|
|
|
|
The plugin automatically sorts OpenAPI keys in the recommended order:
|
|
|
|
> 📖 **Complete Key Reference**: For a comprehensive reference of all keys, their ordering, and detailed reasoning, see [KEYS.md](./KEYS.md).
|
|
|
|
## Examples
|
|
|
|
### Monolithic File Structure
|
|
|
|
#### Before (unformatted):
|
|
```yaml
|
|
paths:
|
|
/users:
|
|
get:
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
components:
|
|
schemas:
|
|
User:
|
|
type: object
|
|
openapi: 3.0.0
|
|
info:
|
|
version: 1.0.0
|
|
title: My API
|
|
```
|
|
|
|
#### After (formatted):
|
|
```yaml
|
|
openapi: 3.0.0
|
|
info:
|
|
title: My API
|
|
version: 1.0.0
|
|
paths:
|
|
/users:
|
|
get:
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
components:
|
|
schemas:
|
|
User:
|
|
type: object
|
|
```
|
|
|
|
### Modular File Structure
|
|
|
|
#### Root Document (`openapi.yaml`):
|
|
```yaml
|
|
openapi: 3.0.0
|
|
info:
|
|
title: My API
|
|
version: 1.0.0
|
|
paths:
|
|
$ref: './paths/users.yaml'
|
|
components:
|
|
schemas:
|
|
$ref: './components/schemas/User.yaml'
|
|
```
|
|
|
|
#### Component File (`components/schemas/User.yaml`):
|
|
```yaml
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
name:
|
|
type: string
|
|
required:
|
|
- id
|
|
- name
|
|
```
|
|
|
|
#### Path File (`paths/users.yaml`):
|
|
```yaml
|
|
get:
|
|
summary: Get users
|
|
responses:
|
|
'200':
|
|
description: Success
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '../components/schemas/User.yaml'
|
|
```
|
|
|
|
## Vendor Extension Guide
|
|
|
|
### Adding Your Vendor Extensions
|
|
|
|
The plugin supports a simple system for vendors to contribute custom extensions.
|
|
|
|
Here's how to add your vendor extensions:
|
|
|
|
#### Step 1: Create Your Vendor Extension File
|
|
|
|
Create a new TypeScript file in `src/extensions/vendor/your-vendor.ts`:
|
|
|
|
```typescript
|
|
/**
|
|
* Your Vendor Extensions
|
|
*
|
|
* Your vendor extensions for OpenAPI formatting.
|
|
* Website: https://your-vendor.com
|
|
*/
|
|
|
|
import { defineConfig } from "../index.js";
|
|
|
|
export const yourVendor = defineConfig({
|
|
info: {
|
|
name: 'Your Vendor',
|
|
website: 'https://your-vendor.com',
|
|
support: 'support@your-vendor.com'
|
|
},
|
|
extensions: {
|
|
// Define your extensions here
|
|
}
|
|
});
|
|
```
|
|
|
|
#### Step 2: Register Your Vendor
|
|
|
|
Add your vendor to the vendor loader in `src/extensions/vendor-loader.ts`:
|
|
|
|
```typescript
|
|
// Import your vendor extension
|
|
import { yourVendor } from './vendor/your-vendor.js';
|
|
|
|
// Add to the vendorModules array
|
|
const vendorModules = [
|
|
speakeasy,
|
|
postman,
|
|
redoc,
|
|
yourVendor // Add your vendor here
|
|
];
|
|
```
|
|
|
|
#### Step 3: Define Your Extensions
|
|
|
|
Use the `before()` and `after()` helper functions to position your extensions relative to standard OpenAPI keys. The system now provides **full IntelliSense support** with type-safe key suggestions:
|
|
|
|
```typescript
|
|
extensions: {
|
|
'top-level': (before, after) => {
|
|
// ✅ IntelliSense shows: 'swagger', 'openapi', 'info', 'paths', etc.
|
|
return {
|
|
'x-your-vendor-sdk': before('info'), // ✅ Type-safe: 'info' is valid
|
|
'x-your-vendor-auth': after('paths'), // ✅ Type-safe: 'paths' is valid
|
|
// 'x-invalid': before('invalidKey'), // ❌ TypeScript error: 'invalidKey' not valid
|
|
};
|
|
},
|
|
'operation': (before, after) => {
|
|
// ✅ IntelliSense shows: 'summary', 'operationId', 'parameters', 'responses', etc.
|
|
return {
|
|
'x-your-vendor-retries': after('parameters'), // ✅ Type-safe: 'parameters' is valid
|
|
'x-your-vendor-timeout': before('responses'), // ✅ Type-safe: 'responses' is valid
|
|
};
|
|
},
|
|
'schema': (before, after) => {
|
|
// ✅ IntelliSense shows: '$ref', 'title', 'type', 'format', 'example', etc.
|
|
return {
|
|
'x-your-vendor-validation': after('type'), // ✅ Type-safe: 'type' is valid
|
|
'x-your-vendor-example': after('example'), // ✅ Type-safe: 'example' is valid
|
|
};
|
|
}
|
|
}
|
|
```
|
|
|
|
### 🎯 Enhanced IntelliSense Features
|
|
|
|
The vendor extension system now provides comprehensive IntelliSense support:
|
|
|
|
#### Type-Safe Key Suggestions
|
|
- **Context-aware autocomplete**: Each context shows only valid OpenAPI keys
|
|
- **Real-time validation**: TypeScript errors for invalid keys
|
|
- **Hover documentation**: Detailed information about each key's purpose
|
|
|
|
#### Available Contexts with IntelliSense
|
|
- `'top-level'` → Shows: `swagger`, `openapi`, `info`, `paths`, `components`, etc.
|
|
- `'info'` → Shows: `title`, `version`, `description`, `contact`, `license`, etc.
|
|
- `'operation'` → Shows: `summary`, `operationId`, `parameters`, `responses`, etc.
|
|
- `'schema'` → Shows: `$ref`, `title`, `type`, `format`, `example`, etc.
|
|
- `'parameter'` → Shows: `name`, `description`, `in`, `required`, `schema`, etc.
|
|
- `'response'` → Shows: `description`, `headers`, `content`, `links`
|
|
- `'securityScheme'` → Shows: `type`, `description`, `name`, `in`, `scheme`, etc.
|
|
- `'server'` → Shows: `url`, `description`, `variables`
|
|
- `'tag'` → Shows: `name`, `description`, `externalDocs`
|
|
- `'externalDocs'` → Shows: `description`, `url`
|
|
- `'webhook'` → Shows: `summary`, `operationId`, `parameters`, `responses`, etc.
|
|
- `'definitions'` → Shows schema keys (Swagger 2.0)
|
|
- `'securityDefinitions'` → Shows security scheme keys (Swagger 2.0)
|
|
|
|
#### Enhanced Helper Functions
|
|
|
|
```typescript
|
|
import { createPositionHelpers } from "../index.js";
|
|
|
|
// Get enhanced helpers for a specific context
|
|
const helpers = createPositionHelpers('operation');
|
|
|
|
// Type-safe positioning
|
|
helpers.before('parameters'); // ✅ IntelliSense shows valid operation keys
|
|
helpers.after('responses'); // ✅ IntelliSense shows valid operation keys
|
|
|
|
// Additional utilities
|
|
const availableKeys = helpers.getAvailableKeys(); // Get all valid keys
|
|
const isValid = helpers.isValidKey('summary'); // Check if key is valid
|
|
```
|
|
|
|
### Supported Contexts
|
|
|
|
You can define extensions for these OpenAPI contexts:
|
|
|
|
- `'top-level'` - Root OpenAPI document
|
|
- `'info'` - API information section
|
|
- `'operation'` - HTTP operations (GET, POST, etc.)
|
|
- `'parameter'` - Operation parameters
|
|
- `'schema'` - Data schemas
|
|
- `'response'` - Operation responses
|
|
- `'securityScheme'` - Security schemes
|
|
- `'server'` - Server definitions
|
|
- `'tag'` - API tags
|
|
- `'externalDocs'` - External documentation
|
|
- `'webhook'` - Webhook definitions
|
|
- `'definitions'` - Swagger 2.0 definitions
|
|
- `'securityDefinitions'` - Swagger 2.0 security definitions
|
|
|
|
### Standard OpenAPI Keys Reference
|
|
|
|
When positioning your extensions, you can reference these standard OpenAPI keys:
|
|
|
|
#### Top-Level Keys
|
|
- `openapi`, `swagger`, `info`, `externalDocs`, `servers`, `security`, `tags`, `paths`, `webhooks`, `components`
|
|
|
|
#### Info Section Keys
|
|
- `title`, `version`, `summary`, `description`, `termsOfService`, `contact`, `license`
|
|
|
|
#### Operation Keys
|
|
- `summary`, `operationId`, `description`, `externalDocs`, `tags`, `deprecated`, `security`, `servers`, `parameters`, `requestBody`, `responses`, `callbacks`
|
|
|
|
#### Schema Keys
|
|
- `$ref`, `title`, `description`, `type`, `format`, `enum`, `default`, `example`, `properties`, `required`, `items`, `allOf`, `anyOf`, `oneOf`, `not`
|
|
|
|
#### Parameter Keys
|
|
- `name`, `description`, `in`, `required`, `deprecated`, `schema`, `content`, `style`, `explode`, `allowReserved`, `example`
|
|
|
|
#### Response Keys
|
|
- `description`, `headers`, `content`, `links`
|
|
|
|
#### Security Scheme Keys
|
|
- `type`, `description`, `name`, `in`, `scheme`, `bearerFormat`, `flows`, `openIdConnectUrl`
|
|
|
|
#### Server Keys
|
|
- `url`, `description`, `variables`
|
|
|
|
#### Tag Keys
|
|
- `name`, `description`, `externalDocs`
|
|
|
|
#### External Docs Keys
|
|
- `description`, `url`
|
|
|
|
#### Webhook Keys
|
|
- `summary`, `operationId`, `description`, `deprecated`, `tags`, `security`, `servers`, `parameters`, `requestBody`, `responses`, `callbacks`
|
|
|
|
> 📖 **Complete Key Reference**: For a comprehensive reference of all keys, their ordering, and detailed reasoning, see [KEYS.md](./KEYS.md).
|
|
|
|
### Positioning Your Extensions
|
|
|
|
Use the helper functions to position your extensions:
|
|
|
|
- `before(key)` - Position before a standard OpenAPI key
|
|
- `after(key)` - Position after a standard OpenAPI key
|
|
|
|
#### Example: Positioning Extensions
|
|
|
|
```typescript
|
|
'operation': (before, after) => {
|
|
return {
|
|
// Position before standard keys
|
|
'x-your-vendor-auth': before('security'),
|
|
'x-your-vendor-rate-limit': before('parameters'),
|
|
|
|
// Position after standard keys
|
|
'x-your-vendor-retries': after('parameters'),
|
|
'x-your-vendor-timeout': after('responses'),
|
|
|
|
// Position relative to other extensions
|
|
'x-your-vendor-cache': after('x-your-vendor-retries'),
|
|
};
|
|
}
|
|
```
|
|
|
|
### Extension Naming Convention
|
|
|
|
Follow these naming conventions for your extensions:
|
|
|
|
- Use your vendor prefix: `x-your-vendor-`
|
|
- Use descriptive names: `x-your-vendor-retries`, `x-your-vendor-timeout`
|
|
- Keep names consistent across contexts
|
|
- Use kebab-case for multi-word extensions
|
|
|
|
### Testing Your Extensions
|
|
|
|
1. **Build the project**: `bun run build`
|
|
2. **Run tests**: `bun test`
|
|
3. **Test with real OpenAPI files**: Create test files with your extensions
|
|
4. **Verify positioning**: Check that your extensions appear in the correct order
|
|
|
|
### Extension Collision Detection
|
|
|
|
The system automatically detects and warns about extension key collisions:
|
|
|
|
```
|
|
⚠️ Extension collision detected!
|
|
Key: "x-common-extension" in context "operation"
|
|
Already defined by: Vendor A
|
|
Conflicting with: Vendor B
|
|
Using position from: Vendor A (5)
|
|
Ignoring position from: Vendor B (3)
|
|
```
|
|
|
|
### Advanced Type Safety
|
|
|
|
The vendor extension system provides comprehensive TypeScript support:
|
|
|
|
#### Type Definitions
|
|
```typescript
|
|
import {
|
|
type VendorExtensions,
|
|
type ContextExtensionFunction,
|
|
type OpenAPIContext,
|
|
type ExtensionKey
|
|
} from "../index.js";
|
|
|
|
// Type-safe extension configuration
|
|
const extensions: VendorExtensions = {
|
|
'top-level': (before, after) => {
|
|
// before and after are type-safe for top-level keys
|
|
return {
|
|
'x-my-extension': before('info'),
|
|
'x-my-config': after('paths')
|
|
};
|
|
}
|
|
};
|
|
```
|
|
|
|
#### Extension Key Validation
|
|
```typescript
|
|
import { isValidExtensionKey } from "../index.js";
|
|
|
|
// Validate extension keys follow OpenAPI conventions
|
|
const isValid = isValidExtensionKey('x-my-vendor-extension'); // ✅ true
|
|
const isInvalid = isValidExtensionKey('my-extension'); // ❌ false
|
|
```
|
|
|
|
#### Context-Specific Helpers
|
|
```typescript
|
|
import { createPositionHelpers } from "../index.js";
|
|
|
|
// Get type-safe helpers for a specific context
|
|
const operationHelpers = createPositionHelpers('operation');
|
|
|
|
// All functions are type-safe
|
|
operationHelpers.before('summary'); // ✅ Valid operation key
|
|
operationHelpers.after('responses'); // ✅ Valid operation key
|
|
operationHelpers.isValidKey('summary'); // ✅ true
|
|
operationHelpers.getAvailableKeys(); // Returns all valid operation keys
|
|
```
|
|
|
|
### Best Practices
|
|
|
|
1. **Use descriptive extension names** that clearly indicate their purpose
|
|
2. **Position extensions logically** relative to related standard keys
|
|
3. **Document your extensions** in your vendor documentation
|
|
4. **Test thoroughly** with real OpenAPI files
|
|
5. **Follow OpenAPI extension conventions** (x-vendor-name format)
|
|
6. **Consider extension conflicts** when choosing names
|
|
7. **Leverage IntelliSense** for type-safe key positioning
|
|
8. **Use helper functions** for additional validation and discovery
|
|
|
|
### Troubleshooting
|
|
|
|
#### Common Issues
|
|
|
|
**Extension not appearing in formatted output:**
|
|
- Check that your vendor is registered in `vendor-loader.ts`
|
|
- Verify your extension keys follow the `x-vendor-name` format
|
|
- Ensure your positioning functions return valid numbers
|
|
|
|
**Extensions in wrong order:**
|
|
- Use `before()` and `after()` helper functions for positioning
|
|
- Check that referenced standard keys exist in the context
|
|
- Verify your positioning logic is correct
|
|
|
|
**Extension collisions:**
|
|
- Use unique vendor prefixes to avoid conflicts
|
|
- Check the console for collision warnings
|
|
- Consider renaming conflicting extensions
|
|
|
|
**Build errors:**
|
|
- Ensure your TypeScript syntax is correct
|
|
- Check that all imports are properly resolved
|
|
- Verify your extension structure matches the expected format
|
|
|
|
#### Debug Tips
|
|
|
|
1. **Enable debug logging**: Set `DEBUG=prettier-plugin-openapi:*` environment variable
|
|
2. **Check console output**: Look for collision warnings and error messages
|
|
3. **Test with simple extensions**: Start with basic positioning before complex logic
|
|
4. **Verify context names**: Ensure you're using the correct context names from the supported list
|
|
|
|
### Example: Complete Vendor Extension
|
|
|
|
```typescript
|
|
/**
|
|
* MyAPI Extensions
|
|
*
|
|
* MyAPI platform extensions for OpenAPI formatting.
|
|
* Website: https://myapi.com
|
|
*/
|
|
|
|
import { defineConfig } from "../index.js";
|
|
|
|
export const myapi = defineConfig({
|
|
info: {
|
|
name: 'MyAPI',
|
|
website: 'https://myapi.com',
|
|
support: 'support@myapi.com'
|
|
},
|
|
extensions: {
|
|
'top-level': (before, after) => {
|
|
return {
|
|
'x-myapi-sdk': before('info'),
|
|
'x-myapi-version': after('info'),
|
|
};
|
|
},
|
|
'operation': (before, after) => {
|
|
return {
|
|
'x-myapi-rate-limit': before('parameters'),
|
|
'x-myapi-retries': after('parameters'),
|
|
'x-myapi-timeout': after('responses'),
|
|
};
|
|
},
|
|
'schema': (before, after) => {
|
|
return {
|
|
'x-myapi-validation': after('type'),
|
|
'x-myapi-example': after('example'),
|
|
};
|
|
}
|
|
}
|
|
});
|
|
```
|
|
|
|
## Development
|
|
|
|
### Modern Development Stack
|
|
|
|
This project uses modern development tools for optimal performance and developer experience:
|
|
|
|
- **Bun** - Fast JavaScript runtime and package manager
|
|
- **TypeScript** - Type-safe development with strict settings
|
|
- **Biome** - Fast linting and formatting (replaces ESLint + Prettier for code)
|
|
- **Prettier** - Documentation and configuration file formatting
|
|
- **GitHub Actions** - Automated CI/CD with smart releases
|
|
|
|
### Quick Start
|
|
|
|
```bash
|
|
# Install dependencies
|
|
bun install
|
|
|
|
# Build the plugin
|
|
bun run build
|
|
|
|
# Run tests
|
|
bun test
|
|
|
|
# Run tests with coverage
|
|
bun test --coverage
|
|
|
|
# Lint code
|
|
bun run lint
|
|
|
|
# Fix linting issues
|
|
bun run lint:fix
|
|
|
|
# Format code
|
|
bun run format
|
|
```
|
|
|
|
### Available Scripts
|
|
|
|
- `bun run dev` - Start development mode with TypeScript watch
|
|
- `bun run build` - Build the project
|
|
- `bun run test` - Run all tests
|
|
- `bun run test:coverage` - Run tests with coverage report
|
|
- `bun run test:watch` - Run tests in watch mode
|
|
- `bun run lint` - Run Biome linting
|
|
- `bun run lint:fix` - Fix Biome linting issues automatically
|
|
- `bun run format` - Format code with Prettier
|
|
- `bun run format:check` - Check code formatting
|
|
- `bun run type-check` - Run TypeScript type checking
|
|
- `bun run validate` - Run all validation checks (type-check, lint, test)
|
|
- `bun run clean` - Clean build artifacts
|
|
|
|
### Project Structure
|
|
|
|
```
|
|
src/
|
|
index.ts # Main plugin implementation
|
|
keys.ts # OpenAPI key definitions
|
|
extensions/
|
|
index.ts # Extension system
|
|
vendor-loader.ts # Automatic vendor loading
|
|
vendor/ # Vendor extensions
|
|
speakeasy.ts
|
|
postman.ts
|
|
redoc.ts
|
|
test/
|
|
plugin.test.ts # Core plugin tests
|
|
integration.test.ts # Integration tests
|
|
build.test.ts # Build validation tests
|
|
coverage.test.ts # Coverage enhancement tests
|
|
file-detection.test.ts # File detection tests
|
|
key-ordering.test.ts # Key sorting tests
|
|
custom-extensions.test.ts # Extension tests
|
|
options.test.ts # Configuration tests
|
|
simple-ordering.test.ts # Basic ordering tests
|
|
vendor.test.ts # Vendor extension tests
|
|
setup.ts # Test utilities
|
|
```
|
|
|
|
### Test Suite
|
|
|
|
The project includes a comprehensive test suite with **142 tests** covering:
|
|
|
|
- **Core Functionality**: Plugin structure, parsing, formatting
|
|
- **Integration Tests**: Real OpenAPI file processing, error handling
|
|
- **Build Tests**: Package validation, TypeScript compilation
|
|
- **Coverage Tests**: Edge cases, error scenarios
|
|
- **File Detection**: OpenAPI file recognition, component files
|
|
- **Key Ordering**: OpenAPI key sorting, custom extensions
|
|
- **Vendor Extensions**: Extension system functionality
|
|
- **Options**: Configuration and formatting options
|
|
|
|
**Coverage**: 95.69% line coverage, 97.00% function coverage
|
|
|
|
### CI/CD Pipeline
|
|
|
|
The project includes automated CI/CD with GitHub Actions:
|
|
|
|
- **Continuous Integration**: Tests on Node.js 18, 20, 22 and Bun
|
|
- **Automated Testing**: Linting with Biome, type checking, security audits
|
|
- **Smart Releases**: Automatic patch version bumps on main branch updates
|
|
- **NPM Publishing**: Automated publishing with version management
|
|
- **Quality Gates**: All tests must pass before release
|
|
|
|
## Configuration Options
|
|
|
|
The plugin respects standard Prettier options:
|
|
|
|
- `tabWidth`: Number of spaces for indentation (default: 2)
|
|
- `printWidth`: Maximum line length (default: 80)
|
|
- `useTabs`: Use tabs instead of spaces (default: true)
|
|
|
|
## Advanced Features
|
|
|
|
### File Detection
|
|
|
|
The plugin intelligently detects OpenAPI files based on:
|
|
|
|
1. **Content Structure**: Files with OpenAPI-specific keys (`openapi`, `swagger`, `components`, etc.)
|
|
2. **Directory Patterns**: Files in OpenAPI-related directories (`components/`, `paths/`, `webhooks/`)
|
|
3. **File Extensions**: Standard OpenAPI file extensions
|
|
|
|
### Key Sorting Algorithm
|
|
|
|
The plugin uses a unified sorting algorithm that:
|
|
|
|
1. **Prioritizes Standard Keys**: OpenAPI specification keys are sorted first
|
|
2. **Handles Custom Extensions**: Vendor extensions are positioned relative to standard keys
|
|
3. **Sorts Unknown Keys**: Non-standard keys are sorted alphabetically at the end
|
|
4. **Context-Aware**: Different sorting rules for different OpenAPI contexts (operations, schemas, etc.)
|
|
|
|
### Performance Optimizations
|
|
|
|
- **Unified Sorting Function**: Single function handles all sorting scenarios
|
|
- **Lazy Loading**: Vendor extensions are loaded only when needed
|
|
- **Efficient Detection**: Fast file type detection with minimal overhead
|
|
|
|
## Quality & Reliability
|
|
|
|
### Comprehensive Testing
|
|
|
|
- **142 Test Cases**: Covering all major functionality
|
|
- **95.69% Line Coverage**: Extensive test coverage
|
|
- **97.00% Function Coverage**: Nearly complete function testing
|
|
- **Edge Case Testing**: Malformed files, error scenarios, performance
|
|
- **Integration Testing**: Real-world OpenAPI file processing
|
|
|
|
### Code Quality
|
|
|
|
- **TypeScript**: Full type safety and IntelliSense support
|
|
- **Biome**: Fast linting and formatting with TypeScript support
|
|
- **Prettier**: Consistent code formatting
|
|
- **Security Audits**: Automated dependency vulnerability scanning
|
|
- **Performance Testing**: Large file handling and memory usage
|
|
|
|
### CI/CD Pipeline
|
|
|
|
- **Automated Testing**: Runs on every commit and PR
|
|
- **Multi-Environment**: Tests on Node.js 18, 20, 22 and Bun
|
|
- **Quality Gates**: All tests must pass before merge
|
|
- **Smart Releases**: Automatic patch version management
|
|
- **NPM Publishing**: Automated package publishing with proper versioning
|
|
|
|
## Contributing
|
|
|
|
We welcome contributions! Please follow these steps:
|
|
|
|
1. **Fork the repository**
|
|
2. **Create a feature branch**: `git checkout -b feature/your-feature-name`
|
|
3. **Make your changes** with proper TypeScript types
|
|
4. **Add tests** for new functionality (aim for 90%+ coverage)
|
|
5. **Run the test suite**:
|
|
```bash
|
|
bun test
|
|
bun run lint
|
|
bun run format
|
|
```
|
|
6. **Ensure all tests pass** (142 tests, 0 failures)
|
|
7. **Submit a pull request** with a clear description
|
|
|
|
### Development Guidelines
|
|
|
|
- **Code Quality**: All code must pass Biome and Prettier checks
|
|
- **Testing**: New features require comprehensive tests
|
|
- **TypeScript**: Use proper types and interfaces
|
|
- **Documentation**: Update README for new features
|
|
- **CI/CD**: All GitHub Actions must pass before merge
|
|
|
|
### Release Process
|
|
|
|
- **Automatic**: Patch releases happen automatically on main branch updates
|
|
- **Manual**: Major/minor releases require manual version bumps
|
|
- **Quality Gates**: All tests, linting, and security checks must pass
|
|
- **NPM Publishing**: Automated publishing with proper versioning
|
|
|
|
## License
|
|
|
|
MIT License - see LICENSE file for details.
|
|
|
|
## Related Projects
|
|
|
|
- [Prettier](https://prettier.io/) - The core formatter
|
|
- [OpenAPI Specification](https://spec.openapis.org/oas/v3.1.0.html) - The OpenAPI specification
|
|
- [Swagger](https://swagger.io/) - API development tools
|