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

@wahlu/public-api-contracts

v0.7.3

Published

Executable public HTTP wire contracts for the Wahlu API

Downloads

124

Readme

@wahlu/public-api-contracts

Executable, domain-free HTTP wire contracts for Wahlu's public API. The package can be consumed in browser or server builds and has no framework, database, provider, job, CLI, MCP, or UI dependency.

Contract status: this source models the 22-operation public contract. The package is ESM-only and targets Node.js 18+ or a modern browser runtime. Cursor signing remains server-only even though consumer schemas are browser-compatible.

npm install @wahlu/public-api-contracts

Public exports

  • Strict Zod schemas and inferred types for success/error envelopes, response metadata, structured issues, bounded error details, links, cursor pagination, rate limits, request IDs, idempotency keys, and canonical UTC timestamps.
  • createSuccessEnvelopeSchema and cursorResponseMetadataSchema are cursor-only producer contracts. Consumers can use createConsumerSuccessEnvelopeSchema during migration; an existing offset endpoint must opt into createLegacySuccessEnvelopeSchema explicitly.
  • coreErrorPolicy, createPublicError, producer schema factories, and safe status helpers. The consumer schema accepts future bounded uppercase domain codes; producers derive status and retryability from the immutable core registry or an explicit domain registry. Unregistered producer errors collapse to a minimal, non-retryable INTERNAL_ERROR rather than exposing the attempted code, details, or message.
  • resolveOrGenerateRequestId for the server policy that accepts valid caller IDs and replaces invalid values instead of turning them into a public error.
  • toUtcTimestamp, requireUtcTimestamp, and generic toSafePublicStatus boundary helpers.
  • encodeCursor and decodeCursor for versioned HMAC-SHA-256 cursor tokens.
  • Domain-free operation registry primitives. definePublicOperation validates and freezes complete endpoint descriptors; createOperationRegistry rejects duplicate IDs and route shapes and returns a deterministically ordered, typed registry. Candidate/released filters never reorder operations.
  • Canonical released schemas and operation descriptors for 22 operations: agent context, brand target discovery, non-mutating live target-bound TikTok privacy reads, explicit target privacy refresh, public platform capabilities, Media upload sessions, remote Media import, bounded brand-scoped Media listing, one-item Media read, explicit reviewed Media repair derivatives, bounded content-item listing, one-item content read, draft creation, precise existing-draft TikTok privacy update, write-free scheduling preflight, bounded date-range Schedule listing, held Schedule creation, one-item Schedule read, bounded publish receipt lookup, exact receipt-bound provider cleanup, guarded rescheduling, and auditable unsent cancellation. Their registered HTTP routes, SDK, CLI/MCP adapters and shared raw/SDK acceptance scenarios conform to the canonical success metadata envelope.
  • Pure deterministic OpenAPI 3.1 projection. generateReleasedOpenApiDocument filters candidates, projects exact descriptor statuses/auth/scopes/examples and protocol-bodyless responses, while stringifyOpenApiDocument produces stable reviewable bytes. The committed released artifact is docs/openapi/wahlu-public-api-v1.openapi.json.

The independent OpenAPI 3.1 structure gate is:

yarn workspace @wahlu/public-api-contracts validate:openapi

It pins Redocly CLI through npx so validation does not add a package dependency or change the repository lockfile.

Operation registry contract

The registry is the developer-authored source for API, OpenAPI, SDK, and reference work. Exactly 22 descriptors are released and generate the committed released OpenAPI artifact: five discovery operations, Media upload sessions, remote Media import, bounded brand-scoped Media listing, one-item Media read, explicit reviewed repair derivatives, bounded content listing, one-item content read, draft creation, precise TikTok privacy update and write-free scheduling preflight, held Schedule creation and one-item Schedule read, bounded publish receipt lookup, and exact receipt-bound provider cleanup, guarded rescheduling, and auditable unsent cancellation. Execution, approval, retry, polling, and /publish-runs operations remain absent. A descriptor must declare its stable ID and release state, canonical method/path template, tags and prose, authentication and exact scopes, effect/risk/authority policy, idempotency behaviour, request schema slots, success schema, allowed canonical errors, validated JSON examples, links, and deprecation state.

Registry construction enforces several cross-field invariants:

  • path, query, and header parameters are strict named Zod objects; template parameter names and path schema fields match exactly;
  • GET/HEAD are read-only, PUT/PATCH/DELETE cannot claim to be reads, and a naturally idempotent PUT may return an unchanged success. Released non-PUT mutations require explicit idempotency except the explicitly registered bounded target-refresh POST action, whose medium-risk write has a strict empty body and no content, Schedule, or provider-publishing effect;
  • an external effect is deliberately narrower than a generic write: it is high-risk, requires API-key authentication, names at least one effect-authority scope already present in the operation scopes, and always requires idempotency. A publishing descriptor can therefore name publish:execute, while a different external effect can use its own explicit authority without making this package domain-specific;
  • header/body idempotency uses the exported canonical field schemas and resolveOperationIdempotencyKey. When both sources are allowed, at least one is required for a required operation and two supplied values must match. Replay returns a stable result through the explicitly declared replay.response_status; it is not misleadingly described as returning the original wire response, and validation requires that status to select a declared response schema;
  • examples parse through every declared request/success/error schema, contain bounded plain JSON, and are cloned and deeply frozen. Zod schema objects remain unfrozen and reusable;
  • one primary 2xx response may declare exact alternate expected 2xx statuses or conditional-GET 304. Statuses are unique, every expected status has a matching schema-validated example, canonical error statuses cannot be reclassified as expected responses, and protocol-bodyless 204/205/304 responses use the exported bodylessResponseSchema. A 304 also requires the canonical optional If-None-Match request field. This models both ETag revalidation and create/replay 201/200 variation without weakening error validation;
  • deprecated replacement IDs resolve inside the registry, cannot form deprecated chains, and a released operation cannot point to a candidate replacement.

Zod schemas are a trusted developer-time contract boundary, not untrusted request input. The schema check accepts real Zod 3 first-party types structurally as well as through instanceof, so schemas created by another installed Zod 3 module instance remain usable. It rejects minimal duck types and requires direct strict ZodObject shapes where OpenAPI needs named path/query/header parameters. Consumers should still share one compatible Zod 3 version where possible.

The released capabilities operation models If-None-Match and its bodyless 304 directly. OpenAPI's global-header layer combines operation-specific ETag/cache headers on successful representations with request-ID and rate-limit headers on every response. It does not claim cache or idempotency-replay headers on errors, and it documents Retry-After only for the guaranteed 429 rate-limit response.

Cursor security contract

The codec requires an explicit signing secret containing at least 32 bytes and uses Web Crypto, so the main package does not import Node-only crypto modules. Cursor encoding and authenticated decoding are server-only operations: never expose or bundle the signing secret into browser code. Browser consumers should treat cursor tokens as opaque strings and use cursorTokenSchema when validation is needed. A cursor authenticates its version, resource, ordering identity, sort value, final ID tie-break, optional expiry, and a keyed digest of the caller's canonical named scope fields. Raw workspace/brand scope strings are therefore not embedded in the payload, and structured encoding avoids delimiter collisions.

Decode always authenticates the token before parsing the payload. Wrong-resource, wrong-order, cross-scope, malformed, expired, and tampered tokens all throw InvalidCursorError with code INVALID_CURSOR and the same safe public message. The reason property is for internal metrics and tests only; public adapters must not expose it.

const cursor = await encodeCursor(
	{
		resource: "schedules",
		order: "scheduled_at:asc,id:asc",
		scope: { workspace_id: workspaceId, brand_id: brandId },
		sortValue: schedule.scheduled_at,
		id: schedule.id
	},
	process.env.PUBLIC_CURSOR_SIGNING_SECRET
);

const position = await decodeCursor(cursor, process.env.PUBLIC_CURSOR_SIGNING_SECRET, {
	resource: "schedules",
	order: "scheduled_at:asc,id:asc",
	scope: { workspace_id: workspaceId, brand_id: brandId }
});

The payload is opaque and tamper-evident, not encrypted. Do not place secrets or provider payloads in sort values or IDs. Error-detail producers remain responsible for allowlisting and redacting values before validating them against the bounded public schema.

responseMetadataSchema.pagination temporarily accepts a strict legacy offset variant as well as the canonical cursor shape. New collections should validate directly with cursorPaginationSchema; the offset schema exists only so response-envelope migration does not break live V1 collections.