@contract-kit/core
v0.1.2
Published
Core contract definitions and builders for contract-kit
Maintainers
Readme
@contract-kit/core
Core contract definitions and builders for Contract Kit
This package provides the foundation for defining type-safe API contracts that can be used across your entire stack. Contracts describe HTTP endpoints with full TypeScript support.
Installation
npm install @contract-kit/core
# Use with your preferred Standard Schema library
npm install zod
# or
npm install valibot
# or
npm install arktypeTypeScript Requirements
This package requires TypeScript 5.0 or higher for proper type inference.
Key Concepts
Contract
A contract is the single source of truth for an API endpoint. It describes:
- HTTP method and path (with path parameters)
- Path parameters, query parameters, and request body schemas
- Response schemas (per status code)
- Error schemas (per status code)
- Metadata for auth, rate limiting, idempotency, etc.
Contract Group
A contract group allows you to share configuration across related endpoints, such as a common namespace, authentication requirements, and error schemas.
Usage
Defining Contracts
import { z } from "zod";
import { createContractGroup } from "@contract-kit/core";
// Create a contract group for related endpoints
const todos = createContractGroup()
.namespace("todos")
.meta({ auth: "required" })
.errors({
401: z.object({ message: z.literal("Unauthorized") }),
403: z.object({ message: z.literal("Forbidden") }),
});
// Define schemas
const TodoSchema = z.object({
id: z.string(),
title: z.string(),
completed: z.boolean(),
});
const CreateTodoRequest = z.object({
title: z.string().min(1),
completed: z.boolean().optional(),
});
// Define contracts
export const getTodo = todos
.get("/api/todos/:id")
.path(z.object({ id: z.string() }))
.response(200, TodoSchema)
.errors({
404: z.object({
code: z.literal("TODO_NOT_FOUND"),
message: z.string()
}),
});
export const createTodo = todos
.post("/api/todos")
.body(CreateTodoRequest)
.response(201, TodoSchema);
export const listTodos = todos
.get("/api/todos")
.query(z.object({
completed: z.boolean().optional(),
limit: z.coerce.number().optional(),
}))
.response(200, z.array(TodoSchema));Contract Metadata
Use metadata to drive cross-cutting concerns like authentication, rate limiting, and idempotency:
const sendMessage = messages
.post("/api/messages")
.body(SendMessageRequest)
.response(201, SendMessageResponse)
.meta({
auth: "required",
idempotency: {
enabled: true,
header: "Idempotency-Key",
windowSeconds: 300,
},
rateLimit: {
max: 60,
window: "1m",
},
});OpenAPI Metadata
Add OpenAPI-specific metadata for documentation:
export const getTodo = todos
.get("/api/todos/:id")
.path(z.object({ id: z.string() }))
.response(200, TodoSchema)
.summary("Get a todo by ID")
.description("Retrieves a single todo item by its unique identifier")
.tags("todos")
.deprecated(false)
.operationId("getTodoById")
.externalDocs("https://docs.example.com/todos", "Todo documentation")
.security({ bearerAuth: [] });Schema Introspection
Contracts expose their schemas for runtime introspection:
getTodo.schema.path; // Path parameter schema
getTodo.schema.query; // Query parameter schema
getTodo.schema.body; // Request body schema
getTodo.schema.responses; // Response schemas by status code
getTodo.schema.errors; // Error schemas by status code
getTodo.pathTemplate; // "/api/todos/:id"
getTodo.method; // "GET"
getTodo.metadata; // { auth: "required", ... }API Reference
createContractGroup()
Creates a new contract group for defining related endpoints.
const group = createContractGroup()
.namespace("myNamespace") // Optional namespace prefix
.meta({ auth: "required" }) // Shared metadata
.errors({ // Shared error schemas
401: UnauthorizedSchema,
403: ForbiddenSchema,
});Contract Builder Methods
| Method | Description |
|--------|-------------|
| .get(path) | Define a GET endpoint |
| .post(path) | Define a POST endpoint |
| .put(path) | Define a PUT endpoint |
| .patch(path) | Define a PATCH endpoint |
| .delete(path) | Define a DELETE endpoint |
| .path(schema) | Define path parameter schema |
| .query(schema) | Define query parameter schema |
| .body(schema) | Define request body schema |
| .response(status, schema) | Define success response schema |
| .errors(schemas) | Define error response schemas |
| .meta(metadata) | Add custom metadata |
Standard Schema Support
This package works with any Standard Schema compatible library:
- Zod - Most popular, excellent TypeScript inference
- Valibot - Lightweight alternative to Zod
- ArkType - High-performance runtime validation
Related Packages
@contract-kit/client- HTTP client@contract-kit/next- Next.js server adapter@contract-kit/react-query- TanStack Query integration@contract-kit/react-hook-form- React Hook Form integration@contract-kit/server- Hexagonal framework for application composition@contract-kit/openapi- OpenAPI 3.1 generation
License
MIT
