CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-swagger-client

SwaggerJS - a collection of interfaces for OAI specs

Pending
Overview
Eval results
Files

resolution.mddocs/

Spec Resolution and Processing

Resolve OpenAPI specifications with reference handling, validation, and normalization across different spec versions.

Capabilities

Resolve Function

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
});

Custom Resolver Creation

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
});

Resolution Strategies

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"
});

Subtree Resolution

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"]
);

Reference Resolution

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 });

Path Discrimination

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"
  ]
});

Normalization Control

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
});

Resolution Errors

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 errors

Cache Management

Manage 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 Resolution Options

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
});

Common Types

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

docs

client-construction.md

execution.md

helpers.md

http-client.md

index.md

request-building.md

resolution.md

tile.json