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

jsonspecs-cli

v2.1.2

Published

Authoring, validation, snapshot build, sample-test, and local Studio CLI for jsonspecs projects

Downloads

33

Readme

JSONSpecs CLI

CI npm License: MIT Node 20+

Authoring, validation, build, sample-test, and local Studio host for jsonspecs rules projects.

Install

npm install --global jsonspecs-cli

Commands

jsonspecs init <project-name>
jsonspecs validate
jsonspecs test
jsonspecs build
jsonspecs studio

| Command | Purpose | | --- | --- | | init | Creates a minimal rules project with manifest, example rules, samples, local operator pack, and output directories. | | validate | Loads artifacts from rules/ and reports structured diagnostics from the jsonspecs compiler. | | test | Runs every JSON sample in samples/ against the compiled project. | | build | Writes deterministic snapshot.json and build-info.json into dist/. | | studio | Starts the local SPA Studio and JSON API for exploration and playground runs. |

Rules project layout

manifest.json
rules/
  library/
  entrypoints/
  internal/
  dictionaries/
operators/
  node/
samples/
docs/
dist/

docs/ is reserved for hand-written project documentation. The CLI no longer generates Markdown or Confluence-style documentation from pipelines. Studio is an exploration/playground UI; it does not expose /api/docs/* endpoints.

Manifest contract

manifest.json must contain an explicit SemVer ruleset version:

{
  "project": {
    "id": "checkout-rules",
    "version": "1.0.0",
    "title": "Checkout rules",
    "description": "Checkout validation rules",
    "language": "ru"
  }
}

project.version is copied to:

  • snapshot.meta.rulesetVersion;
  • build-info.json.rulesetVersion;
  • runtime result ruleset.rulesetVersion after jsonspecs.compileSnapshot().

Increment it whenever the rules package is released. Projects created before project.version became required must add it before running validate, test, build, or Studio.

The manifest also drives Studio display metadata:

  • catalog.fields[field].title is the primary human-readable field label;
  • catalog.fields[field].description is secondary explanatory text;
  • catalog.entrypoints[id] and catalog.artifacts[id] provide titles/descriptions for pages and flow views;
  • catalog.operators and operator-pack meta.operators provide operator descriptions.

Build output

jsonspecs build writes a deterministic snapshot suitable for jsonspecs.compileSnapshot():

{
  "format": "jsonspecs-snapshot",
  "formatVersion": 1,
  "sourceHash": "...",
  "engine": { "minVersion": "2.1.1" },
  "artifacts": [],
  "meta": {
    "projectId": "checkout-rules",
    "projectTitle": "Checkout rules",
    "description": "Checkout validation rules",
    "rulesetVersion": "1.0.0"
  }
}

build-info.json duplicates deployment metadata useful for CI, Docker images, and runtime services: project id/title, ruleset version, engine version, snapshot format/version, source hash, artifact count, entrypoints, and local Node operator packs.

Sample tests

Each samples/*.json file is a complete execution case:

{
  "context": {
    "pipelineId": "entrypoints.order.validation",
    "currentDate": "2026-07-12"
  },
  "payload": {
    "order": { "amount": 1500 }
  },
  "expect": {
    "status": "OK",
    "exact": true,
    "issues": []
  }
}

expect.status is exact. expect.issues uses subset matching, so a sample can assert only stable fields such as code, field, and level. expect.exact: true rejects additional issues.

Custom operators

Project-local custom operators are loaded from manifest.json:

{
  "operatorPacks": {
    "node": ["./operators/node"]
  }
}

A local Node operator pack exports check, predicate, and optional meta:

module.exports = {
  check: {
    amount_gt_zero(rule, ctx) {
      const got = ctx.get(rule.field);
      if (!got.ok) return { status: "FAIL", actual: undefined };

      const value = Number(got.value);
      return {
        status: Number.isFinite(value) && value > 0 ? "OK" : "FAIL",
        actual: got.value,
      };
    },
  },
  predicate: {},
  meta: {
    operators: {
      amount_gt_zero: {
        description: "должно быть больше нуля",
      },
    },
  },
};

Project-local operator packs should use the runtime context passed by jsonspecs:

  • ctx.get(path) — stable payload/context field access;
  • ctx.has(path) — presence check;
  • ctx.payloadKeys — flattened payload keys;
  • ctx.getDictionary(id) — dictionary lookup.

Do not import jsonspecs or deepGet from project-local operator packs.

Studio

jsonspecs studio serves a bundled SPA from / and a JSON API under /api/*.

Current Studio capabilities:

  • entrypoint list and project summary;
  • pipeline flow, nested conditions, and stats;
  • rule, condition, dictionary, and generic artifact pages;
  • playground execution against sample payloads;
  • safe basic trace rendering in the playground;
  • SPA deep-link fallback for routes such as /rules/<id> and /pipelines/<id>/playground.

Studio binds to 127.0.0.1 by default and uses same-origin requests. It is a local development tool and must not be exposed as a production service.

The bundled frontend is built from the separate jsonspecs-studio-ui repository and copied into static/.

Development

The source checkout intentionally depends on a sibling ../jsonspecs checkout:

git clone https://github.com/catindev/jsonspecs.git
git clone https://github.com/catindev/jsonspecs-cli.git
cd jsonspecs-cli
npm ci
npm run verify

package.json pins the coordinated engine release in:

{
  "config": {
    "jsonspecsVersion": "2.1.1",
    "jsonspecsGitRef": "v2.1.1"
  }
}

Advance both fields deliberately when the CLI needs a newer engine. Dependabot/Renovate will not update this pair automatically because the source dependency is intentionally a sibling checkout for reproducible local and CI builds.

Tests

npm test
npm run test:pack
npm run verify

npm run test:pack creates real tarballs, installs them in a clean CommonJS consumer, and runs the installed CLI through init, validate, test, and build.

Current coverage and recommended additions are tracked in TESTING.md.

Release order

  1. Publish the matching jsonspecs version first.
  2. Update config.jsonspecsVersion and config.jsonspecsGitRef if needed.
  3. Tag jsonspecs-cli with v<version>.

The tag workflow downloads the exact engine release, builds a sanitized registry-safe tarball whose dependency is ^<jsonspecsVersion>, repeats the pack/install smoke test, publishes to npm, and creates a GitHub release.

Direct publication from the source checkout is blocked by private: true and a prepublishOnly guard.