This document provides comprehensive guidance for AI assistants working on the swagger-js (swagger-client) codebase.
swagger-js (npm package: swagger-client) is a JavaScript module that allows you to fetch, resolve, and interact with Swagger/OpenAPI documents. It supports:
- OpenAPI 3.2.0 (latest)
- OpenAPI 3.1.0
- OpenAPI 3.0.x (3.0.0 through 3.0.4)
- Swagger/OpenAPI 2.0
- Legacy Swagger 1.x (via version 2.x branch)
Current Version: 3.36.0
The library is used by Swagger-UI and other tools in the OpenAPI ecosystem to parse, resolve references, and execute operations defined in OpenAPI specifications.
swagger-js/
├── src/ # Source code (ES6+ modules)
│ ├── execute/ # Request execution logic for OAS operations
│ │ ├── oas3/ # OpenAPI 3.x execution
│ │ └── swagger2/ # Swagger 2.0 execution
│ ├── helpers/ # Utility functions and helpers
│ ├── http/ # HTTP client implementation
│ │ └── serializers/ # Request/response serialization
│ ├── resolver/ # Spec resolution and $ref handling
│ │ ├── apidom/ # ApiDOM-based resolution (OAS 3.1)
│ │ ├── specmap/ # Legacy spec resolution engine
│ │ └── strategies/ # Version-specific resolution strategies
│ ├── subtree-resolver/ # Partial spec resolution
│ ├── index.js # Main entry point
│ ├── interfaces.js # Tags interface generation
│ ├── constants.js # Global constants
│ └── commonjs.js # CommonJS entry point
├── test/ # Test suite
│ ├── bugs/ # Bug reproduction tests
│ ├── data/ # Test fixtures and sample specs
│ ├── execute/ # Execution tests
│ ├── helpers/ # Helper function tests
│ ├── http/ # HTTP client tests
│ ├── oas3/ # OpenAPI 3.x specific tests
│ ├── swagger2/ # Swagger 2.0 specific tests
│ ├── resolver/ # Resolution tests
│ └── build-artifacts/ # Build output verification tests
├── config/ # Build and test configuration
│ ├── jest/ # Jest test configurations
│ └── webpack/ # Webpack build configurations
├── docs/ # Documentation
│ ├── usage/ # Usage documentation
│ ├── development/ # Development guides
│ └── migration/ # Migration guides
├── lib/ # Built CommonJS output (gitignored)
├── es/ # Built ES modules output (gitignored)
├── dist/ # Built browser UMD bundle (gitignored)
└── .github/ # GitHub configuration
└── workflows/ # CI/CD workflows
- Language: JavaScript (ES6+)
- Build Tools: Babel, Webpack
- Test Framework: Jest
- Module Formats: CommonJS, ES Modules, UMD (browser)
- @swagger-api/apidom-*: ApiDOM suite for OpenAPI 3.1 parsing and resolution
- ramda: Functional programming utilities
- js-yaml: YAML parsing
- deepmerge: Deep object merging
- fast-json-patch: JSON Patch operations
- node-fetch-commonjs: Fetch polyfill for Node.js
- openapi-path-templating: Path parameter templating
- openapi-server-url-templating: Server URL templating
- eslint: Code linting (Airbnb base config)
- prettier: Code formatting
- commitlint: Commit message validation
- husky: Git hooks
- lint-staged: Pre-commit linting
The project uses Babel for transpilation and Webpack for browser bundling.
-
UMD Browser Bundle (
dist/swagger-client.browser.min.js)- For
<script>tag inclusion - Includes all polyfills
- Minified and source-mapped
- For
-
CommonJS (
lib/)- ES5 code with CommonJS
require/module.exports - For Node.js and older bundlers
- ES5 code with CommonJS
-
ES Modules (
es/)- ES5 code with ES6
import/export - For modern bundlers and tree-shaking
- ES5 code with ES6
The project uses environment-specific Babel configurations (see babel.config.js):
BABEL_ENV=commonjs: CommonJS outputBABEL_ENV=es: ES modules outputBABEL_ENV=browser: Browser UMD bundle
The project uses conditional imports for platform-specific code:
btoa.node.jsvsbtoa.browser.jsfetch-polyfill.node.jsvsfetch-polyfill.browser.jsabortcontroller-polyfill.node.jsvsabortcontroller-polyfill.browser.js
These are configured in package.json under the browser field.
# Use correct Node.js version (see .nvmrc)
nvm use
# Install dependencies
npm install
# Build all targets
npm run build
# Run tests
npm test- Development: Node.js >= 22.11.0, npm >= 10.9.0
- Runtime Support: Node.js >= 12.20.0
- Note: EOL Node.js versions may be dropped without major version bump
npm run lint: Check for linting errorsnpm run lint:fix: Auto-fix linting errorsnpm run build: Build all targets (UMD, CommonJS, ES)npm run build:umd:browser: Build browser bundle onlynpm run build:commonjs: Build CommonJS onlynpm run build:es: Build ES modules onlynpm test: Run all tests (unit + artifact tests)npm run test:unit: Run unit testsnpm run test:unit:watch: Run tests in watch modenpm run test:unit:coverage: Run tests with coveragenpm run test:artifact: Test build outputsnpm run clean: Remove all build outputsnpm run analyze:umd:browser: Analyze browser bundle size
The project uses Husky for Git hooks:
- pre-commit: Runs
lint-stagedto lint and format staged files - commit-msg: Validates commit message format with commitlint
Follows Conventional Commits:
<type>(<scope>): <subject>
<body>
<footer>
Rules (from .commitlintrc.json):
- Max header length: 69 characters
- Type: Required (e.g., feat, fix, docs, test, chore, refactor)
- Scope: Optional, camelCase/kebab-case/UPPER_CASE
- Subject: Required, any case
Examples:
feat(resolver): add support for OpenAPI 3.1 webhooks
fix(http): handle empty response bodies correctly
docs(README): update installation instructions
test(execute): add test for parameter serialization
chore(deps): bump @swagger-api/apidom-core to 1.0.0
- Unit Tests: Test individual functions and modules
- Artifact Tests: Verify that built outputs work correctly
- Integration Tests: Test full workflows (resolve → execute)
Multiple Jest configs for different test scenarios:
jest.unit.config.js: Fast unit testsjest.unit.coverage.config.js: Unit tests with coverage reportingjest.artifact-umd-browser.config.js: Test browser UMD bundlejest.artifact-commonjs.config.js: Test CommonJS buildjest.artifact-es.config.js: Test ES modules build
- Test files mirror source structure:
src/foo/bar.js→test/foo/bar.js - Use descriptive test names
- Mock external dependencies (HTTP requests, file system)
- Use fixture files in
test/data/for OpenAPI specs
# Run specific test file
npm run test:unit -- path/to/test.js
# Run tests matching pattern
npm run test:unit -- --testNamePattern="resolver"
# Run with coverage
npm run test:unit:coverage- Base Config: Airbnb JavaScript Style Guide
- Parser: @babel/eslint-parser
- Extensions: Prettier integration
- Import Order: Grouped and sorted (builtin/external/internal, then parent/sibling/index)
- Import Extensions: Always include
.jsextension in imports - No Param Reassign: Temporarily disabled (marked for future fix)
- No Use Before Define: Functions only (marked for future fix)
From .prettierrc:
{
"printWidth": 100,
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"trailingComma": "es5"
}-
Imports: Always use
.jsextensionsimport foo from './foo.js'; // ✓ Correct import foo from './foo'; // ✗ Wrong
-
Import Groups: Maintain separation between external and internal imports
// External dependencies import ramda from 'ramda'; import yaml from 'js-yaml'; // Internal modules import { makeHttp } from './http/index.js'; import { opId } from './helpers/index.js';
-
Exports: Use named exports, default export for main entry
// Named exports export const resolve = () => {}; export const execute = () => {}; // Default export for main module export default Swagger;
-
Async/Await: Prefer async/await over raw Promises
// ✓ Preferred async function resolve(spec) { const result = await http.fetch(spec.url); return result; } // ✗ Avoid (unless chaining is cleaner) function resolve(spec) { return http.fetch(spec.url).then(result => result); }
src/index.js exports the main Swagger constructor function with attached methods:
Swagger(): Main constructor, returns a promiseSwagger.resolve(): Resolve an OpenAPI spec (handle $refs, normalize)Swagger.execute(): Execute an operationSwagger.buildRequest(): Build a request object without executingSwagger.http: HTTP clientSwagger.helpers: Helper utilities
Handles $ref resolution and spec normalization. Uses different strategies based on OpenAPI version:
Resolution Strategies:
openapi-3-2-apidom: Uses ApiDOM library for OpenAPI 3.2 (most modern)openapi-3-1-apidom: Uses ApiDOM library for OpenAPI 3.1openapi-3-0: Custom resolver for OpenAPI 3.0.xopenapi-2-0: Custom resolver for Swagger 2.0generic: Fallback for unknown specs
Strategy Selection (in src/resolver/index.js):
Strategies are tried in order until one matches. ApiDOM is preferred for OAS 3.1.
SpecMap (src/resolver/specmap/):
Legacy resolution engine used by non-ApiDOM strategies. Handles:
$refresolutionallOfmerging- Parameter normalization
- Property resolution
Builds and executes HTTP requests based on OpenAPI operations.
Version-Specific Logic:
execute/swagger2/: Swagger 2.0 parameter handling, securityexecute/oas3/: OpenAPI 3.x parameter styles, security, requestBody
Key Functions:
execute(): Full execution (build + send request)buildRequest(): Build request object onlybaseUrl(): Determine base URL from spec
Abstraction over fetch API with interceptors.
Features:
- Request/response interceptors
- Automatic serialization
- Cookie handling
- Abort controller support
Serializers (src/http/serializers/):
- Request serializers: body, headers, query parameters
- Response serializers: parse response, extract headers
Generates convenient tag-based and operationId-based interfaces:
const client = await Swagger('https://petstore.swagger.io/v2/swagger.json');
// Tag-based interface
client.apis.pet.addPet({ body: petData });
// OperationId-based interface
client.apis.addPet({ body: petData });Multiple resolution strategies that implement a common interface:
{
match: (spec) => boolean, // Can this strategy handle this spec?
resolve: (options) => Promise, // Resolve the spec
}Request and response interceptors for customization:
const client = await Swagger({
url: 'https://api.example.com/spec.json',
requestInterceptor: (req) => {
req.headers.Authorization = 'Bearer token';
return req;
},
responseInterceptor: (res) => {
console.log('Response:', res);
return res;
},
});Platform-specific imports configured in package.json:
// In source code
import btoa from './helpers/btoa.node.js';
// In browser, webpack resolves to
import btoa from './helpers/btoa.browser.js';- Identify the OpenAPI version (2.0, 3.0, 3.1, 3.2)
- Update the appropriate resolver strategy:
- OAS 3.2:
src/resolver/strategies/openapi-3-2-apidom/ - OAS 3.1:
src/resolver/strategies/openapi-3-1-apidom/ - OAS 3.0:
src/resolver/strategies/openapi-3-0/ - OAS 2.0:
src/resolver/strategies/openapi-2/
- OAS 3.2:
- Update execution logic if feature affects operations:
src/execute/oas3/orsrc/execute/swagger2/
- Add tests in corresponding test directory
- Update documentation in
docs/
- Write a failing test in
test/bugs/that reproduces the issue - Identify the affected module
- Fix the bug in source code
- Verify the test passes
- Run full test suite:
npm test - Check linting:
npm run lint - Commit with proper format:
fix(module): description
- Install dependency:
npm install <package> - Update imports with
.jsextension - Consider browser compatibility
- Update
package.jsonbrowser field if needed for polyfills - Test all build targets:
npm run test:artifact - Check bundle size:
npm run analyze:umd:browser
- Run tests first:
npm test(ensure baseline) - Make incremental changes
- Run tests after each change
- Update imports if moving files
- Check for breaking changes in public API
- Run lint:
npm run lint:fix - Commit with:
refactor(module): description
File: .github/workflows/nodejs.yml
Main Build Job (runs on Node.js 16, 18, 20, 22):
- Checkout code
- Setup Node.js
- Cache node_modules
- Install dependencies (
npm ci) - Lint commit message (commitlint)
- Lint code (
npm run lint) - Run tests (
npm test) - Build (
npm run build) - Upload build artifacts (Node 22 only)
Artifact Test Job: Tests CommonJS build on multiple Node.js versions (12.20.0, 14.x, 16.x, 18.x, 20.x, 22.x)
Other Workflows:
codeql.yml: Security analysis with CodeQLrelease.yml: Automated releasesdependabot-merge.yml: Auto-merge Dependabot PRs
All PRs must pass:
- ✓ Linting (ESLint)
- ✓ Commit message format (commitlint)
- ✓ Unit tests
- ✓ Artifact tests
- ✓ Build succeeds
package.json: Dependencies, scripts, build config, browser fieldbabel.config.js: Babel transpilation config (multi-environment).eslintrc.js: ESLint rules.prettierrc: Prettier formatting rules.commitlintrc.json: Commit message validation.browserslistrc: Browser targets for Babel.editorconfig: Editor settings.nvmrc: Node.js version (22).lintstagedrc: Lint-staged configuration
src/index.js: Main entry point, Swagger constructorsrc/commonjs.js: CommonJS entry pointsrc/constants.js: Global constants (e.g., DEFAULT_OPENAPI_3_SERVER)src/interfaces.js: Tag and operationId interface generationsrc/resolver/index.js: Resolver factory, strategy selectionsrc/execute/index.js: Execution enginesrc/http/index.js: HTTP client
README.md: Project overview, installation, basic usagedocs/usage/: User-facing documentationdocs/development/: Developer guidesdocs/migration/: Migration guides between versions
lib/: CommonJS buildes/: ES modules builddist/: Browser UMD bundlecoverage/: Test coverage reports
- Check OpenAPI version context: Different logic for 2.0 vs 3.0 vs 3.1
- Understand resolution vs execution: Separate concerns
- Look for version-specific paths:
swagger2/vsoas3/directories - Check for browser polyfills: Platform-specific imports
- Always run tests:
npm testbefore and after changes - Check all build targets: UMD, CommonJS, and ES modules
- Maintain import conventions: Include
.jsextensions - Follow existing patterns: Especially for strategy implementations
- Update tests: Add tests for new functionality
- Check browser compatibility: Test UMD bundle if affecting browser code
- Lint before committing:
npm run lint:fix
- Check resolver strategy: Which strategy is handling the spec?
- Inspect intermediate state: Look at resolved spec before execution
- Review test fixtures:
test/data/has example specs - Use unit tests: Write minimal reproduction in test
- Check HTTP layer: Use requestInterceptor to debug requests
- Use descriptive names:
test('should resolve $ref in parameters', ...) - Isolate tests: Mock HTTP, file system
- Use fixtures: Reuse specs from
test/data/ - Test edge cases: Empty specs, missing fields, invalid refs
- Check multiple OAS versions: Test 2.0, 3.0, and 3.1 if applicable
- Forgetting
.jsextensions: Will fail ESLint - Breaking browser builds: Test with
npm run test:artifact:umd:browser - Mutating parameters: Avoid (see ESLint rules)
- Missing import grouping: ESLint enforces order
- Commit message format: Use conventional commits
- Not testing all Node versions: CI tests 16, 18, 20, 22
-
swagger-ui: Main consumer of this library
- Repo: https://github.com/swagger-api/swagger-ui
- Link testing instructions:
docs/development/setting-up.md
-
@swagger-api/apidom: ApiDOM suite for OpenAPI 3.1
- Used by
openapi-3-1-apidomresolver strategy - Multiple packages: core, reference, parsers, etc.
- Used by
- Report security issues to: security@swagger.io
- Do not use public issue tracker for security vulnerabilities
- See
.github/SECURITY.mdfor details
Apache 2.0 (see LICENSE file)
See package.json contributors list and GitHub contributors page.
Last Updated: 2026-01-22 swagger-client Version: 3.36.0 Node.js Version: 22.11.0+