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

@apollo-deploy/schemas

v1.7.0

Published

Cross-language type definitions using JSON Schema for Apollo Deploy monorepo

Readme

@apollo-deploy/schemas

Shared wire contracts for Apollo Deploy. This package is the single source of truth for types that cross the backend↔client boundary.

If a schema is only used inside one backend service, it does not belong here.


TL;DR (Read This First)

  1. This package is for shared wire contracts only — request/response shapes, public domain models, and enums consumed by both the backend and at least one external surface (SDK, web client, OpenAPI export, another service, or non-TS service).
  2. Backend-private schemas live in the owning module, not here. For apps/api, that is apps/api/src/modules/<module>/contracts/internal/.
  3. Only contracts/global/* inside an api module may import from this package. Other layers must go through the module's contracts/global wrapper.
  4. After changing schema sources, run, in order: registry:checkgeneratebuild.
  5. When unsure whether something is "shared", default to keeping it local. Promoting later is cheap. Un-promoting after consumers depend on it is not.

What This Package Is For

@apollo-deploy/schemas defines:

  • Zod schemas for runtime validation and TypeScript type inference
  • JSON Schema files for non-TypeScript consumers (Zig, Rust, Go, etc.)
  • Stable, versioned wire contracts that the backend and its clients agree on

It is consumed by:

  • apps/api — for request/response validation and OpenAPI generation
  • packages/typescript-sdk — generated from these contracts
  • The web client and other first-party clients
  • Non-TypeScript services that read the generated JSON Schema files

It is not a general-purpose type library. It is a contract surface.


When To Add A Schema Here

Add a schema to packages/schemas only if all of the following are true:

  • It defines data that crosses a process boundary (HTTP request/response, queue payload, webhook body, etc.).
  • It is consumed (or will be consumed) by at least one non-backend surface — SDK, web client, OpenAPI, third-party service, or non-TS service.
  • It needs both runtime validation (Zod) and a published TypeScript type.
  • It is intended to be stable — breaking changes require coordination with consumers.

Common examples that belong here:

  • Public REST request bodies, query params, path params, and response envelopes
  • Public domain entities exposed in API responses (AppSchema, ReleaseSchema, etc.)
  • Enums shared across request and response (ReleaseStatusSchema, PlatformSchema)
  • Webhook payload shapes
  • Anything that needs JSON Schema output for cross-language consumers

When Not To Add A Schema Here

Keep the schema local to the owning module if any of the following apply:

  • It is only used inside the backend (admin endpoints used by internal tooling are still backend-private unless that tooling is a separate published client).
  • It is a persistence-layer or domain-model type that is not part of any wire contract.
  • It is a transport-only request shape for a single internal route with no SDK/client consumer.
  • It is a temporary adapter, an in-flight refactor, or experimental.
  • It is a service-internal queue/job payload not exposed externally.

For apps/api modules the canonical home for these is:

apps/api/src/modules/<module>/contracts/internal/<name>.schema.ts

Internal contracts MUST NOT be imported from @apollo-deploy/schemas, MUST NOT be re-exported from this package, and MUST NOT be referenced by other services. If an internal schema later needs to be shared, promote it: move it here, register it, regenerate, and update the module's contracts/global wrapper to consume the shared version.


Decision Tree

Is this schema crossing a process boundary?
├── No  → Keep it in the owning module (domain/, application/, or contracts/internal).
└── Yes → Will any non-backend surface consume it?
         (SDK, web client, OpenAPI, third-party, non-TS service)
         ├── No  → Keep it in contracts/internal.
         └── Yes → Add it to packages/schemas.

When the answer is unclear, keep it local. Promotion is a one-line move; rollback is not.


How apps/api Modules Consume This Package

Per the workspace architecture (see AGENTS.md):

  • Only contracts/global/* inside a feature module may import from @apollo-deploy/schemas.
  • All other layers (controllers, services, infrastructure, route schemas) import from the module's contracts/global barrel.
  • This keeps the dependency on shared contracts explicit and easy to audit per module.
// apps/api/src/modules/apps/contracts/global/index.ts
export {
  AppSchema,
  AppCreateSchema,
  AppResponseSchema,
  type App,
  type AppCreateInput,
} from "@apollo-deploy/schemas/apps";
// apps/api/src/modules/apps/api/route-schema.ts
import { AppCreateSchema, AppResponseSchema } from "../contracts/global/index.js";

If you find yourself importing @apollo-deploy/schemas directly outside contracts/global/*, stop and route it through the module's barrel.


Installation

Public consumers:

bun add @apollo-deploy/schemas zod

Inside this monorepo, use the workspace reference:

{ "dependencies": { "@apollo-deploy/schemas": "workspace:*" } }

zod >= 4.0.0 is a peer dependency.


Quick Start

Prefer subpath imports for tree-shaking and clarity:

import {
  AppCreateSchema,
  AppResponseSchema,
  type AppCreateInput,
  type AppResponse,
} from "@apollo-deploy/schemas/apps";

const input: AppCreateInput = AppCreateSchema.parse(rawBody);

Root-level imports are supported but should be reserved for shared primitives:

import {
  PaginationSchema,
  PaginationMetaSchema,
  PlatformSchema,
} from "@apollo-deploy/schemas";

Non-TypeScript consumers should use the JSON Schema files under packages/schemas/generated/.


Available Subpaths

The exports map in package.json is the source of truth. Currently published subpaths:

| Domain | Subpath | |---|---| | Common (shared primitives, enums, pagination) | @apollo-deploy/schemas | | All definitions (aggregate barrel) | @apollo-deploy/schemas/definitions | | Generators (tooling) | @apollo-deploy/schemas/generators | | Admin Users | @apollo-deploy/schemas/admin-users | | Analytics | @apollo-deploy/schemas/analytics | | API Keys | @apollo-deploy/schemas/api-keys | | Apps | @apollo-deploy/schemas/apps | | Approvals | @apollo-deploy/schemas/approvals | | Artifacts | @apollo-deploy/schemas/artifacts | | Audit Log | @apollo-deploy/schemas/audit-log | | Auth | @apollo-deploy/schemas/auth | | Billing | @apollo-deploy/schemas/billing | | Credentials | @apollo-deploy/schemas/credentials | | CVE Scanner | @apollo-deploy/schemas/cve-scanner | | Apollo Signal — Email | @apollo-deploy/schemas/signal-email | | Integrations | @apollo-deploy/schemas/integrations | | Marketplace | @apollo-deploy/schemas/marketplace | | Organizations | @apollo-deploy/schemas/orgs | | Releases | @apollo-deploy/schemas/releases | | Service Accounts | @apollo-deploy/schemas/service-accounts | | Sessions | @apollo-deploy/schemas/sessions | | Settings | @apollo-deploy/schemas/settings | | Share Links | @apollo-deploy/schemas/share-links | | Stores | @apollo-deploy/schemas/stores | | Teams | @apollo-deploy/schemas/teams | | Webhooks | @apollo-deploy/schemas/webhooks |

Some directories under src/definitions/ may exist without a published subpath while a domain is still being shaped. Until a subpath is added to package.json, those are not considered shared contracts and external consumers must not depend on them.


Domain Folder Layout

Every domain under src/definitions/<domain>/ follows the same shape:

<domain>/
├── domain.schema.ts     # Entities, value objects, shared enums
├── request.schema.ts    # Inputs: query, params, bodies
├── response.schema.ts   # Outputs: response shapes, list envelopes
├── resources.schema.ts  # Optional: large auxiliary schemas tightly coupled to the domain
└── index.ts             # Barrel — re-exports only, no definitions

domain.schema.ts

Stable building blocks. Entities, value objects, and enums shared between request and response. No HTTP concerns.

request.schema.ts

Everything validating data into an endpoint: query params, path params, request bodies. Boundary-only refinements (e.g. coercion, .strict()) live here. Do not redeclare entity fields — compose from domain.schema.ts.

response.schema.ts

Everything describing data out of an endpoint: response bodies, paginated envelopes (typically via createPaginatedResponseSchema), domain-specific pagination metadata when it differs from the common shape.

resources.schema.ts (optional)

Use this when a domain has a secondary concept large enough to clutter domain.schema.ts but still tightly coupled to the domain. Examples in the current codebase:

  • api-keys/resources.schema.ts — the dynamic permission catalog
  • auth/resources.schema.tsROUTE_OAUTH_SCOPES, OAUTH_SCOPE_DESCRIPTIONS, scopeSatisfies

Do not create this file just to split things up. Small domains keep everything in domain.schema.ts.

index.ts

Re-exports only. No definitions, no logic. Apply aliases to avoid cross-domain name collisions (e.g. ApiKeyResponseSchema as OrganizationApiKeyResponseSchema).

Consumers import from the domain barrel or the package root. They must not reach into individual *.schema.ts files.


Authoring Rules

  • One concern per schema. Keep schemas focused.

  • Compose, don't duplicate. If a field appears in both request and response, define it in domain.schema.ts and import it.

  • Reuse common primitives (UUIDSchema, DateTimeSchema, PaginationSchema, etc.) from common.ts.

  • Document with JSDoc. Every exported schema gets a comment explaining what it represents and when it is used.

  • Derive nested helper types from exported response contracts rather than redefining client DTOs:

    import type { IntegrationsAppIntegration } from "@apollo-deploy/schemas/integrations";
    type AppConfigSurface = IntegrationsAppIntegration["appConfig"];
  • Register every exported *Schema with z.globalRegistry. The repo enforces this — see the registry section.

  • No HTTP concerns (status codes, framework-specific helpers) inside schema files. Those belong in the consuming module.

  • Treat exports as a public API. Breaking changes need a deliberate plan. Prefer additive evolution.


Schema Registry

Every exported *Schema constant must be registered with z.globalRegistry. This is automated:

bun run registry:check   # Fails if any exported *Schema is unregistered
bun run registry:fix     # Auto-adds missing registrations

CI enforces registry:check. Run registry:fix after adding new schemas.


Development Workflow

After changing schema sources, run these in order from packages/schemas/:

bun run registry:check   # 1. Confirm all schemas are registered (or run :fix)
bun run generate         # 2. Regenerate JSON Schema output under generated/
bun run build            # 3. Rebuild dist/ so workspace consumers see new types

The build step matters in this monorepo: workspace references read declarations from dist/, and stale builds will surface as confusing type errors in apps/api or the SDK.

When removing a schema or subpath, watch for stale files in generated/ and dist/. Source removal does not always delete obsolete artifacts — clean them up explicitly.

Validation Commands

bun run typecheck   # Type-only check
bun run test        # Bun test suite

Adding A New Domain

Before adding a new domain, confirm it is genuinely shared using the decision tree above. If it is backend-private, create it under the owning module's contracts/internal/ instead.

If it is shared:

  1. Create the domain folder:

    mkdir -p packages/schemas/src/definitions/my-domain
  2. Create the standard files: domain.schema.ts, request.schema.ts, response.schema.ts, optional resources.schema.ts, and index.ts.

  3. Wire exports:

    • Add the domain to src/definitions/index.ts.
    • Add a subpath to package.json exports (otherwise external consumers cannot import it).
    • Add a row to the subpath table in this README.
  4. Register schemas: bun run registry:fix.

  5. Generate: bun run generate.

  6. Build: bun run build.

  7. In each consuming apps/api module, expose the new types through contracts/global/ — never import @apollo-deploy/schemas from other layers.


JSON Schema For Non-TypeScript Services

Generated JSON Schema files live in packages/schemas/generated/ and are checked in. Copy or reference them from non-TS services:

// Zig, Rust, Go, etc. consume the *.schema.json files directly.
// See generated/ for the latest output.

Do not hand-edit files in generated/. They are produced by bun run generate.


Anti-Patterns

// ❌ Adding a backend-only admin endpoint schema here
// Belongs in apps/api/src/modules/<module>/contracts/internal/

// ❌ Importing from @apollo-deploy/schemas anywhere except contracts/global/*
// in an apps/api module
import { AppSchema } from "@apollo-deploy/schemas/apps"; // in controller.ts

// ✅ Route through the module's contracts/global barrel
import { AppSchema } from "../contracts/global/index.js";
// ❌ Redefining a published response shape in a client
type AppListResponse = { items: App[]; nextCursor?: string };

// ✅ Derive from the published contract
import type { AppListEnvelope } from "@apollo-deploy/schemas/apps";
type AppListResponse = AppListEnvelope;
// ❌ Inline definitions or logic in index.ts
export const Foo = z.object({ ... });

// ✅ index.ts re-exports only
export * from "./domain.schema.js";
export * from "./request.schema.js";
export * from "./response.schema.js";

Troubleshooting

Cannot find module '@apollo-deploy/schemas/<domain>' Add a subpath entry to package.json exports and run bun run build.

Stale types in apps/api after editing a schema Rebuild the package: bun run build from packages/schemas/. Workspace consumers read dist/.

registry:check fails Run bun run registry:fix, review the diff, commit.

Type errors after removing a schema Check generated/ and dist/ for stale files. Clean them up and rebuild.


Summary For AI Agents

When deciding where a new schema goes:

  1. If it is consumed only by apps/api (including admin/internal routes used by internal tooling that is not a separate published client), put it in apps/api/src/modules/<module>/contracts/internal/.
  2. If it is part of a wire contract consumed by the SDK, web client, OpenAPI export, or any non-backend surface, add it here.
  3. Inside apps/api modules, only contracts/global/* may import from @apollo-deploy/schemas. Always route through that wrapper.
  4. After changes: registry:checkgeneratebuild.
  5. When in doubt, keep the schema local. Promotion is easy; un-promotion is not.