@laag/openapi
v2.0.6
Published
TypeScript library for interfacing with OpenAPI/Swagger documents
Downloads
346
Maintainers
Readme
@laag/openapi
A modern TypeScript library for working with OpenAPI/Swagger specification documents. Provides comprehensive support for reading, writing, and manipulating OpenAPI 3.0+ documents with full type safety.
Features
- 🔧 Full TypeScript Support - Complete type definitions for OpenAPI 3.0+ specification
- 📦 Multiple Module Formats - ESM, CommonJS, and browser bundles
- ✅ Document Validation - Built-in validation according to OpenAPI specification
- 🚀 High Performance - Optimized for speed and memory efficiency
- 🔌 Extension Support - Full support for OpenAPI extensions (x-* properties)
- 🛠️ Developer Friendly - Comprehensive API with utility methods
- 🌐 Cross-Platform - Works in Node.js, browsers, and edge environments
Installation
# Install with npm
npm install @laag/openapi @laag/core
# Install with yarn
yarn add @laag/openapi @laag/core
# Install with bun
bun add @laag/openapi @laag/coreQuick Start
ESM (Recommended)
import { Openapi } from '@laag/openapi';
// Create from object
const api = new Openapi({
openapi: '3.0.2',
info: { title: 'My API', version: '1.0.0' },
paths: {},
});
console.log(api.info.title); // "My API"CommonJS
const { Openapi } = require('@laag/openapi');
const api = new Openapi({
openapi: '3.0.2',
info: { title: 'My API', version: '1.0.0' },
paths: {},
});Usage Examples
Reading an Existing Document
import { readFileSync } from 'fs';
import { Openapi } from '@laag/openapi';
// Load from JSON file
const jsonData = readFileSync('petstore.json', 'utf8');
const api = new Openapi(jsonData);
console.log(`API: ${api.info.title} v${api.info.version}`);
console.log('Available paths:');
for (const path of api.getPathNames()) {
console.log(` ${path}`);
}
// Get operation details
const operations = api.getOperationIds();
for (const op of operations) {
console.log(`${op.method.toUpperCase()} ${op.path} → ${op.id}`);
}Output:
API: Swagger Petstore v1.0.0
Available paths:
/pets
/pets/{petId}
GET /pets → listPets
POST /pets → createPets
GET /pets/{petId} → showPetByIdCreating a New Document
import { Openapi } from '@laag/openapi';
import type { InfoObject, PathItemObject } from '@laag/openapi';
// Create empty document
const api = new Openapi();
// Set API information with type safety
api.info = {
title: 'User Management API',
version: '2.0.0',
description: 'A comprehensive user management system',
contact: {
name: 'API Team',
email: '[email protected]',
},
license: {
name: 'MIT',
url: 'https://opensource.org/licenses/MIT',
},
};
// Add servers
api.servers = [
{
url: 'https://api.company.com/v2',
description: 'Production server',
},
];
// Add a path with full type safety
const userPath: PathItemObject = {
get: {
summary: 'Get user by ID',
operationId: 'getUserById',
parameters: [
{
name: 'userId',
in: 'path',
required: true,
schema: { type: 'string' },
},
],
responses: {
'200': {
description: 'User found',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/User' },
},
},
},
'404': {
description: 'User not found',
},
},
},
};
api.appendPath('/users/{userId}', userPath);
// Add components
api.components = {
schemas: {
User: {
type: 'object',
required: ['id', 'name', 'email'],
properties: {
id: { type: 'string', format: 'uuid' },
name: { type: 'string' },
email: { type: 'string', format: 'email' },
},
},
},
};
// Output as pretty JSON
console.log(api.getDefinition('prettyjson'));Working with Extensions
import { Openapi } from '@laag/openapi';
const api = new Openapi();
// Add root-level extensions
api.rootExtensions = {
'x-api-id': 'user-api',
'x-rate-limit': 1000,
};
// Add info-level extensions
api.infoExtensions = {
'x-logo': {
url: 'https://company.com/logo.png',
},
};
// Add path-level extensions
api.pathsExtensions = {
'x-cache-ttl': 300,
};Document Validation
import { Openapi } from '@laag/openapi';
const api = new Openapi({
openapi: '3.0.2',
info: { title: 'Test API', version: '1.0.0' },
paths: {},
});
const validation = api.validate();
if (validation.valid) {
console.log('✅ Document is valid');
} else {
console.log('❌ Document has errors:');
for (const error of validation.errors) {
console.log(` ${error.path}: ${error.message}`);
}
}Sample Generation
Generate sample payloads and code from your OpenAPI schemas:
import { Openapi } from '@laag/openapi';
const api = new Openapi(/* your document */);
// Generate JSON samples from schemas
const requestSample = api.generateJsonSample('/users', 'post', 'request');
const responseSample = api.generateJsonSample('/users', 'post', 'response');
console.log('Request:', JSON.stringify(requestSample, null, 2));
console.log('Response:', JSON.stringify(responseSample, null, 2));
// Generate curl commands
const curlCommands = api.getCurlCommands('/users', 'post');
for (const cmd of curlCommands) {
console.log(cmd.command);
}
// Generate Python code
const pythonCode = api.getPythonCode('/users', 'post');
console.log(pythonCode);
// Generate JavaScript code (async/await or promises)
const jsCodeAsync = api.getJavaScriptCode('/users', 'post', true);
const jsCodePromise = api.getJavaScriptCode('/users', 'get', false);
// Generate TypeScript code with interfaces
const tsCode = api.getTypeScriptCode('/users', 'post');
console.log(tsCode);Advanced Operations
import { Openapi } from '@laag/openapi';
const api = new Openapi(/* your document */);
// Check if operation exists
if (api.operationExists('/users', 'get')) {
console.log('GET /users operation exists');
}
// Get operation details
const operationId = api.getOperationId('/users', 'get');
const description = api.getOperationDescription('/users', 'get');
// Get media types
const requestMedia = api.getOperationRequestMedia('/users', 'post');
const responseMedia = api.getOperationResponseMedia('/users', 'get');
// Get all HTTP methods used
const methods = api.getAllHttpMethods();
// Get all status codes used
const statusCodes = api.getAllStatusCodes();API Reference
Constructor
new Openapi(doc?: string | OpenAPIDocument)Creates a new OpenAPI document instance. If no document is provided, creates a minimal valid structure.
Properties
info: InfoObject- API informationservers: ServerObject[]- Server configurationspaths: PathsObject- API paths and operationscomponents: ComponentsObject- Reusable componentstags: TagObject[]- API tagsrootExtensions: Record<string, any>- Root-level extensionsinfoExtensions: Record<string, any>- Info-level extensionspathsExtensions: Record<string, any>- Paths-level extensions
Methods
Document Operations
getDefinition(format: 'js' | 'json' | 'prettyjson'): any- Get document in specified formatvalidate(): ValidationResult- Validate document structuregetDocument(): OpenAPIDocument- Get raw document object
Path Operations
getPathNames(): string[]- Get all path namesgetPath(path: string): PathItemObject- Get path itemappendPath(path: string, pathItem: PathItemObject): void- Add new path
Operation Operations
operationExists(path: string, method: string): boolean- Check if operation existsgetOperationId(path: string, method: string): string- Get operation IDgetOperationIds(): Array<{id: string, path: string, method: string}>- Get all operation IDsgetOperationDescription(path: string, method: string): string- Get operation descriptiongetOperationRequestMedia(path: string, method: string): string[]- Get request media typesgetOperationResponseMedia(path: string, method: string): string[]- Get response media types
Sample Generation Methods
generateJsonSample(path: string, verb: string, type: 'request' | 'response'): unknown- Generate sample JSON from schemagetCurlCommands(path: string, verb: string): Array<{command: string, description: string}>- Generate curl commandsgetPythonCode(path: string, verb: string): string- Generate Python code samplegetJavaScriptCode(path: string, verb: string, useAsync?: boolean): string- Generate JavaScript code samplegetTypeScriptCode(path: string, verb: string): string- Generate TypeScript code with interfaces
Utility Methods
getAllHttpMethods(): string[]- Get all HTTP methods usedgetAllStatusCodes(): string[]- Get all status codes usedgetStatusCodes(path: string, method: string): Array<{code: string, reason: string}>- Get status codes for operation
TypeScript Support
This library is written in TypeScript and provides comprehensive type definitions:
import type {
OpenAPIDocument,
InfoObject,
PathItemObject,
OperationObject,
SchemaObject,
ComponentsObject,
} from '@laag/openapi';Browser Support
The library works in modern browsers with ES2020 support:
<script type="module">
import { Openapi } from 'https://unpkg.com/@laag/openapi/dist/browser/index.js';
const api = new Openapi({
openapi: '3.0.2',
info: { title: 'Browser API', version: '1.0.0' },
paths: {},
});
</script>Examples
Check out the examples directory for more comprehensive examples:
- Basic Usage - Fundamental operations
- Advanced Operations - Complex document manipulation
- Browser Usage - Browser integration examples
- CommonJS Usage - CommonJS examples
Related Packages
- @laag/core - Core utilities and base classes
- @laag/cli - Command-line interface
- @laag/raml - RAML document support (coming soon)
License
MIT - see LICENSE for details.
