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

@ezstart/api-contracts

v2.0.1

Published

Wire contracts (TypeScript types + Zod schemas) shared between @ezstart API clients and servers — envelope, pagination, error codes, auth flows.

Readme

@ezstart/api-contracts

Wire contracts (TypeScript types + Zod schemas) shared between @ezstart/api-sdk (client) and the future @ezstart/api-core (server framework).

Install

pnpm add @ezstart/api-contracts zod

zod is a peer dependency (^3.23.0) so consumers stay on a single Zod instance.

Quickstart

Client — discriminate the response envelope

import { isSuccessResponse, type ApiResponse } from '@ezstart/api-contracts'

const body: ApiResponse<{ id: string; email: string }> = await fetchJson('/api/me')

if (isSuccessResponse(body)) {
  body.data.email // → string (fully typed)
} else {
  body.error // → ErrorPayload | string (narrow at use-site)
}

Server — validate pagination query

import { PaginationQuerySchema } from '@ezstart/api-contracts'

app.get('/api/users', (req, res) => {
  const { limit, offset } = PaginationQuerySchema.parse(req.query)
  // limit: 1..100 (default 20), offset: >= 0 (default 0)
})

Shared — standardized error codes

import { ErrorCode } from '@ezstart/api-contracts'

if (err.code === ErrorCode.RATE_LIMIT_EXCEEDED) {
  await sleep(err.retryAfter ?? 60)
}

Auth — Zod schemas shared by client and server

import { LoginRequestSchema, type LoginRequest } from '@ezstart/api-contracts'

// server
const parsed = LoginRequestSchema.safeParse(req.body)
if (!parsed.success) return res.status(400).json({ issues: parsed.error.issues })

// client
const body: LoginRequest = { email, password, app: 'myapp' }

API

Envelope (envelope.ts)

| Export | Kind | Purpose | | -------------------- | ----- | --------------------------------------------------- | | SuccessResponse<T> | type | { success: true, data: T, meta?: ApiMeta } | | ErrorResponse | type | { success: false, error: ErrorPayload \| string } | | ErrorPayload | type | { message, code?, details?, retryAfter? } | | ApiResponse<T> | type | Union SuccessResponse<T> \| ErrorResponse | | isSuccessResponse | guard | Narrows unknown → SuccessResponse<T> | | isErrorResponse | guard | Narrows unknown → ErrorResponse |

Pagination (pagination.ts)

| Export | Kind | Purpose | | ----------------------- | ---- | ---------------------------------------------------- | | ApiMeta | type | Permissive meta (indexable) | | PaginationMeta | type | { total, limit, offset } (all numbers) | | PaginatedResponse<T> | type | { data: T[], meta: PaginationMeta } | | PaginationQuerySchema | Zod | Validates GET list querystring (default 20, max 100) | | PaginationQuery | type | z.infer<typeof PaginationQuerySchema> |

Errors (errors.ts)

ErrorCode — frozen object + matching union type. Codes:

  • Auth: UNAUTHORIZED, INVALID_TOKEN, INVALID_OR_EXPIRED_TOKEN, EMAIL_NOT_VERIFIED, TWO_FACTOR_REQUIRED
  • AuthZ: FORBIDDEN
  • Validation: VALIDATION_ERROR
  • Resources: NOT_FOUND, ALREADY_EXISTS, CONFLICT
  • Rate limit: RATE_LIMIT_EXCEEDED
  • Server/network: NETWORK_ERROR, INTERNAL_ERROR, SERVICE_UNAVAILABLE

NEVER rename or remove an existing code without a major version bump.

Auth (auth.ts)

Zod schemas + inferred types for the core auth endpoints:

  • LoginRequest / LoginResponse (union of LoginAuthCodeResponse and LoginTwoFactorPendingResponse)
  • RegisterRequest / RegisterResponse
  • QuickSignupRequest
  • ForgotPasswordRequest
  • ResetPasswordRequest
  • VerifyEmailRequest
  • SendVerificationRequest
  • RefreshRequest / RefreshResponse
  • TokenRequest / TokenResponse (auth code → access token exchange)
  • VerifyRequest / VerifyResponse
  • AuthUser (public user shape, never contains secrets)
  • SupportedLocale ('en' | 'fr' | 'vi')
  • EmailOverride (optional per-send template overrides)

More specialized flows (2FA enrollment, session listing, SSO authorize/exchange) are intentionally omitted from this first cut — they can be added without breaking these contracts.

Migration

This is a new package — no prior version to migrate from. Consumers that previously defined envelope / pagination / error shapes locally can adopt @ezstart/api-contracts additively: re-export the canonical types from here and delete the local duplicates when ready. Adoption is per-scope (envelope OR pagination OR errors OR auth), nothing is all-or-nothing.

1.x to 2.0.0

ApplicationSchema no longer has webhookEndpointUrl / webhookSecret (webhooks are an ezpay feature). Stop reading those fields; nothing else changed. Publish order: @ezstart/api-contracts 2.0.0, then @ezstart/auth-sdk 2.0.0.

Adoption

This package is consumed by:

  • @ezstart/api-sdk — client-side (envelope parsing, error codes)
  • @ezstart/api-core — server-side (helpers honor the same shapes)

Adopting it in any project (internal or external) guarantees wire compatibility with both ends, even without the @ezstart SDKs.

Related