@apollo-deploy/schemas
v1.5.1
Published
Cross-language type definitions using JSON Schema for Apollo Deploy monorepo
Downloads
2,141
Readme
@apollo-deploy/schemas
Cross-language type definitions for Apollo Deploy using JSON Schema and Zod.
This package provides a single source of truth for all API schemas across the Apollo Deploy platform, enabling type-safe development in TypeScript services and cross-language compatibility for non-TypeScript services (Zig, Rust, Go).
Overview
@apollo-deploy/schemas is a comprehensive schema package that:
- Defines all API types using Zod for runtime validation and TypeScript type inference
- Generates JSON Schema files for cross-language compatibility
- Organizes schemas by domain for easy discovery and modular imports
- Provides subpath imports to minimize bundle size and improve tree-shaking
- Maintains a single source of truth for all type definitions across the monorepo
Key Features
- ✅ Type-Safe: Full TypeScript support with Zod schema validation
- ✅ Cross-Language: JSON Schema files for Zig, Rust, Go, and other languages
- ✅ Modular: Domain-based organization with subpath imports
- ✅ Performant: Optimized for tree-shaking and minimal bundle size
- ✅ Well-Documented: Comprehensive JSDoc comments and examples
- ✅ Maintainable: Single source of truth prevents schema duplication
Installation
This package is published publicly to npm and expects zod as a peer dependency.
npm install @apollo-deploy/schemas zod
# or
yarn add @apollo-deploy/schemas zod
# or
bun add @apollo-deploy/schemas zodInside this monorepo, prefer the workspace package directly:
{
"dependencies": {
"@apollo-deploy/schemas": "workspace:*"
}
}Quick Start
TypeScript - Import from Root
import {
AppSchema,
AppCreateSchema,
AppResponseSchema,
type App,
type AppCreateInput,
type AppResponse,
} from '@apollo-deploy/schemas';
// Validate input
const input = AppCreateSchema.parse(userInput);
// Use types
const app: App = await createApp(input);TypeScript - Subpath Imports (Recommended)
For better tree-shaking, import from specific domains:
// Apps domain
import {
AppSchema,
AppCreateSchema,
AppResponseSchema,
type App,
type AppCreateInput,
} from '@apollo-deploy/schemas/apps';
// Artifacts domain
import {
ArtifactSchema,
CreateArtifactSchema,
type Artifact,
type CreateArtifactInput,
} from '@apollo-deploy/schemas/artifacts';
// Credentials domain
import {
CredentialSchema,
CredentialCreateSchema,
type Credential,
type CredentialCreateInput,
} from '@apollo-deploy/schemas/credentials';Non-TypeScript Services
Use the generated JSON Schema files for code generation:
# Copy JSON schema files to your project
cp packages/schemas/generated/*.schema.json ./schemas/
# Use with your language's JSON Schema tools
# Zig: Use with zig-json-schema
# Rust: Use with serde_json and json-schema crates
# Go: Use with go-json-schemaWhat Belongs Here
Add a contract to packages/schemas when it is a shared wire contract that must be consumed by more than one surface, such as:
- API request or response shapes used by clients, SDK generation, OpenAPI export, or multiple services
- Transport contracts that need both runtime validation and published TypeScript types
- Schemas that need generated JSON Schema output for non-TypeScript consumers
Keep a contract out of packages/schemas when it is private to a single backend module, such as:
- Service-internal request shapes for admin or internal-only routes
- Persistence-only or domain-only model types
- Temporary module-local adapters that are not part of a shared API surface
For apps/api feature modules, the intended pattern is:
contracts/global/*wraps imports from@apollo-deploy/schemascontracts/internal/*owns service-private transport schemas
If you already export a top-level response contract from this package, prefer deriving nested helper types from that exported contract instead of redefining client DTOs in consumers:
import type {
IntegrationsAvailableIntegration,
IntegrationsAppIntegration,
} from '@apollo-deploy/schemas/integrations';
type ConnectionSurface = IntegrationsAvailableIntegration['connection'];
type AppConfigSurface = IntegrationsAppIntegration['appConfig'];Schema Registry Maintenance
This package includes automation to ensure every exported *Schema constant
is registered with z.globalRegistry.
# Check for missing z.globalRegistry.add(...) entries
bun run registry:check
# Auto-add any missing registrations across all *.schema.ts files
bun run registry:fixDevelopment Workflow
After changing schema sources, run the package workflow in this order:
cd packages/schemas
# Ensure all exported schemas are registered with z.globalRegistry
bun run registry:check
# Generate JSON Schema output
bun run generate
# Refresh dist JS and .d.ts files used by subpath consumers
bun run buildUse bun run registry:fix if registry:check reports missing registrations.
The build step matters for local consumers in this monorepo: workspace references can continue reading stale declarations from dist/ until the package is rebuilt.
Available Domains
The package currently publishes these main entrypoints and subpaths:
| Domain | Purpose | Subpath |
|--------|---------|---------|
| Common | Shared schemas, utilities, cross-domain enums | @apollo-deploy/schemas |
| Definitions | Aggregate re-export of all definitions | @apollo-deploy/schemas/definitions |
| Generators | Generator helpers and tooling exports | @apollo-deploy/schemas/generators |
| Admin Users | Admin user management | @apollo-deploy/schemas/admin-users |
| Analytics | Analytics data and reporting contracts | @apollo-deploy/schemas/analytics |
| API Keys | API key management | @apollo-deploy/schemas/api-keys |
| Apps | Application management | @apollo-deploy/schemas/apps |
| Approvals | Approval and review workflows | @apollo-deploy/schemas/approvals |
| Artifacts | Build artifacts (APK, IPA, etc.) | @apollo-deploy/schemas/artifacts |
| Audit Log | Audit logging | @apollo-deploy/schemas/audit-log |
| Auth | Authentication, OAuth, roles, permissions | @apollo-deploy/schemas/auth |
| Billing | Subscriptions, plans, and billing usage | @apollo-deploy/schemas/billing |
| Credentials | Store credentials | @apollo-deploy/schemas/credentials |
| CVE Scanner | Vulnerability scanning contracts | @apollo-deploy/schemas/cve-scanner |
| Integrations | Third-party integrations | @apollo-deploy/schemas/integrations |
| Marketplace | Marketplace listings and discovery | @apollo-deploy/schemas/marketplace |
| Organizations | Organization management | @apollo-deploy/schemas/orgs |
| Releases | Release management | @apollo-deploy/schemas/releases |
| Service Accounts | Service account management | @apollo-deploy/schemas/service-accounts |
| Stores | Store connections | @apollo-deploy/schemas/stores |
| Sessions | Session management | @apollo-deploy/schemas/sessions |
| Settings | Org and user settings surfaces | @apollo-deploy/schemas/settings |
| Share Links | Shareable artifact links | @apollo-deploy/schemas/share-links |
| Teams | Team management | @apollo-deploy/schemas/teams |
| Webhooks | Webhook configuration | @apollo-deploy/schemas/webhooks |
Some source directories may exist in src/definitions/ without a dedicated published subpath yet. For external consumers, treat the exports map in package.json as the source of truth.
Package Layout
Most domains follow the same structure under src/definitions/<domain>/:
Domain Schemas (domain.schema.ts)
Core entity definitions and reusable domain-level schema fragments:
import { AppSchema, type App } from '@apollo-deploy/schemas/apps';
const app: App = {
id: 'app_123',
name: 'My App',
packages: { android: 'com.example.app' },
// ...
};Request Schemas (request.schema.ts)
Input validation for API requests:
import { AppCreateSchema, type AppCreateInput } from '@apollo-deploy/schemas/apps';
const input: AppCreateInput = AppCreateSchema.parse({
name: 'My App',
packages: { android: 'com.example.app' },
});Response Schemas (response.schema.ts)
Output validation for API responses:
import { AppResponseSchema, type AppResponse } from '@apollo-deploy/schemas/apps';
const response: AppResponse = AppResponseSchema.parse(apiResponse);Not every domain needs all three files. Some domains expose only request and response contracts, while common cross-domain primitives live in packages/schemas/src/definitions/common.ts.
TypeScript Examples
Validation
import { AppCreateSchema, type AppCreateInput } from '@apollo-deploy/schemas/apps';
// Validate and parse input
try {
const input: AppCreateInput = AppCreateSchema.parse(userInput);
console.log('Valid input:', input);
} catch (error) {
console.error('Validation failed:', error.errors);
}
// Safe parsing (returns result object)
const result = AppCreateSchema.safeParse(userInput);
if (result.success) {
console.log('Valid:', result.data);
} else {
console.error('Invalid:', result.error.flatten());
}Type Inference
import { AppCreateSchema } from '@apollo-deploy/schemas/apps';
// Infer type from schema
type AppCreateInput = typeof AppCreateSchema._type;
// Or use explicit type import
import type { AppCreateInput } from '@apollo-deploy/schemas/apps';Pagination
import { AppListEnvelopeSchema, type AppListEnvelope } from '@apollo-deploy/schemas/apps';
const response: AppListEnvelope = {
data: [
{ id: 'app_1', name: 'App 1', /* ... */ },
{ id: 'app_2', name: 'App 2', /* ... */ },
],
page: {
size: 2,
totalPages: 5,
hasMore: true,
},
};JSON Schema Examples
Using with Zig
const std = @import("std");
const json = std.json;
// Load schema
const schema_text = @embedFile("schemas/apps.schema.json");
const schema = try json.parseFromSlice(json.Value, allocator, schema_text, .{});
// Generate types or validate dataUsing with Rust
use serde_json::json;
use jsonschema::JSONSchema;
// Load schema
let schema_text = include_str!("../schemas/apps.schema.json");
let schema = serde_json::from_str(schema_text)?;
let validator = JSONSchema::compile(&schema)?;
// Validate data
let data = json!({ "name": "My App", "packages": { "android": "com.example.app" } });
validator.validate(&data)?;Using with Go
import (
"encoding/json"
"github.com/xeipuuv/gojsonschema"
)
// Load schema
schemaLoader := gojsonschema.NewReferenceLoader("file:///schemas/apps.schema.json")
schema, _ := gojsonschema.NewSchema(schemaLoader)
// Validate data
documentLoader := gojsonschema.NewGoLoader(data)
result, _ := schema.Validate(documentLoader)Schema Regeneration
JSON Schema output is generated explicitly, not as part of bun run build.
cd packages/schemas
bun run generateThis updates the checked-in files under packages/schemas/generated/.
If you changed exported TypeScript types or subpath barrels, also rebuild afterward:
cd packages/schemas
bun run buildWhen removing a schema surface or export, watch for stale files in both generated/ and dist/. A source removal does not always delete obsolete generated artifacts automatically.
Contributing
Adding a New Domain
- Decide whether it is actually shared:
- If the contract is only used by one backend module, keep it local instead of adding it here.
- If it is part of a shared API surface, continue.
Create domain directory:
mkdir -p packages/schemas/src/definitions/my-domainCreate schema files:
domain.schema.ts- Entity definitionsrequest.schema.ts- Request validationresponse.schema.ts- Response structuresindex.ts- Domain exports
Update exports:
- Add exports to
src/definitions/index.ts - Add subpath export to
package.json - Update this README if the new domain is intended for external consumers
- Add exports to
Register schemas:
bun run registry:check # or bun run registry:fixGenerate schemas:
bun run generateBuild the package: Run
bun run build.Commit changes:
git add packages/schemas/ git commit -m "feat: add my-domain schemas"
Schema Best Practices
- Only add shared wire contracts - keep service-private contracts in the owning module
- Use Zod refinements for complex validation logic
- Add JSDoc comments to all exported schemas
- Keep schemas focused - one concern per schema
- Reuse common schemas - import from
common.ts - Prefer deriving nested helper types from exported top-level contracts rather than redefining DTOs downstream
- Keep
z.globalRegistrycomplete - runregistry:checkorregistry:fixafter adding schemas - Test schema validation - add unit tests for complex schemas
- Document breaking changes - update CHANGELOG.md
Testing Schemas
import { describe, it, expect } from 'bun:test';
import { AppCreateSchema } from '@apollo-deploy/schemas/apps';
describe('AppCreateSchema', () => {
it('should validate valid input', () => {
const input = {
name: 'My App',
packages: { android: 'com.example.app' },
};
expect(() => AppCreateSchema.parse(input)).not.toThrow();
});
it('should reject invalid input', () => {
const input = { name: '' }; // Invalid: empty name
expect(() => AppCreateSchema.parse(input)).toThrow();
});
});API Reference
Common Schemas
// Pagination
import { PaginationSchema, PaginationMetaSchema } from '@apollo-deploy/schemas';
// Enums
import { PlatformSchema, StoreProviderSchema, StatusSchema } from '@apollo-deploy/schemas';
// Utilities
import { UUIDSchema, DateTimeSchema, UrlSchema } from '@apollo-deploy/schemas';Authentication
import {
UserRoleSchema,
OrgRoleSchema,
TeamRoleSchema,
PermissionSchema,
} from '@apollo-deploy/schemas';Domain Imports
// Apps
import { AppSchema, AppCreateSchema, AppResponseSchema } from '@apollo-deploy/schemas/apps';
// Artifacts
import { ArtifactSchema, CreateArtifactSchema } from '@apollo-deploy/schemas/artifacts';
// Credentials
import { CredentialSchema, CredentialCreateSchema } from '@apollo-deploy/schemas/credentials';
// And so on for other domains...Troubleshooting
Import Errors
Problem: Cannot find module '@apollo-deploy/schemas/apps'
Solution: Ensure the package is installed and the subpath export is defined in package.json.
Type Errors
Problem: Type 'AppCreateInput' is not assignable to type 'App'
Solution: Use the correct schema type. AppCreateInput is for creating apps, App is the full entity type.
Validation Errors
Problem: Validation failed: [{"code":"too_small","minimum":3,"type":"string","path":["name"],"message":"String must contain at least 3 characters"}]
Solution: Ensure input meets all schema requirements. Check the error details for specific field requirements.
Performance
- Bundle Size: Subpath imports enable tree-shaking (~5KB per domain)
- Validation Speed: Zod schemas are compiled once at import time
- JSON Schema Generation: Runs in <1s for all domains
License
This package is part of Apollo Deploy and follows the same license as the main repository.
