Validates JSON-FG documents and OGC API endpoints against OGC specifications.
Built on @geonovum/standards-checker; see its documentation for the validation engine, CLI toolkit, and web UI framework.
Release notes are in CHANGELOG.md; see Versioning & releasing for how it is produced.
Demo: https://geonovum.github.io/ogc-checker/
# From a local file
npx @geonovum/ogc-checker@latest validate --standard json-fg --input ./data/spec.json
# From a URL
npx @geonovum/ogc-checker@latest validate --standard json-fg --input https://example.com/spec.json
# From stdin
cat spec.json | npx @geonovum/ogc-checker@latest validate --standard json-fgnpm install -g @geonovum/ogc-checker@latest
ogc-checker validate --standard json-fg --input ./data/spec.jsonpnpm install
pnpm build:cli
node dist/cli.mjs validate --standard json-fg --input ./data/spec.jsonAvailable standards: json-fg, ogc-api-features, ogc-api-processes, ogc-api-records. --version is
optional and defaults to the latest final version of the standard. Only ogc-api-processes ships more
than one version — it defaults to the approved 1.0.0, and the 2.0.0 draft is opt-in:
ogc-checker validate --standard ogc-api-processes --input ./openapi.json # 1.0.0
ogc-checker validate --standard ogc-api-processes --version 2.0.0 --input ./openapi.json # 2.0.0 draftThe old --ruleset <slug> flag still works as a deprecated alias (it prints a warning on stderr and
resolves the old slug to the same standard/version): --ruleset json-fg == --standard json-fg --version 1.0.
| Flag | Description | Default |
|---|---|---|
--standard <slug> |
Standard to validate against | (required) |
--version <id> |
Version of the standard | latest final |
--ruleset <slug> |
Deprecated alias for --standard/--version |
— |
--input <file|-> |
Input file, URL, or - for stdin |
- |
--format <fmt> |
Output: table, json |
table |
--fail-on <level> |
Exit code policy: none, warn, error |
error |
Exit codes: 0 = pass, 1 = failed per --fail-on policy, >1 = unexpected error.
Each specification below maps to a standard in the checker; its requirement table lists the conformance classes of that standard's current version. Pick the standard in the header, then the version:
Standard (--standard) |
Version (--version) |
Status | Covers |
|---|---|---|---|
json-fg |
1.0.0 |
final | JSON-FG |
ogc-api-features |
1.0.1 |
final | OGC API - Features Part 1 (Core) and Part 2 (CRS by ref.) |
ogc-api-processes |
1.0.0 |
final (default) | OGC API - Processes Part 1 (Core) |
ogc-api-processes |
2.0.0 |
draft | OGC API - Processes Part 1 (Core) |
ogc-api-records |
1.0.0 |
final | OGC API - Records Part 1 (Core) |
Version: 1.0.0 — Specification
| Requirement | Testable | Tested | Remarks |
|---|---|---|---|
/req/core/schema-valid |
Yes | Yes | |
/req/core/metadata |
Yes | Yes | |
/req/core/instant |
Yes | Yes | Covered by /req/core/schema-valid |
/req/core/interval |
Yes | Yes | |
/req/core/instant-and-interval |
Yes | Yes | |
/req/core/utc |
Yes | Yes | Covered by /req/core/schema-valid |
/req/core/coordinate-dimension |
Yes | Yes | |
/req/core/geometry-wgs84 |
Yes | Yes | |
/req/core/geometry-no-jsonfg-extension |
Yes | Yes | Covered by /req/core/schema-valid |
/req/core/valid-geometry |
Yes | No | |
/req/core/place-geometries |
Yes | Yes | |
/req/core/same-crs |
Yes | Yes | Covered by /req/core/schema-valid |
/req/core/fallback |
Yes | Yes | |
/req/core/axis-order |
No | No | |
/req/polyhedra/metadata |
Yes | Yes | |
/req/polyhedra/coordinates |
Yes | Yes | |
/req/polyhedra/valid-geometry |
Yes | No | |
/req/prisms/metadata |
Yes | Yes | |
/req/prisms/coordinates |
Yes | Yes | |
/req/circular-arcs/metadata |
Yes | Yes | |
/req/circular-arcs/valid-geometry |
Yes | No | |
/req/measures/metadata |
Yes | Yes | |
/req/measures/coordinates |
Yes | Yes | |
/req/measures/sub-geometries |
Yes | Yes | Covered by /req/core/schema-valid |
/req/types-schemas/metadata |
Yes | Yes | |
/req/types-schemas/feature-type |
Yes | Yes | |
/req/types-schemas/geometry-dimension |
Yes | Yes | |
/req/types-schemas/feature-schemas |
No | No | Referenced schemas not dereferenced |
/req/types-schemas/single-feature-schema |
Yes | Yes | |
/req/profiles/rfc7946 |
No | No | Profile negotiation (API layer) |
/req/profiles/jsonfg |
No | No | Profile negotiation (API layer) |
/req/profiles/jsonfg-plus |
No | No | Profile negotiation (API layer) |
/req/api/profile-parameter |
No | No | Web API behavior, not a document |
Version: 1.0.1 — Specification
| Requirement | Testable | Tested | Remarks |
|---|---|---|---|
/req/core/root-op |
Yes | Yes | |
/req/core/root-success |
Yes | Yes | |
/req/core/conformance-op |
Yes | Yes | |
/req/core/conformance-success |
Yes | Yes | |
/req/core/fc-md-op |
Yes | Yes | |
/req/core/fc-md-success |
Yes | Yes | |
/req/core/sfc-md-op |
Yes | Yes | |
/req/core/sfc-md-success |
Yes | Yes | |
/req/core/fc-op |
Yes | Yes | |
/req/core/fc-response |
Yes | Yes | |
/req/core/fc-limit-definition |
Yes | Yes | |
/req/core/fc-bbox-definition |
Yes | Yes | |
/req/core/fc-time-definition |
Yes | Yes | |
/req/core/f-op |
Yes | Yes | |
/req/core/f-response |
Yes | Yes | |
/req/oas30/oas-definition-2 |
Yes | Yes |
Version: 1.0.1 — Specification
| Requirement | Testable | Tested | Remarks |
|---|---|---|---|
/req/crs/crs-uri |
No | No | |
/req/crs/fc-md-crs-list |
Yes | Yes | |
/req/crs/fc-md-storageCrs |
No | No | |
/req/crs/fc-md-storageCrs-valid-value |
Yes | Yes | |
/req/crs/fc-md-crs-list-global |
No | No | |
/req/crs/fc-bbox-crs-definition |
Yes | Yes | |
/req/crs/fc-bbox-crs-valid-value |
Yes | Yes | Tests the presence of a 400 response. |
/req/crs/fc-bbox-crs-valid-defaultValue |
Yes | Yes | Covered by /req/crs/fc-bbox-crs-definition. |
/req/crs/fc-bbox-crs-action |
No | No | |
/req/crs/fc-crs-definition |
Yes | Yes | |
/req/crs/fc-crs-valid-value |
No | No | |
/req/crs/fc-crs-default-value |
Yes | Yes | Covered by /req/crs/fc-crs-definition. |
/req/crs/fc-crs-action |
No | No | |
/req/crs/geojson |
No | No | |
/req/crs/ogc-crs-header |
Yes | Yes | |
/req/crs/ogc-crs-header-value |
No | No |
Version: 1.0.0 — Specification
| Requirement | Testable | Tested | Remarks |
|---|---|---|---|
/req/core/landingpage-op |
Yes | Yes | |
/req/core/landingpage-success |
Yes | Yes | |
/req/core/api-definition-op |
No | No | |
/req/core/api-definition-success |
No | No | |
/req/core/conformance-op |
Yes | Yes | |
/req/core/conformance-success |
Yes | Yes | |
/req/core/http |
No | No | |
/req/core/process-list |
Yes | Yes | |
/req/core/pl-limit-definition |
Yes | Yes | |
/req/core/pl-limit-response |
No | No | |
/req/core/process-list-success |
Yes | Yes | |
/req/core/pl-links |
No | No | |
/req/core/process |
Yes | Yes | |
/req/core/process-success |
Yes | Yes | |
/req/core/process-exception/no-such-process |
Yes | Yes | |
/req/core/process-execute-op |
Yes | Yes | |
/req/core/process-execute-request |
Yes | Yes | |
/req/core/process-execute-inputs |
No | No | |
/req/core/process-execute-input-array |
No | No | |
/req/core/process-execute-input-inline-object |
No | No | |
/req/core/process-execute-input-mixed-type |
No | No | |
/req/core/process-execute-input-inline-binary |
No | No | |
/req/core/process-execute-input-validation |
No | No | |
/req/core/process-execute-default-execution-mode |
No | No | |
/req/core/process-execute-auto-execution-mode |
No | No | |
/req/core/process-execute-default-outputs |
No | No | |
/req/core/process-execute-sync-raw-value-one |
Yes | Yes | Only the 200 response is statically checked |
/req/core/process-execute-sync-raw-value-multi |
No | No | |
/req/core/process-execute-sync-raw-ref |
No | No | |
/req/core/process-execute-sync-raw-mixed-multi |
No | No | |
/req/core/process-execute-sync-document |
Yes | Yes | |
/req/core/job-results-success-sync |
No | No | |
/req/core/process-execute-success-async |
Yes | Yes | |
/req/core/job |
Yes | Yes | |
/req/core/job-success |
Yes | Yes | |
/req/core/job-exception-no-such-job |
Yes | Yes | |
/req/core/job-results |
Yes | Yes | |
/req/core/job-results-async-raw-value-one |
No | No | |
/req/core/job-results-async-raw-value-multi |
No | No | |
/req/core/job-results-async-raw-mixed-multi |
No | No | |
/req/core/job-results-async-raw-ref |
No | No | |
/req/core/job-results-async-document |
Yes | Yes | |
/req/core/job-results-exception/no-such-job |
Yes | Yes | |
/req/core/job-results-exception/results-not-ready |
Yes | Yes | |
/req/core/job-results-failed |
Yes | Yes | |
/req/core/test-process |
No | No | |
/req/ogc-process-description/json-encoding |
Yes | Yes | |
/req/ogc-process-description/inputs-def |
No | No | |
/req/ogc-process-description/input-def |
No | No | |
/req/ogc-process-description/input-binary |
No | No | |
/req/ogc-process-description/input-mixed-type |
No | No | |
/req/ogc-process-description/outputs-def |
No | No | |
/req/ogc-process-description/output-def |
No | No | |
/req/ogc-process-description/output-mixed-type |
No | No | |
/req/json/definition |
Yes | Yes | |
/req/html/definition |
No | No | |
/req/html/content |
No | No | |
/req/oas30/oas-definition-1 |
No | No | |
/req/oas30/oas-definition-2 |
No | No | |
/req/oas30/oas-impl |
No | No | |
/req/oas30/completeness |
No | No | |
/req/oas30/exceptions-codes |
No | No | |
/req/oas30/security |
No | No | |
/req/job-list/job-list-op |
Yes | Yes | |
/req/job-list/type-definition |
Yes | Yes | |
/req/job-list/type-response |
No | No | |
/req/job-list/processID-mandatory |
Yes | No | |
/req/job-list/processID-definition |
Yes | Yes | |
/req/job-list/processid-response |
No | No | |
/req/job-list/status-definition |
Yes | Yes | |
/req/job-list/status-response |
No | No | |
/req/job-list/datetime-definition |
Yes | Yes | |
/req/job-list/datetime-response |
No | No | |
/req/job-list/duration-definition |
Yes | Yes | minDuration/maxDuration are integer arrays |
/req/job-list/duration-response |
No | No | 18-062r2 misprints it as status-response |
/req/job-list/limit-definition |
Yes | Yes | |
/req/job-list/limit-response |
No | No | |
/req/job-list/job-list-success |
Yes | Yes | |
/req/job-list/links |
No | No | |
/req/callback/job-callback |
No | No | |
/req/dismiss/job-dismiss-op |
Yes | No | |
/req/dismiss/job-dismiss-success |
Yes | No |
Version: 2.0 (Draft) — Specification
| Requirement | Testable | Tested | Remarks |
|---|---|---|---|
/req/core/landingpage-op |
Yes | Yes | |
/req/core/landingpage-success |
Yes | Yes | |
/req/core/api-definition-op |
No | No | |
/req/core/api-definition-success |
No | No | |
/req/core/conformance-op |
Yes | Yes | |
/req/core/conformance-success |
Yes | Yes | |
/req/core/http |
No | No | |
/req/core/process-list-op |
Yes | Yes | |
/req/core/pl-limit-definition |
Yes | Yes | |
/req/core/pl-limit-response |
No | No | |
/req/core/process-list-success |
Yes | Yes | |
/req/core/pl-links |
No | No | |
/req/core/process-summary-links |
No | No | |
/req/core/process-description-op |
Yes | Yes | |
/req/core/process-description-success |
Yes | Yes | |
/req/core/process-exception-no-such-process |
Yes | Yes | |
/req/core/process-execute-op |
Yes | Yes | |
/req/core/process-execute-request |
Yes | Yes | |
/req/core/process-execute-default-execution-mode |
No | No | |
/req/core/process-execute-auto-execution-mode |
No | No | |
/req/core/process-execute-input-array |
No | No | |
/req/core/process-execute-input-inline-object |
No | No | |
/req/core/process-execute-input-multiple-types |
No | No | |
/req/core/process-execute-input-inline-binary |
No | No | |
/req/core/process-execute-input-inline-bbox |
No | No | |
/req/core/process-execute-input-validation |
No | No | |
/req/core/process-execute-omitted-outputs |
No | No | |
/req/core/process-execute-empty-outputs |
No | No | |
/req/core/process-execute-sync-one |
Yes | Yes | |
/req/core/process-execute-sync-one-default-content |
No | No | |
/req/core/process-execute-sync-one-multi-valued-json |
No | No | |
/req/core/process-execute-sync-many-json |
Yes | Yes | |
/req/core/process-execute-success-sync-outputs-omitted |
No | No | |
/req/core/process-execute-success-sync-empty-outputs |
No | No | |
/req/core/job-results-success-sync |
No | No | |
/req/core/process-execute-success-async |
Yes | Yes | |
/req/core/process-execute-success-async-outputs |
No | No | |
/req/core/process-execute-success-async-outputs-Nth |
No | No | |
/req/core/process-execute-success-async-outputs-empty |
No | No | |
/req/core/process-execute-success-async-outputs-omitted |
No | No | |
/req/core/job-op |
Yes | Yes | |
/req/core/job-success |
Yes | Yes | |
/req/core/job-exception-no-such-job |
Yes | Yes | |
/req/core/job-results-op |
Yes | Yes | |
/req/core/job-results-param-outputs |
Yes | Yes | |
/req/core/job-results-param-outputs-response |
No | No | |
/req/core/job-results-profile |
No | No | |
/req/core/job-result-op |
Yes | Yes | |
/req/core/job-result-op-Nth |
Yes | No | |
/req/core/job-result-op-0th |
Yes | Yes | |
/req/core/job-results-async-one |
Yes | Yes | |
/req/core/job-results-async-one-Nth |
No | No | |
/req/core/job-results-async-one-multi-valued |
No | No | |
/req/core/job-results-async-many |
Yes | Yes | |
/req/core/job-results-exception-invalid-query-parameter-value |
Yes | Yes | |
/req/core/job-results-exception-no-such-output |
Yes | Yes | |
/req/core/job-results-exception-no-such-job |
Yes | Yes | |
/req/core/job-results-exception-results-not-ready |
Yes | Yes | |
/req/core/job-results-exception-results-not-available |
Yes | Yes | |
/req/core/job-results-failed |
Yes | Yes | |
/req/core/test-process |
No | No | |
/req/ogc-process-description/json-encoding |
Yes | Yes | |
/req/ogc-process-description/links |
No | No | |
/req/ogc-process-description/inputs-def |
No | No | |
/req/ogc-process-description/data-classes |
No | No | |
/req/ogc-process-description/data-access-apis |
No | No | |
/req/ogc-process-description/input-def |
No | No | |
/req/ogc-process-description/input-multiple-types |
No | No | |
/req/ogc-process-description/value-passing |
No | No | |
/req/ogc-process-description/execution-unit-requirements |
No | No | |
/req/ogc-process-description/outputs-def |
No | No | |
/req/ogc-process-description/output-def |
No | No | |
/req/ogc-process-description/output-multiple-types |
No | No | |
/req/job-list/job-list-op |
Yes | Yes | |
/req/job-list/type-definition |
Yes | Yes | |
/req/job-list/type-response |
No | No | |
/req/job-list/processID-mandatory |
Yes | No | |
/req/job-list/processID-definition |
Yes | Yes | |
/req/job-list/processid-response |
No | No | |
/req/job-list/status-definition |
Yes | Yes | |
/req/job-list/status-response |
No | No | |
/req/job-list/datetime-definition |
Yes | Yes | |
/req/job-list/datetime-response |
No | No | |
/req/job-list/duration-definition |
Yes | Yes | |
/req/job-list/duration-response |
No | No | |
/req/job-list/limit-definition |
Yes | Yes | |
/req/job-list/limit-response |
No | No | |
/req/job-list/job-list-success |
Yes | Yes | |
/req/job-list/links |
No | No | |
/req/json/definition |
Yes | Yes |
Version: 1.0 (Draft) — Specification
| Requirement | Testable | Tested | Remarks |
|---|---|---|---|
/req/json/conformance |
No | No | |
/req/json/record-response |
Yes | Yes | |
/req/json/record-content |
Yes | Yes | |
/req/json/record-content-profile |
No | No | |
/req/json/collection-response |
Yes | Yes | |
/req/json/catalog-content |
Yes | Yes |
- Node.js 24+
- pnpm 10+
pnpm install| Command | Description |
|---|---|
pnpm dev |
Vite dev server with hot reload |
pnpm build |
Full build: tsc + CLI bundle + vite webapp |
pnpm build:cli |
Build only the CLI binary (dist/cli.mjs) |
pnpm test |
Vitest in watch mode |
pnpm test run |
Vitest single run |
pnpm lint |
Check for lint and formatting issues |
pnpm lint:fix |
Auto-fix lint and formatting issues |
Run a single test file:
npx vitest run src/standards/json-fg/rulesets/core.test.tsVersioning, the changelog, and publishing are driven by Changesets. Describing a change is decoupled from cutting a release:
-
Add a changeset with your change. Run
pnpm changeset, pick the bump (major/minor/patch), and write a one-line summary. This creates a.changeset/<name>.mdfile — commit it with your PR. Omit only for changes that don't affect the published package (CI, internal docs, tests). -
Cut the release. Run
pnpm version-packages(alias forchangeset version). It consumes the pending.changeset/*.mdfiles, bumpspackage.json, and prepends the summaries toCHANGELOG.md. Review and commit the result. Don't hand-edit theversionfield — Changesets owns it. -
Publish. Tag the released version and push; the CI workflow verifies
package.jsonmatches the tag, builds, tests, publishes to npm, and deploys to GitHub Pages:git tag v1.1.0 git push --tags
pnpm release(pnpm build && changeset publish) publishes to npm locally if you need to bypass the workflow (it does not deploy Pages).