OpenAPI AnyEnv Suite is a toolkit to validate, grade, and generate HTML/JSON reports for OpenAPI specifications.
Overview
- Canonical entrypoints:
pnpm run check— validate and grade a specpnpm run report:static— generate the static HTML report (writes dist/index.html)
Requirements
- Node.js: Use Node 22.12.0+ for CLI/tools (Redocly v2 compatible). Release automation (semantic-release v25) still requires Node >= 24.10.0; prefer 24.10.0+ in release workflows.
- pnpm (Corepack supported)
Schema linting
- Redocly schema lint is optional and enabled with
SCHEMA_LINT=1. When Redocly is not available the tool falls back to the built-in bundler sopnpm run checkworks without external services.
Quick install (local)
pnpm install --frozen-lockfileUsage
Direct CLI (no install)
# Using pnpm dlx
pnpm dlx @zoomiit/openapi-anyenv-suite openapi-grade -- path/to/openapi.yaml [--no-bundle] [--soft] [--docs]
# Using npx (npm >= 7)
npx -y @zoomiit/openapi-anyenv-suite openapi-grade -- path/to/openapi.yaml
# Windows PowerShell example
pnpm dlx @zoomiit/openapi-anyenv-suite openapi-grade -- "C:\\path\\to\\openapi.yaml"Render docs from an existing bundle (npx/pnpm)
# Using npx (avoids multiple-bin prompt)
npx -y @redocly/cli@2.8.0 redocly build-docs dist/bundled.json --output dist/docs.html
# Using pnpm dlx (must specify the binary name)
pnpm --package=@redocly/cli@2.8.0 dlx redocly build-docs dist/bundled.json --output dist/docs.html
# Fallback (classic redoc-cli)
npx -y redoc-cli bundle dist/bundled.json -o dist/docs.htmlPowerShell examples
# Run grader (PowerShell) with a quoted path
pnpm dlx @zoomiit/openapi-anyenv-suite openapi-grade -- "C:\path\to\openapi.yaml"
# Build docs from an existing bundle with npx (PowerShell)
npx -y @redocly/cli@2.8.0 redocly build-docs "C:\path\to\dist\bundled.json" --output "C:\path\to\dist\docs.html"
# Build docs from an existing bundle with pnpm dlx (PowerShell)
pnpm --package=@redocly/cli@2.8.0 dlx redocly build-docs "C:\path\to\dist\bundled.json" --output "C:\path\to\dist\docs.html"Linux/macOS bash examples
# Run grader (bash)
pnpm dlx @zoomiit/openapi-anyenv-suite openapi-grade -- path/to/openapi.yaml
# Build docs from an existing bundle with npx (bash)
npx -y @redocly/cli@2.8.0 redocly build-docs dist/bundled.json --output dist/docs.html
# Build docs from an existing bundle with pnpm dlx (bash)
pnpm --package=@redocly/cli@2.8.0 dlx redocly build-docs dist/bundled.json --output dist/docs.htmlBuild Swagger UI from an existing bundle
# Bash (Linux/macOS): create dist/swagger.html pointing to dist/bundled.json
mkdir -p dist
cat > dist/swagger.html << 'HTML'
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Swagger UI</title>
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@4/swagger-ui.css" />
</head>
<body style="margin:0;padding:0">
<div id="swagger"></div>
<script src="https://unpkg.com/swagger-ui-dist@4/swagger-ui-bundle.js"></script>
<script>
SwaggerUIBundle({ url: 'bundled.json', dom_id: '#swagger' });
</script>
</body>
</html>
HTML# PowerShell (Windows): create dist/swagger.html pointing to dist/bundled.json
New-Item -ItemType Directory -Force -Path dist | Out-Null
@'
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Swagger UI</title>
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@4/swagger-ui.css" />
</head>
<body style="margin:0;padding:0">
<div id="swagger"></div>
<script src="https://unpkg.com/swagger-ui-dist@4/swagger-ui-bundle.js"></script>
<script>
SwaggerUIBundle({ url: 'bundled.json', dom_id: '#swagger' });
</script>
</body>
</html>
'@ | Set-Content -Path dist/swagger.html -Encoding UTF8Notes (npx/pnpm)
- With pnpm dlx, packages exposing multiple binaries (like @redocly/cli) require specifying the binary
name (use
redoclyoropenapi). - Redocly CLI engines: Node >= 22.12.0 or >= 20.19.0 < 21. Ensure your Node version satisfies this requirement to avoid engine warnings.
What gets generated
openapi-graderendersdist/index.htmlusing the bundled HTML template (no extra setup), even when run viadlx/npx.- When
--docsis provided, it tries to builddist/docs.htmlwith Redocly; if unavailable, it creates a minimaldocs.htmlandswagger.htmlthat consumedist/bundled.jsonso links always work. dist/grade-report.jsonis always written;dist/grade-report.htmlis also written as a legacy copy ofindex.htmlfor compatibility.
```bash
# Validate + grade (and optionally generate docs)
pnpm run check -- path/to/openapi.yaml [--no-bundle] [--soft] [--docs]
# Generate the static HTML report
pnpm run report:static -- path/to/openapi.yaml
# Preview the generated site
pnpm run serve:dist # opens a preview of dist/ on http://127.0.0.1:5173/index.html
Outputs
dist/grade-report.json- machine-readable grading resultdist/index.html- human-friendly HTML report (templated)dist/docs.html- API docs (Redocly when available, otherwise a lightweight fallback that consumesbundled.json)dist/swagger.html- Swagger UI fallback (consumesbundled.json)
Docs generation behavior
- Pass
--docsto request docs pages. If Redocly is available, it buildsdocs.html. - When bundling fails, the tool skips docs/swagger by default to avoid misleading outputs.
- Force fallback docs even on bundle errors with:
- Flag:
--docs-force - Env:
DOCS_FORCE=1This creates lightweightdocs.htmlandswagger.htmlthat render whatever is indist/bundled.json(including the minimal stub when applicable).
- Flag:
Branding
Set REPORT_LOGO or GRADE_LOGO_URL to show a custom logo in the report (supports http(s) URLs or local paths). Local file paths are embedded as data-URLs.
Grading model
The grading model is driven by grade.config.json in the repository root. If this file is missing, the packaged grade.config.json bundled with the tool is used automatically. If that is not available, built‑in defaults apply. See that file for penalties, bonuses and grade thresholds.
Spectral rules
Local rule packs live under rules/. The root .spectral.yaml extends spectral:oas and the included packs.
Docker
Build the image (BuildKit recommended):
export DOCKER_BUILDKIT=1
docker build -t openapi-tools .On Windows PowerShell:
$env:DOCKER_BUILDKIT=1
docker build -t openapi-tools .Prebuilt images are published to GHCR and are tagged by version and latest. To customize grading in Docker, mount your grade.config.json into /work/grade.config.json.
Example: run validation inside the official image
docker run --rm \
-v "$PWD/path/to:/spec:ro" \
-v "$PWD/dist:/work/dist" \
-v "$PWD/grade.config.json:/work/grade.config.json:ro" \
ghcr.io/ramongranda/openapi-anyenv-suite:v2.13.0 \
pnpm run check -- /spec/openapi.yamlCI (GitHub Actions / Jenkins)
Reusable workflows live in .github/workflows/. See docs/ for examples and integration notes.
Testing
This project uses Jest. Run tests locally with:
pnpm testContributing
See CONTRIBUTING.md for development guidelines and style rules. Run pnpm test and keep lint checks passing before opening PRs.
Repository layout
scripts/— Node scripts for bundling, validation, grading, and reportingrules/— Spectral rule packs and custom functions.spectral.yaml— root rulesetdist/— output folder for bundles and reports
Utilities
npm run doctor— prints Node/Spectral/Redocly versions
Docker: buildx / multi-arch
docker buildx create --name devbuilder --use
docker buildx inspect --bootstrap
docker buildx build -t openapi-tools . --load # use --push to publishImage tags
Images are tagged as v<package.json version> and latest. Prefer versioned tags for reproducibility.
Release process
- Branching:
developis the integration branch;mainis the release branch. - Use
release/*branches for pre-releases. Semantic-Release is the canonical publisher and runs on merges tomain.
Prerequisites for publishing
- Add
NPM_TOKENto repository secrets for npm publish. In some orgs you may also need a PAT for GHCR ifGITHUB_TOKENcannot write packages.
Local dry-run
npm publish --dry-runCI example (GitHub Actions)
name: API Lint
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '22' }
- run: pnpm ci
- run: pnpm run check -- path/to/openapi.yaml
- run: SCHEMA_LINT=1 pnpm run check -- path/to/openapi.yamlUseful notes
- When using npm scripts that accept a spec path, pass the path after
--to forward arguments correctly. - On Windows, if
node_modulesis locked: close editors/watchers, runnpx rimraf node_modules, and reinstall.
Further reading
See docs/ for CI examples, Docker usage, and the Jenkins pipeline sample.
Quick links
- Example spec:
example/openapi.yaml - Docs and examples:
docs/
If you prefer Spanish documentation, see docs/README.es.md.
*** End Patch pnpm dlx @zoomiit/openapi-anyenv-suite openapi-bundle path/to/openapi.yaml --out dist/bundled-openapi.yaml
Alternativa de instalación local:
```bash
pnpm add -D @zoomiit/openapi-anyenv-suite
# Ejecuta los binarios con pnpm dlx si lo necesitas
pnpm dlx @zoomiit/openapi-anyenv-suite openapi-grade -- path/to/openapi.yaml
Notas
- SCHEMA_LINT=1 incluye la verificación de esquema de Redocly en la validación/calificación.
- Los comandos CLI empaquetan internamente antes de la verificación para resolver $ref entre archivos.
- La API programática no está proporcionada; la interfaz recomendada es la CLI.
Notas:
validate:npx/bundle:npxactualmente fijan Redocly CLI 2.6.0.- Prefiere instalaciones locales para resultados completamente reproducibles.
make check path/to/openapi.yaml
SCHEMA_LINT=1 make check path/to/openapi.yaml
make report path/to/openapi.yaml
# variantes npx removedLa calificación es configurable a través del archivo grade.config.json. Si este archivo no existe, se utilizan valores predeterminados.
Al ejecutar los comandos npm y make localmente, el archivo grade.config.json se detecta y utiliza automáticamente si está presente en la raíz del proyecto.
El archivo grade.config.json tiene la siguiente estructura:
{
"penalties": {
"spectral": {
"error": 4,
"warning": 1,
"maxError": 40,
"maxWarning": 15
},
"redocly": {
"error": 5,
"warning": 2,
"maxError": 25,
"maxWarning": 10
}
},
"bonuses": {
"max": 20,
"rules": {
"info.title": 2,
"info.version": 2,
"servers": 1,
"summaryRatio": {
"threshold": 0.8,
"points": 5
},
"descriptionRatio": {
"threshold": 0.8,
"points": 5
},
"4xxRatio": {
"threshold": 0.7,
"points": 5
},
"securitySchemes": 3
}
},
"grades": {
"A": 90,
"B": 80,
"C": 65,
"D": 50
}
}La sección penalties define los puntos deducidos por cada error o advertencia de Spectral y Redocly.
error: Puntos deducidos por error.warning: Puntos deducidos por advertencia.maxError: Puntos máximos deducidos por errores.maxWarning: Puntos máximos deducidos por advertencias.
La sección bonuses define los puntos otorgados por cumplir con ciertas heurísticas.
max: Puntos máximos de bonificación otorgados.rules: Reglas para otorgar puntos.
La sección grades define los umbrales de puntuación para cada calificación.
A: Puntuación mínima para recibir una A.B: Puntuación mínima para recibir una B.C: Puntuación mínima para recibir una C.D: Puntuación mínima para recibir una D.
DEBUG_JSON=1escribe las salidas del linter sin procesar endist/debug-*.txtsi falla el análisis.
Conjunto de reglas principal: .spectral.yaml, extendiendo spectral:oas y paquetes de reglas locales:
rules/core.yaml— rutas/nombres, documentación, etiquetas, esquemasrules/business.yaml— manejo de errores, enums, nombres, cachérules/format.yaml— tipos de contenido, reglas de solicitud/respuesta, formatos de datosrules/pagination.yaml— límites de matriz y consistencia de paginaciónrules/security.yaml— HTTPS, auth, respuestas de seguridad, rangos numéricos
Funciones personalizadas (CommonJS) están bajo rules/functions/:
validateDateTimeFormat.js— hacer cumplirdate/date-timepara cadenas temporalesvalidatePropertyHasExample.js— sugerir ejemplos en propiedades importantesvalidateResponseHasExample.js— requerir ejemplos para respuestas 2xx (a menos que$ref)maxGteMin.js— validar la coherencia del rango numérico
Puedes ajustar o desactivar reglas directamente en los archivos YAML o .spectral.yaml.
-
Cambiar la gravedad en
.spectral.yaml(anula de los paquetes extendidos):rules: operation-description: error # era warn server-https: off # desactivar
-
Agregar una función personalizada:
- Coloca
rules/functions/myRule.jsy exporta una función(input, context) => issues|undefined. - Referénciala en
rules/*.yamlbajofunctions:y úsala enrules:. - Asegúrate de que
.spectral.yamlfunctionsDirapunte a./rules/functions.
- Coloca
-
Linux/WSL:
export DOCKER_BUILDKIT=1 docker build -t openapi-tools .
-
Windows PowerShell:
$env:DOCKER_BUILDKIT=1 docker build -t openapi-tools .
docker buildx create --name devbuilder --use
docker buildx inspect --bootstrap
docker buildx build -t openapi-tools . --load # usar --push para publicarLas extracciones públicas no requieren autenticación. Prefiere una etiqueta de versión para mayor claridad y reproducibilidad.
Para usar una configuración de calificación personalizada, monta tu archivo grade.config.json en /work/grade.config.json.
# Extraer (etiqueta de versión)
docker pull ghcr.io/ramongranda/openapi-anyenv-suite:v2.13.0
# O usa latest para una prueba rápida
docker pull ghcr.io/ramongranda/openapi-anyenv-suite:latest
# Validar (montar spec como solo lectura; salidas a ./dist)
docker run --rm \
-v "$PWD/path/to:/spec:ro" \
-v "$PWD/dist:/work/dist" \
-v "$PWD/grade.config.json:/work/grade.config.json:ro" \
ghcr.io/ramongranda/openapi-anyenv-suite:v2.13.0 \
pnpm run check -- /spec/openapi.yaml
# Validar con la verificación de esquema de Redocly
docker run --rm \
-e SCHEMA_LINT=1 \
-v "$PWD/path/to:/spec:ro" \
-v "$PWD/dist:/work/dist" \
-v "$PWD/grade.config.json:/work/grade.config.json:ro" \
ghcr.io/ramongranda/openapi-anyenv-suite:v2.13.0 \
pnpm run check -- /spec/openapi.yaml
# Calificar (reporte escrito en el host ./dist)
docker run --rm \
-v "$PWD/path/to:/spec:ro" \
-v "$PWD/dist:/work/dist" \
-v "$PWD/grade.config.json:/work/grade.config.json:ro" \
ghcr.io/ramongranda/openapi-anyenv-suite:v2.13.0 \
pnpm run check -- /spec/openapi.yaml
# Ver Reporte de Calificación (HTML)
docker run --rm -p 8080:8080 \
-v "$PWD/example:/spec:ro" \
-v "$PWD/dist:/work/dist" \
-v "$PWD/grade.config.json:/work/grade.config.json:ro" \
ghcr.io/ramongranda/openapi-anyenv-suite:v2.13.0 \
pnpm run report:static -- /spec/openapi.yamlNotas
- Las imágenes están etiquetadas como
v<package.json version>(recomendado) y también comolatest. - La etiqueta
v<version>se crea automáticamente en los aumentos de versión en package.json. Actual:v1.2.0.
Desde la raíz del repositorio, ejecuta contra example/openapi.yaml. Esto también utilizará el grade.config.json desde la raíz del repositorio.
# Validar
docker run --rm \
-v "$PWD/example:/spec:ro" \
-v "$PWD/dist:/work/dist" \
-v "$PWD/grade.config.json:/work/grade.config.json:ro" \
ghcr.io/ramongranda/openapi-anyenv-suite:v2.13.0 \
pnpm run check -- /spec/openapi.yaml
# Calificar (con verificación de esquema)
docker run --rm \
-e SCHEMA_LINT=1 \
-v "$PWD/example:/spec:ro" \
-v "$PWD/dist:/work/dist" \
-v "$PWD/grade.config.json:/work/grade.config.json:ro" \
ghcr.io/ramongranda/openapi-anyenv-suite:v2.13.0 \
pnpm run check -- /spec/openapi.yaml
Para usar una configuración de calificación personalizada, monta tu archivo grade.config.json en /work/grade.config.json.
# Validar (montar spec como solo lectura; salidas a ./dist)
docker run --rm \
-v "$PWD/path/to:/spec:ro" \
-v "$PWD/dist:/work/dist" \
-v "$PWD/grade.config.json:/work/grade.config.json:ro" \
openapi-tools \
pnpm run check -- /spec/openapi.yaml
# Con verificación de esquema
docker run --rm \
-e SCHEMA_LINT=1 \
-v "$PWD/path/to:/spec:ro" \
-v "$PWD/dist:/work/dist" \
-v "$PWD/grade.config.json:/work/grade.config.json:ro" \
openapi-tools \
pnpm run check -- /spec/openapi.yaml
# Calificar
docker run --rm \
-v "$PWD/path/to:/spec:ro" \
-v "$PWD/dist:/work/dist" \
-v "$PWD/grade.config.json:/work/grade.config.json:ro" \
openapi-tools \
pnpm run check -- /spec/openapi.yaml
# Ver Reporte de Calificación (HTML)
docker run --rm -p 8080:8080 \
-v "$PWD/path/to:/spec:ro" \
-v "$PWD/dist:/work/dist" \
-v "$PWD/grade.config.json:/work/grade.config.json:ro" \
openapi-tools \
pnpm run report:static -- /spec/openapi.yamlEjemplo de GitHub Actions para validación y calificación:
name: API Lint
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '22' }
- run: pnpm ci
- run: pnpm run check -- path/to/openapi.yaml
- run: SCHEMA_LINT=1 pnpm run check -- path/to/openapi.yaml-
Prerrequisitos
- Agregar el secreto del repositorio
NPM_TOKEN(token de automatización de npm). - Asegurarse de que
package.jsontengaprivate: falseypublishConfig.access: public(ya configurado).
- Agregar el secreto del repositorio
-
Publicación manual
- Actions → "Publish to npm" → Run workflow (usa el commit actual en la rama).
-
En etiqueta (recomendado)
- Crear una etiqueta
vX.Y.Z(hecho automáticamente en la fusión a master por auto‑version). - El flujo de trabajo publica el paquete en npm con la misma versión.
- Crear una etiqueta
-
Prueba en seco local (opcional)
npm publish --dry-runpara inspeccionar los archivos incluidos en el paquete.
scripts/- Scripts de Node para empaquetar, validar, calificar, reportarrules/— Paquetes de reglas de Spectral y funciones personalizadas.spectral.yaml— conjunto de reglas raíz que extiende paquetes localesdist/- carpeta de salida para paquetes y reportes
npm run doctor- imprime versiones de Node/Spectral/Redocly
Este proyecto usa Jest para pruebas unitarias. Las pruebas están ubicadas en el directorio test/.
Para ejecutar las pruebas, usa el siguiente comando:
npm testLas pruebas también se ejecutan automáticamente antes de cada commit usando un gancho pre-commit, y en cada push y pull request usando una Acción de GitHub.
- Siempre pasa la ruta de la especificación después de
--al usar scripts de npm. - En Windows, si
node_modulesestá bloqueado: cierra observadores/editores, ejecutanpx rimraf node_modules, y luego reinstala. - Usa Node 22.12.0+ para CLI y herramientas (compatible con Redocly v2). Para publicación, semantic-release requiere Node >= 24.10.0.
- Validar: usa
ramongranda/openapi-anyenv-suite/.github/workflows/openapi-validate.yml@master - Calificar: usa
ramongranda/openapi-anyenv-suite/.github/workflows/openapi-grade.yml@master - Docs: usa
ramongranda/openapi-anyenv-suite/.github/workflows/openapi-docs.yml@master
Consulta docs/CI.md para el uso completo, entradas y el ejemplo de pipeline de Jenkins.
- Ramificación: develop es la rama de integración; master mantiene las versiones.
- El trabajo de características se dirige a ramas de develop; fusión a develop a través de PR.
- Para liberar en master, abre un PR en master. La etiqueta de liberación se aplica automáticamente según los Commits Convencionales (título/commits). Si no se encuentra una señal clara, el valor predeterminado es
release:minor.release:majorcuando se detecta un cambio de ruptura (!/BREAKING CHANGE)release:minorpara características o como predeterminadorelease:patchpuede usarse explícitamente si deseas un aumento de parche
- Al fusionar, el flujo de trabajo de Auto Version:
- Ejecuta
npm version <type>en master, confirma y etiquetav<version> - Activa Release, publicación de Docker en GHCR (etiquetas:
v<version>,latest), y la prueba de humo de Docker.
- Ejecuta
- La verificación de aumento de versión en PR se omite cuando hay una etiqueta de liberación presente.
Este proyecto es una herramienta para validar, calificar y generar reportes de especificaciones OpenAPI.
All-in-one toolkit to bundle, lint, grade, and report OpenAPI specs. Ships with pinned tool versions and an opinionated Spectral ruleset, plus an A-E quality grade on top of your validation pipeline.
- Local tools:
@stoplight/spectral-cli6.15.0. Redocly (optional) may be used when available. - npx tools: pinned or latest depending on script (see Usage)
Note: Redocly CLI v2 is ESM-only. Use Node 22.12.0+.
También disponible en español: docs/README.es.md
- Node.js 22.12.0+
- pnpm
SCHEMA_LINT=1Incluye la verificación de esquema de Redocly en la validación/calificación y la factoriza en la puntuación final.GRADE_SOFT=1Fuerza un código de salida cero incluso cuando hay errores presentes (útil para informes no bloqueantes en CI).
pnpm install # o: pnpm install --frozen-lockfilepnpm run check -- path/to/openapi.yaml
# Windows PowerShell/CMD:
pnpm run check -- "C:\path\to\openapi.yaml"Comprobación de esquema opcional con Redocly:
SCHEMA_LINT=1 pnpm run check -- path/to/openapi.yaml
# PowerShell
$env:SCHEMA_LINT=1; pnpm run check -- "C:\path\to\openapi.yaml"pnpm run check -- path/to/openapi
