@reso-standards/reso-certification
RESO Certification
Compliance testing toolkit for RESO OData servers. Run certification tests from the command line, integrate them into your CI pipeline, or call the SDK directly from your application.
- Three endorsements ready to use: Add/Edit, EntityEvent, Web API Core
- No Java required – pure TypeScript, built on
reso-clientfor OData andreso-validationfor field validation - Auto-configuring – samples live server data to build test parameters, auto-detects enum mode from metadata
- SDK-first – the CLI, Desktop Client, and MCP server all call the same SDK functions with progress callbacks
- Flexible auth – bearer tokens, OAuth2 Client Credentials,
.envfiles, or environment variables
User Guide – a task-oriented walkthrough with realistic examples.
Install
npm install @reso-standards/reso-certification
Getting Started
# Add/Edit compliance
reso-cert add-edit --url https://api.example.com --auth-token TOKEN
# EntityEvent compliance
reso-cert entity-event --url https://api.example.com --auth-token TOKEN
# Web API Core compliance
reso-cert core --url https://api.example.com --auth-token TOKEN
Authentication
Auth is resolved automatically from the first available source:
- CLI flags:
--auth-tokenor--client-id/--client-secret/--token-url - Config file:
--config path/to/config.json(per-entry auth) .envfile: in the current directory- Environment variables:
RESO_AUTH_TOKENorRESO_CLIENT_ID/RESO_CLIENT_SECRET/RESO_TOKEN_URI
Endorsements
Add/Edit (RCP-010)
Validates CRUD operations: create, update, and delete with representation/minimal preferences and error handling. 8 certification scenarios.
reso-cert add-edit --url https://api.example.com --auth-token TOKEN
EntityEvent (RCP-027)
Validates EntityEvent change tracking in observe mode (read-only) or full mode (canary writes). 9-12 scenarios depending on mode.
reso-cert entity-event --url https://api.example.com --auth-token TOKEN --mode observe
Web API Core 2.0.0 / 2.1.0
Validates OData query capabilities: $filter across all data types, $select, $orderby, $top, $skip, $count, enumerations, error codes. v2.1.0 adds $expand, server-driven paging, and string-based enum comparisons.
reso-cert core --url https://api.example.com --auth-token TOKEN
Data Dictionary 2.0
Validates server metadata and data availability against the RESO Data Dictionary. Fetches metadata, merges Lookup Resource data, checks for variations, and replicates data using multiple strategies.
reso-cert dd --url https://api.example.com --auth-token TOKEN
# Strict mode
reso-cert dd --url https://api.example.com --auth-token TOKEN --strict
Output
# Default: progress with spinners
reso-cert core --url https://api.example.com --auth-token TOKEN
# Verbose: line-by-line (good for CI logs)
reso-cert core --url https://api.example.com --auth-token TOKEN --verbose
# JSON: machine-readable output
reso-cert core --url https://api.example.com --auth-token TOKEN --output json
# Write reports to a directory
reso-cert core --url https://api.example.com --auth-token TOKEN --output-dir ./results
Config Files
Run tests from a JSON config file instead of CLI flags. Each entry in the configs array is tested sequentially.
reso-cert add-edit --config sample-configs/add-edit-config.json
See sample-configs/ for examples.
Metadata Report Utilities
reso-cert metadata-report adapt
Synthesize the top-level resources[] block on a DD 2.0 or 2.1 metadata report so it can be loaded by tools that expect a DD 2.2-shaped report (notably the Reference Server). Idempotent – DD 2.2+ reports pass through unchanged.
reso-cert metadata-report adapt \
--in path/to/metadata-report.json \
--out path/to/adapted-report.json \
--pretty
Why this exists: cert metadata reports for DD 2.0 and 2.1 do not carry a top-level resources[] block. That concept arrives in DD 2.2. Anything that consumes a metadata report and needs to know which entity sets to register has to derive the resource list from the next-best source: distinct values in fields[].resourceName. The adapt command does this mechanically and writes a new file with the synthesized block in place.
The same logic is also exposed via the SDK as synthesizeResourcesFromFields:
import {
synthesizeResourcesFromFields,
type MetadataReport,
} from '@reso-standards/reso-certification';
const adapted: MetadataReport = synthesizeResourcesFromFields(report);
The helper is pure and idempotent – calling it on a report that already has a populated resources[] returns the input unchanged.
SDK
All CLI commands wrap the same SDK functions:
import { runComplianceTests } from '@reso-standards/reso-certification';
const result = await runComplianceTests({
endorsement: 'core',
server: {
url: 'https://api.example.com',
auth: { mode: 'token', authToken: 'TOKEN' },
},
}, (progress) => {
console.log(`${progress.step}: ${progress.status}`);
});
Exit Codes
| Code | Meaning |
|---|---|
| 0 | All scenarios passed |
| 1 | One or more scenarios failed |
| 2 | Runtime error |
Docker
Run compliance tests against the RESO Reference Server:
cd ../reso-reference-server
# Add/Edit
docker compose --profile compliance-addedit up --build \
--exit-code-from compliance-addedit db-addedit server-addedit compliance-addedit
# EntityEvent
docker compose --profile compliance-entity-event up --build \
--exit-code-from compliance-entity-event db-entity-event server-entity-event compliance-entity-event
# Web API Core
docker compose --profile compliance-core up --build \
--exit-code-from compliance-core compliance-core
Development
npm install
npm run build
npm test # 250 tests
npm run dev # Watch mode
License
See LICENSE in the repository root.