npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jsonstat-validator/ts

v1.0.1

Published

Semantic validator for JSON-stat 2.0 — layers cross-field cube invariants on top of the official JSON Schema 2020-12 definitions.

Readme

@jsonstat-validator/ts

A semantic validator for JSON-stat 2.0 — the native TypeScript/Node surface of the jsonstat-validator family. It reuses the official JSON Schema 2020-12 definitions for the structural pass and layers on top a rules engine that checks the cross-field cube invariants JSON Schema cannot express.

This package is one of four interchangeable surfaces (TS, Rust, Wasm, CLI) that all share one rules-manifest.json and one corpus/cases.json, so they produce identical findings on identical input. See the monorepo README for the full architecture and DESIGN.md for the design rationale.


Why

JSON Schema can validate shape (required properties, oneOfs, enums, the IANA link regex) but cannot express relationships like "value array length must equal the product of size". This package implements exactly those checks (the S/D/C catalogue) with a stable, versioned error-code vocabulary.

{
  "version": "2.0",
  "class": "dataset",
  "id": ["sex", "year"],
  "size": [2, 3],
  "dimension": { "sex": { "category": { "index": ["M", "F"] } }, "year": { "category": { "index": { "2022": 0, "2023": 1, "2024": 2 } } } },
  "value": [10, 20, 30, 40, 50]
}

A schema engine says "this is shaped like a dataset". @jsonstat-validator/ts tells you the actual problem: value has 5 entries but product(size) is 2 × 3 = 6 — see VALUE_LEN_MISMATCH.


Install

npm install @jsonstat-validator/ts

Works in Node (ESM + CJS) and the browser. Runtime dependencies are limited to ajv and ajv-formats; the package is sideEffects: false so it tree-shakes.


Quick start

import { validate } from "@jsonstat-validator/ts";

const result = validate(doc);          // doc may be an object OR a JSON string
console.log(result.valid);             // true / false
console.log(result.summary);           // { errors, warnings, infos, structuralErrors, byCode }
for (const f of result.findings) {     // Finding[] — empty when valid
  console.log(`[${f.severity}] ${f.code}  ${f.path}  — ${f.message}`);
}

validate() accepts a parsed object or a raw JSON string (it parses for you). To validate a file on disk, use the async validateFile():

import { validateFile } from "@jsonstat-validator/ts";
const result = await validateFile("./my-cube.json");

What the result looks like

{
  "valid": false,
  "findings": [
    {
      "code": "VALUE_LEN_MISMATCH",
      "ruleId": "S3",
      "severity": "error",
      "path": "/value",
      "message": "Dense 'value' length 5 must equal product(size) = 6.",
      "expected": 6,
      "actual": 5,
      "specRef": "wiki/format-specification.md"
    }
  ],
  "summary": { "errors": 1, "warnings": 0, "infos": 0, "structuralErrors": 0, "byCode": { "VALUE_LEN_MISMATCH": 1 } },
  "options": { /* resolved ValidateOptions */ },
  "meta": { "engineVersion": "1.0.1", "ruleSetVersion": "1.0.0", "schemaVersion": "1.05", "durationMs": 3 }
}

Structural (JSON Schema) violations are normalized into the same shape with code: "STRUCTURAL_VIOLATION" and the offending keyword kept in meta — so consumers only ever handle one finding shape.

Tuning a run

validate(doc, {
  mode: "full",              // "full" | "structural" | "semantic"
  minSeverity: "info",       // "error" | "warning" | "info" — filters returned findings
  maxCollectionDepth: 3,     // cap nested-collection recursion
  continueOnStructuralError: true,
  budget: { maxCells: 50_000_000, maxBytes: 200 * 1024 * 1024, maxFindings: 1000 },
  onFinding: (f) => { /* streaming sink, for very large docs */ },
});

minSeverity filters which findings are returned; it never affects the valid flag, which is true iff there are zero error-severity findings.


Web / CDN

The package is dependency-light and browser-safe, so you can use it straight from a CDN with no build step. Works on esm.sh, jsDelivr, and unpkg.

<script type="module"> (recommended)

<script type="module">
  // esm.sh serves the ESM browser build:
  import { validate } from "https://esm.sh/@jsonstat-validator/ts";
  // or jsDelivr / unpkg:
  // import { validate } from "https://cdn.jsdelivr.net/npm/@jsonstat-validator/ts/+esm";

  const result = validate(myJsonstatDocument);
  console.log(result.valid, result.summary);
</script>

Classic <script src> (global JsonstatValidator)

<!-- Minified IIFE bundle from jsDelivr (also on unpkg) -->
<script src="https://cdn.jsdelivr.net/npm/@jsonstat-validator/ts/dist/browser/jsonstat-validator.min.js"></script>
<script>
  const { validate } = window.JsonstatValidator;
  const result = validate(myJsonstatDocument);
  console.log(result.valid, result.findings);
</script>

The browser build excludes validateFile() (it needs node:fs). Use validate() in the browser and fetch the document yourself.

Bundled in an app (Vite, webpack, Rollup, …)

npm install @jsonstat-validator/ts
import { validate } from "@jsonstat-validator/ts";

The package's exports map points bundlers at the browser build automatically, so the same import works in Node and the browser with no special config.


API

validate(doc, options?) → ValidationResult

Run the structural (JSON Schema) + semantic (S/D/C rules) passes. doc may be a parsed object or a JSON string.

validateFile(path, options?) → Promise<ValidationResult>

Read a file from disk and validate it. Enforces the budget.maxBytes guard before reading. Node only — not available in the browser build.

ValidateOptions

| Option | Type | Default | Notes | |---|---|---|---| | mode | "full" \| "structural" \| "semantic" | "full" | Which passes to run | | minSeverity | "error" \| "warning" \| "info" | "info" | Filters returned findings (does not affect valid) | | maxCollectionDepth | number | 3 | Max depth of embedded-collection recursion; 0 disables | | budget | { maxCells?, maxBytes?, maxFindings? } | { 50_000_000, 200 MB, 1000 } | Hard limits to prevent OOM | | continueOnStructuralError | boolean | true | Run semantic rules in degraded mode when shape is broken | | onFinding | (f: Finding) => void | — | Streaming sink, invoked once per finding in addition to the returned array |

Full type definitions ship in dist/index.d.ts.


Error codes

See rules-manifest.json for the authoritative, append-only catalogue. Codes include VALUE_LEN_MISMATCH, SPARSE_KEY_OUT_OF_RANGE, STATUS_LEN_MISMATCH, DIM_KEY_ID_MISMATCH, ID_SIZE_LEN_MISMATCH, ROLE_ID_UNKNOWN, INDEX_COUNT_MISMATCH, INDEX_POSITIONS_INVALID, LABEL_KEY_UNKNOWN, LABEL_KEY_INCOMPLETE, UNIT_KEY_UNKNOWN, COORD_KEY_UNKNOWN, NOTE_KEY_UNKNOWN, CHILD_ID_UNKNOWN, CHILD_CYCLE, METRIC_UNIT_MISSING (warning), BUNDLE_DEPRECATED (info), RECURSION_LIMIT (info), CUBE_SIZE_OVERFLOW, BUDGET_EXCEEDED (warning), PARSE_ERROR, and STRUCTURAL_VIOLATION. The vocabulary is versioned independently (meta.ruleSetVersion) from the package SemVer.


Building from source

# from the monorepo root
npm install                 # runs the `prepare` hook, which builds all workspaces
npm test                    # corpus + rule tests

# or, just this package
cd packages/ts
npm run build               # sync-license → gen assets → tsc → cjs + browser bundles

tools/gen-assets.mjs compiles the shared manifest and vendored schemas into src/generated/ TypeScript modules at build time, so the published tarball is self-contained (no disk reads at runtime). tools/build-browser.mjs uses esbuild to emit the IIFE + ESM browser bundles under dist/browser/.


Related surfaces


License

Apache-2.0.