SwaggerJS - a collection of interfaces for OAI specs
—
Resolve OpenAPI specifications with reference handling, validation, and normalization across different spec versions.
Resolve OpenAPI specifications with automatic reference resolution and validation.
/**
* Resolve an OpenAPI specification
* @param options - Resolution configuration options
* @returns Promise resolving to resolution result
*/
function resolve(options: ResolveOptions): Promise<ResolutionResult>;
interface ResolveOptions {
/** OpenAPI specification object to resolve */
spec?: object;
/** URL to fetch specification from */
url?: string;
/** Custom HTTP client for fetching external references */
http?: HttpClient;
/** Legacy fetch function (use userFetch instead) */
fetch?: FetchFunction;
/** Custom fetch implementation */
userFetch?: FetchFunction;
/** Allow patching of meta patches during resolution */
allowMetaPatches?: boolean;
/** Use circular structures in resolved spec */
useCircularStructures?: boolean;
/** Function to intercept and modify requests */
requestInterceptor?: RequestInterceptor;
/** Function to intercept and modify responses */
responseInterceptor?: ResponseInterceptor;
/** Skip normalization of the resolved specification */
skipNormalization?: boolean;
/** Array of path segments to discriminate during resolution */
pathDiscriminator?: string[];
/** Resolution strategies to use */
strategies?: ResolveStrategy[];
}
interface ResolutionResult {
/** Resolved OpenAPI specification */
spec: object;
/** Errors encountered during resolution */
errors: ResolutionError[];
}
interface ResolutionError {
/** Error message */
message: string;
/** Full path where error occurred */
fullPath: string[];
}Usage Examples:
import { resolve } from "swagger-client";
// Resolve from URL
const result = await resolve({
url: "https://petstore.swagger.io/v2/swagger.json"
});
console.log("Resolved spec:", result.spec);
console.log("Resolution errors:", result.errors);
// Resolve spec object with external references
const result = await resolve({
spec: {
openapi: "3.0.0",
info: { title: "API", version: "1.0.0" },
paths: {
"/users": {
"$ref": "https://api.example.com/paths/users.json"
}
}
}
});
// Resolve with custom HTTP client
const result = await resolve({
url: "https://api.example.com/openapi.json",
http: customHttpClient
});
// Resolve with request interceptor for authentication
const result = await resolve({
url: "https://api.example.com/openapi.json",
requestInterceptor: (req) => {
req.headers.Authorization = "Bearer token";
return req;
}
});
// Resolve with circular structure support
const result = await resolve({
spec: specWithCircularRefs,
useCircularStructures: true
});Create custom resolvers with specific strategies and default options.
/**
* Create a custom resolver function with default options
* @param defaultOptions - Default options for resolution
* @returns Custom resolver function
*/
function makeResolve(defaultOptions: ResolveOptions): (options: ResolveOptions) => Promise<ResolutionResult>;makeResolve Examples:
import { makeResolve } from "swagger-client";
// Create resolver with authentication defaults
const authenticatedResolve = makeResolve({
requestInterceptor: (req) => {
req.headers.Authorization = "Bearer " + getToken();
return req;
}
});
// Use the custom resolver
const result = await authenticatedResolve({
url: "https://api.example.com/openapi.json"
});
// Create resolver with custom strategies
const customResolve = makeResolve({
strategies: [
strategies["openapi-3-1-apidom"],
strategies["openapi-3-0"]
],
allowMetaPatches: true
});Different strategies for resolving different OpenAPI specification versions.
interface ResolveStrategy {
/** Check if this strategy can handle the given spec */
match(spec: object): boolean;
/** Normalize the specification */
normalize(spec: object): object;
/** Resolve the specification */
resolve(options: ResolveOptions): Promise<ResolutionResult>;
}
// Available strategies
const strategies = {
"openapi-3-1-apidom": OpenApi31ApiDOMStrategy,
"openapi-3-0": OpenApi30Strategy,
"openapi-2-0": OpenApi2Strategy,
"generic": GenericStrategy
};Strategy Examples:
import { makeResolve } from "swagger-client";
// Create resolver with custom strategies
const customResolve = makeResolve({
strategies: [
strategies["openapi-3-1-apidom"],
strategies["openapi-3-0"],
strategies["generic"]
]
});
const result = await customResolve({
url: "https://api.example.com/openapi.json"
});Resolve specific parts of a specification for performance optimization.
/**
* Resolve a subtree of an OpenAPI specification
* @param obj - OpenAPI specification object
* @param path - Array path to the subtree to resolve
* @param options - Resolution options
* @returns Promise resolving to resolution result
*/
function resolveSubtree(obj: object, path: string[], options?: SubtreeOptions): Promise<ResolutionResult>;
/**
* Create a custom subtree resolver with default options
* @param defaultOptions - Default options for subtree resolution
* @returns Custom subtree resolver function
*/
function makeResolveSubtree(defaultOptions: SubtreeOptions): (obj: object, path: string[], options?: SubtreeOptions) => Promise<ResolutionResult>;
interface SubtreeOptions {
/** Return entire tree instead of just the subtree */
returnEntireTree?: boolean;
/** Base document for resolution context */
baseDoc?: object;
/** Function to intercept requests */
requestInterceptor?: RequestInterceptor;
/** Function to intercept responses */
responseInterceptor?: ResponseInterceptor;
/** Parameter macro function */
parameterMacro?: Function;
/** Model property macro function */
modelPropertyMacro?: Function;
/** Use circular structures in resolution */
useCircularStructures?: boolean;
/** Resolution strategies to use */
strategies?: ResolveStrategy[];
}Subtree Examples:
import { resolveSubtree, makeResolveSubtree } from "swagger-client";
// Resolve only specific paths
const result = await resolveSubtree(
openApiSpec,
["paths", "/users", "get"]
);
// Resolve only components section
const result = await resolveSubtree(
openApiSpec,
["components", "schemas"]
);
// Return entire tree with specific subtree resolved
const result = await resolveSubtree(
openApiSpec,
["paths", "/users"],
{ returnEntireTree: true }
);
// Create custom subtree resolver
const customSubtreeResolve = makeResolveSubtree({
useCircularStructures: true,
requestInterceptor: (req) => {
req.headers.Authorization = "Bearer " + getToken();
return req;
}
});
const result = await customSubtreeResolve(
openApiSpec,
["components", "schemas", "User"]
);Handle JSON Schema references ($ref) in OpenAPI specifications.
// External reference resolution
const spec = {
openapi: "3.0.0",
info: { title: "API", version: "1.0.0" },
components: {
schemas: {
User: {
"$ref": "https://api.example.com/schemas/user.json"
}
}
}
};
const result = await resolve({ spec });
// Internal reference resolution
const spec = {
openapi: "3.0.0",
info: { title: "API", version: "1.0.0" },
paths: {
"/users": {
get: {
responses: {
"200": {
content: {
"application/json": {
schema: { "$ref": "#/components/schemas/User" }
}
}
}
}
}
}
},
components: {
schemas: {
User: {
type: "object",
properties: {
id: { type: "integer" },
name: { type: "string" }
}
}
}
}
};
const result = await resolve({ spec });Filter resolution to specific paths for performance and security.
// Resolve only specific operation paths
const result = await resolve({
spec: openApiSpec,
pathDiscriminator: ["paths", "/users", "get"]
});
// Multiple path discrimination
const result = await resolve({
spec: openApiSpec,
pathDiscriminator: [
"paths./users.get",
"paths./users.post",
"components.schemas.User"
]
});Control specification normalization during resolution.
// Skip normalization for raw spec access
const result = await resolve({
spec: openApiSpec,
skipNormalization: true
});
// Allow meta patches for spec correction
const result = await resolve({
spec: openApiSpec,
allowMetaPatches: true
});Handle and process resolution errors.
interface ResolutionError {
/** Human-readable error message */
message: string;
/** Array representing the JSON path where error occurred */
fullPath: string[];
}
// Example error handling
const result = await resolve({
url: "https://api.example.com/broken-spec.json"
});
if (result.errors.length > 0) {
result.errors.forEach(error => {
console.error(`Error at ${error.fullPath.join('.')}: ${error.message}`);
});
}
// Common error types:
// - Reference resolution failures
// - Invalid JSON/YAML syntax
// - Network errors when fetching external refs
// - Circular reference detection
// - Schema validation errorsManage resolution caches for performance optimization.
/**
* Clear all resolution caches
*/
function clearCache(): void;
// Usage
import { clearCache } from "swagger-client";
// Clear caches to free memory or force re-resolution
clearCache();Advanced configuration for complex resolution scenarios.
// Custom HTTP configuration
const result = await resolve({
url: "https://api.example.com/openapi.json",
http: {
withCredentials: true,
timeout: 30000
}
});
// Response interceptor for custom processing
const result = await resolve({
url: "https://api.example.com/openapi.json",
responseInterceptor: (response) => {
if (response.headers["content-type"].includes("text/plain")) {
// Convert plain text to JSON
response.body = JSON.parse(response.text);
}
return response;
}
});
// Circular structure handling
const result = await resolve({
spec: {
openapi: "3.0.0",
info: { title: "API", version: "1.0.0" },
components: {
schemas: {
Node: {
type: "object",
properties: {
value: { type: "string" },
children: {
type: "array",
items: { "$ref": "#/components/schemas/Node" }
}
}
}
}
}
},
useCircularStructures: true
});interface HttpClient {
(url: string, options?: HttpOptions): Promise<ResponseObject>;
withCredentials?: boolean;
timeout?: number;
}
interface FetchFunction {
(url: string, options?: RequestInit): Promise<Response>;
}
interface RequestInterceptor {
(request: RequestObject): RequestObject | Promise<RequestObject>;
}
interface ResponseInterceptor {
(response: ResponseObject): ResponseObject | Promise<ResponseObject>;
}
interface ResponseObject {
url: string;
status: number;
statusText: string;
headers: Record<string, string>;
text: string;
body: any;
ok: boolean;
}
interface RequestObject {
url: string;
method: string;
headers: Record<string, string>;
body?: any;
}Install with Tessl CLI
npx tessl i tessl/npm-swagger-client