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

@mockulus/admin-sdk

v0.3.0

Published

Typed client, WireMock-style builders and test helpers for the mockulus admin API.

Readme

@mockulus/admin-sdk

A typed client for the mockulus admin API — for managing mocks programmatically from a service, a test suite, or a deployment script.

$ npm install @mockulus/admin-sdk

No runtime dependencies — it is built on the platform's own fetch. Everything described below is what the package actually exports today, so that this file is never ahead of the code.

The SDK versions independently of the server: it iterates faster than the server does, and a client fix should not wait for a server release. A 0.x version is not a statement about the server's maturity.

What it is for

mockulus refuses a stub it cannot serve, at registration, with a 422 naming the field. That is the property that makes a migration tractable — you learn about every gap in one command instead of at three in the morning. This SDK moves the same contract one step earlier: it types the supported subset and nothing more, so a stub you can express here is a stub the server registers, and a field it does not support is a type error before it is an HTTP response.

That is also the reason the types are strict rather than permissive. An additionalProperties: false in the contract is not pedantry; it is the 422 you would otherwise get, delivered by the compiler.

Available today

The client

One namespace per group of the admin API, over the platform's own fetch:

import { MockulusClient } from '@mockulus/admin-sdk';

const client = new MockulusClient({ baseUrl: 'http://localhost:9090' });
await client.mappings.create({
  request: { method: 'GET', urlPath: '/api/orders' },
  response: { status: 200, jsonBody: { orders: [] } },
});

Every non-2xx answer becomes a MockulusError carrying every problem the server reported rather than the first, since mockulus collects the whole list before answering. The endpoints that answer an unknown id with a bare, bodyless 404 have …OrNull variants beside the throwing defaults.

The builders

The WireMock Java DSL's names, over exactly the supported subset:

import { aResponse, containing, get, stubFor, urlPathEqualTo } from '@mockulus/admin-sdk';

await client.mappings.create(
  stubFor(
    get(urlPathEqualTo('/api/orders'))
      .withHeader('Accept', containing('json'))
      .willReturn(aResponse().withStatus(201).withJsonBody({ id: 7 })),
  ),
);

Nothing outside the subset exists to call, and several of the combinations the server refuses do not type-check either — a modifier is a parameter of the matcher it modifies, a verb takes one URL criterion, a response has one body form.

The test helpers

Three properties of the server that a suite would otherwise discover the hard way, each with a helper:

import { suite, verify, waitForStub } from '@mockulus/admin-sdk';

// The journal is eventually consistent, so this polls rather than asking once.
await verify(client, { method: 'GET', urlPath: '/api/orders' }, { times: 2 });

// A deployment is one shared namespace, so a run namespaces and cleans up by
// tag instead of resetting what everyone else is using.
const run = suite(client, { prefix: 'checkout' });
try {
  const stub = await run.register(stubFor(get(urlPathEqualTo(run.url('/orders')))));
  // Stubs reach the other replicas within `sync_interval`, not instantly.
  await waitForStub(client, stub.id!);
} finally {
  await run.cleanup();
}

verify() reports the count history it observed rather than only the final number, and answers the journal-off case — a 500 with code 1010, which is what a fresh deployment gives — by naming journal_enabled instead of reporting a failed assertion.

The error codes

The server's catalog, and the HTTP status each is answered with:

import { ErrorCode, ErrorCodeStatus } from '@mockulus/admin-sdk';

ErrorCode.JournalDisabled; // 1010
ErrorCodeStatus[ErrorCode.JournalDisabled]; // 500

Two of the codes are WireMock's own — 10 and 109 — kept at its values so a client that already special-cases one keeps working. Everything from 1000 up is mockulus', where WireMock has no code and nothing can collide.

Branch on the code, not the status: five different problems answer 422, and the code is what tells them apart.

These constants are checked against the server's specification by this package's own test suite, in both directions, so they cannot drift from what the server actually answers.

Requirements

Node 20 or newer. ESM only. No runtime dependencies — the client is built on the platform's own fetch.

Compatibility

The SDK versions independently of the server, because it will iterate faster at first, so which pairs work together is stated rather than inferred:

| SDK | Server | Notes | | ------- | ------- | -------------------------------------------------------------- | | 0.1.x | 1.1.x | The admin surface as of the release this SDK was built beside. |

A server older than the row it is paired with is not a supported combination: the SDK's types come from that server's contract, and a call it can express is one an older server may answer 404 code 1001 to. The reverse — a newer server, an older SDK — is safe by the project's own compatibility promise, since after 1.0 the WireMock-compatible surface changes only in majors and a 422 becoming a supported feature is a minor.

The table grows a row per release. It is not generated, because there is nothing to generate it from until there is more than one of either to compare.

How this package is kept honest

Three mechanisms, none of which rely on anyone remembering:

  • The request and response types are generated from api/openapi.yaml and committed. CI regenerates and diffs them, so they cannot drift from the contract.
  • The contract itself is cross-checked against the server's behavior catalog in both directions, so it cannot drift from the surface the server's own test gate enforces.
  • The integration suite drives a real mockulus process it starts itself. A client that type-checks against the contract can still send something the server refuses, and that is the only place it shows up.

License

Apache-2.0, the same as the server. See LICENSE and NOTICE at the repository root.