Enterprise-ready reusable schema definitions for Product SaaS applications. Provides comprehensive, type-safe, and validated schemas using Zod for TypeScript-first development.
β Type-Safe - Full TypeScript support with inferred types β Validation - Built-in validation using Zod β Request Middleware - Express.js and Fastify middleware for automatic validation β Cross-Field Validation - Support for complex field relationships β Enterprise-Ready - Schemas for multi-tenant SaaS applications β Comprehensive - Covers core entities, auth, products, billing, and APIs β Extensible - Easy to extend and customize for your needs β Zero Runtime Dependencies - Minimal dependencies (only Zod) β Well-Documented - Extensive examples and documentation
npm install @kitium-ai/schema
# or
yarn add @kitium-ai/schema
# or
pnpm add @kitium-ai/schemaimport { UserSchema, validate } from '@kitium-ai/schema';
const userData = {
id: '123e4567-e89b-12d3-a456-426614174000',
email: '[email protected]',
firstName: 'John',
lastName: 'Doe',
status: 'active',
emailVerified: true,
createdAt: new Date(),
updatedAt: new Date(),
};
const result = validate(UserSchema, userData);
if (result.success) {
console.log('Valid user:', result.data);
} else {
console.error('Validation errors:', result.errors);
}Core entities for user and organization management:
- User - User account management with preferences
- Organization - Multi-tenant organization management
- Team - Team management within organizations
- Role - Role-based access control (RBAC)
- Permission - Fine-grained permission management
import {
UserSchema,
OrganizationSchema,
RoleSchema,
CreateUserSchema,
CreateOrganizationSchema,
validate,
} from '@kitium-ai/schema/core';
// Validate user creation
const result = validate(CreateUserSchema, {
email: '[email protected]',
password: 'SecurePass123!',
firstName: 'John',
lastName: 'Doe',
acceptTerms: true,
});Authentication, login, and token management:
- AuthToken - Access and refresh tokens
- Session - User sessions with activity tracking
- MFASettings - Multi-factor authentication configuration
- LoginCredentials - Login request validation
- PasswordReset - Password reset flow
- OAuthInput - OAuth provider integration
import {
LoginCredentialsSchema,
RegisterInputSchema,
PasswordResetSchema,
validate,
} from '@kitium-ai/schema/auth';
// Validate login
const loginResult = validate(LoginCredentialsSchema, {
email: '[email protected]',
password: 'password123',
rememberMe: true,
});
// Validate registration
const regResult = validate(RegisterInputSchema, {
email: '[email protected]',
password: 'SecurePass123!',
firstName: 'Jane',
lastName: 'Doe',
organizationName: 'Acme Corp',
acceptTerms: true,
});Team member management and invitations:
- TeamMember - Organization team members
- OrganizationInvitation - Invitation system
- InviteMember - Invite member request
import {
InviteMemberSchema,
UpdateTeamMemberSchema,
validate,
} from '@kitium-ai/schema/organization';
// Validate team member invitation
const inviteResult = validate(InviteMemberSchema, {
email: '[email protected]',
roleIds: ['role-uuid-1', 'role-uuid-2'],
message: 'Welcome to our team!',
expiresIn: 7,
});Features, workspaces, and integrations:
- Feature - Feature flags and feature management
- Workspace - Project workspaces
- WorkspaceMember - Workspace member management
- Integration - Third-party integrations
- IntegrationCredential - Integration credentials
import {
CreateFeatureSchema,
CreateWorkspaceSchema,
CreateIntegrationSchema,
validate,
} from '@kitium-ai/schema/product';
// Create feature flag
const featureResult = validate(CreateFeatureSchema, {
name: 'New Dashboard',
key: 'new_dashboard',
description: 'Experimental new dashboard design',
type: 'feature',
enabled: false,
rolloutPercentage: 10,
});
// Create workspace
const workspaceResult = validate(CreateWorkspaceSchema, {
name: 'Engineering',
description: 'Engineering team workspace',
visibility: 'private',
});
// Create integration
const integrationResult = validate(CreateIntegrationSchema, {
name: 'Stripe Payment',
key: 'stripe_payment',
type: 'api',
config: {
apiVersion: '2023-10-16',
environment: 'production',
},
});Subscriptions, payments, and invoicing:
- Plan - Pricing plans
- Subscription - Customer subscriptions
- Invoice - Invoice generation and tracking
- Payment - Payment processing
- PaymentMethod - Payment method management
- Refund - Refund handling
import {
CreatePlanSchema,
CreateSubscriptionSchema,
CreateInvoiceSchema,
CreatePaymentSchema,
validate,
} from '@kitium-ai/schema/billing';
// Create pricing plan
const planResult = validate(CreatePlanSchema, {
name: 'Pro Plan',
key: 'pro',
price: 99.99,
currency: 'USD',
billingCycle: 'monthly',
features: [
{ name: 'Users', included: true, limit: 50 },
{ name: 'Custom Integrations', included: true, limit: 10 },
{ name: 'API Access', included: true },
],
});
// Create subscription
const subResult = validate(CreateSubscriptionSchema, {
planId: 'plan-uuid',
autoRenew: true,
});
// Create invoice
const invoiceResult = validate(CreateInvoiceSchema, {
subscriptionId: 'sub-uuid',
items: [
{
description: 'Monthly subscription',
quantity: 1,
unitPrice: 99.99,
amount: 99.99,
},
],
dueDate: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000),
});Standardized request and response structures:
- QueryParams - Pagination and filtering
- ListRequest - List requests with advanced filtering
- ApiRequest - Standardized request wrapper
- ApiResponse - Standardized response wrapper
- PaginatedApiResponse - Paginated responses
- BulkResponse - Bulk operation responses
import {
QueryParamsSchema,
ListRequestSchema,
ApiResponseSchema,
PaginatedApiResponseSchema,
validate,
} from '@kitium-ai/schema/api';
// Validate list query
const queryResult = validate(QueryParamsSchema, {
page: 1,
limit: 20,
sort: 'createdAt:desc',
search: 'john',
});
// Validate advanced filtering
const listResult = validate(ListRequestSchema, {
page: 1,
limit: 50,
filter: { status: 'active' },
sort: 'name:asc',
includeArchived: false,
});
// Type-safe response
const createResponseSchema = ApiResponseSchema(
z.object({
id: z.string().uuid(),
name: z.string(),
}),
);
const apiResult = validate(createResponseSchema, {
success: true,
data: {
id: '123e4567-e89b-12d3-a456-426614174000',
name: 'Created Item',
},
});The package includes built-in middleware for automatic request validation in Express.js and Fastify applications.
Use middleware functions to automatically validate request body, query, params, and headers:
import express from 'express';
import {
validateBody,
validateQuery,
validateParams,
validateHeaders,
validationErrorHandler,
} from '@kitium-ai/schema';
import {
CreateUserSchema,
QueryParamsSchema,
UserParamsSchema,
} from '@kitium-ai/schema';
const app = express();
app.use(express.json());
// Validate single source
app.post(
'/users',
validateBody(CreateUserSchema),
(req, res) => {
// req.body is validated and type-safe
res.json({ user: req.body });
},
);
// Validate multiple sources
app.get(
'/users/:id',
validateParams(UserParamsSchema),
validateQuery(QueryParamsSchema),
(req, res) => {
// req.params and req.query are validated
res.json({ user: req.params });
},
);
// Error handling middleware (place after all routes)
app.use(validationErrorHandler());Register validation as a Fastify plugin:
import Fastify from 'fastify';
import { createValidationPlugin } from '@kitium-ai/schema';
import { CreateUserSchema, QueryParamsSchema } from '@kitium-ai/schema';
const fastify = Fastify();
// Register validation plugin
fastify.register(
createValidationPlugin({
body: CreateUserSchema,
query: QueryParamsSchema,
}),
);
fastify.post('/users', async (request, reply) => {
// request.body and request.query are validated
reply.send({ user: request.body });
});Validate relationships between fields:
import { validateWithCrossFields } from '@kitium-ai/schema';
import { UpdateUserSchema } from '@kitium-ai/schema';
const result = validateWithCrossFields(
UpdateUserSchema,
{
email: '[email protected]',
password: 'NewPass123!',
passwordConfirm: 'NewPass123!',
},
[
{
condition: (data) => data.password === data.passwordConfirm,
message: 'Passwords must match',
fields: ['password', 'passwordConfirm'],
},
],
);
if (!result.success) {
console.log('Validation errors:', result.errors);
console.log('Field dependencies:', result.fieldDependencies);
}Validate based on conditions:
import { validateConditional, validateMultiple } from '@kitium-ai/schema';
import { UserSchema, BillingSchema } from '@kitium-ai/schema';
// Validate only if condition is true
const isPremium = true;
const result = validateConditional(
BillingSchema,
userData,
() => isPremium,
);
// Validate multiple schemas
const multiResult = validateMultiple(
{
user: UserSchema,
billing: BillingSchema,
},
data,
);Map validation errors to custom messages:
import {
validate,
createErrorMessageMapper,
} from '@kitium-ai/schema';
import { CreateUserSchema } from '@kitium-ai/schema';
const errorMapper = createErrorMessageMapper({
email: {
invalid_string: 'Please provide a valid email address',
},
password: {
too_small: 'Password must be at least 8 characters',
},
});
const result = validate(CreateUserSchema, data);
if (!result.success && result.errors) {
const customErrors = errorMapper(result.errors);
console.log('User-friendly errors:', customErrors);
}Powerful utility functions for advanced validation scenarios:
import {
filterErrorsByField,
sanitizeData,
createBatchValidator,
createTypeGuard,
extendSchema,
} from '@kitium-ai/schema';
import { UserSchema } from '@kitium-ai/schema';
// Filter errors by specific fields
const emailErrors = filterErrorsByField(result.errors, ['email']);
// Remove null/undefined values
const clean = sanitizeData({ name: 'John', age: null });
// Batch validate items
const batchValidator = createBatchValidator(UserSchema);
const batchResult = batchValidator([user1, user2, user3]);
// Create type guard from schema
const isValidUser = createTypeGuard(UserSchema);
if (isValidUser(data)) {
// data is typed as User
}
// Extend existing schema
const ExtendedUserSchema = extendSchema(UserSchema, {
metadata: z.record(z.string()),
});The package provides convenient validation utilities:
Validates data and returns a result object (no exceptions):
import { UserSchema, validate } from '@kitium-ai/schema';
const result = validate(UserSchema, userData);
if (result.success) {
console.log('Data:', result.data); // Type is UserSchema
} else {
console.log('Errors:', result.errors);
// errors is ValidationErrorDetail[]
}Validates data and throws if invalid:
import { UserSchema, validateOrThrow } from '@kitium-ai/schema';
try {
const user = validateOrThrow(UserSchema, userData);
console.log('Valid user:', user);
} catch (error) {
console.error('Validation failed:', error.message);
}Async validation (useful for async validators):
import { UserSchema, validateAsync } from '@kitium-ai/schema';
const result = await validateAsync(UserSchema, userData);
if (result.success) {
console.log('Valid user:', result.data);
}Type-safe validation check:
import { UserSchema, isValid } from '@kitium-ai/schema';
if (isValid(UserSchema, userData)) {
// userData is now typed as ValidatedUser
console.log(userData.email);
}Validate multiple items:
import { UserSchema, validateBatch } from '@kitium-ai/schema';
const results = validateBatch(UserSchema, [user1, user2, user3]);
results.forEach((result) => {
if (result.success) {
console.log('Valid:', result.data);
} else {
console.log('Errors:', result.errors);
}
});Validate only specific fields:
import { UserSchema, partialValidate } from '@kitium-ai/schema';
const result = partialValidate(UserSchema, userData, ['email', 'firstName']);
// Only validates the specified fieldsAll schemas support TypeScript type inference:
import {
UserSchema,
CreateUserSchema,
ValidatedUser,
ValidatedCreateUser,
UpdateUserSchema,
ValidatedUpdateUser,
} from '@kitium-ai/schema/core';
// Using inferred types from validation
const result = validate(UserSchema, data);
if (result.success) {
const user: ValidatedUser = result.data;
// user is properly typed
}
// Pre-defined validated types
const createUser: ValidatedCreateUser = {
email: '[email protected]',
password: 'SecurePass123!',
firstName: 'John',
lastName: 'Doe',
// ... other fields
};Comprehensive error handling with detailed validation messages:
import { validate } from '@kitium-ai/schema';
const result = validate(UserSchema, invalidData);
if (!result.success) {
result.errors?.forEach((error) => {
console.log(`Field: ${error.field}`);
console.log(`Message: ${error.message}`);
console.log(`Code: ${error.code}`);
});
}
// Or use the ValidationError class
import { ValidationError, validateOrThrow } from '@kitium-ai/schema';
try {
validateOrThrow(UserSchema, data);
} catch (error) {
if (error instanceof ValidationError) {
console.log('Validation errors:', error.errors);
}
}All schemas utilize common types for consistency:
import {
UUID,
Email,
URL,
Status,
SubscriptionStatus,
PaymentStatus,
Permission,
PermissionAction,
WebhookEventType,
AuditLog,
} from '@kitium-ai/schema/common';
// Use branded types for type safety
const userId: UUID = generateUUID();
const email: Email = '[email protected]';
const website: URL = 'https://example.com';
// Use enums for consistent status values
const status: Status = 'active';
const subStatus: SubscriptionStatus = 'active';The schemas implement security best practices:
- Password Validation - Requires uppercase, lowercase, numbers, and special characters
- Email Validation - Uses email validation rules
- URL Validation - Validates URLs are properly formatted
- Data Encryption - Credentials are marked as encrypted in billing schemas
- Permission Controls - Fine-grained RBAC support
- Audit Logging - Support for audit trails
Using automatic request validation middleware:
import express, { Request, Response } from 'express';
import {
validateBody,
validateQuery,
validationErrorHandler,
} from '@kitium-ai/schema';
import { CreateUserSchema, QueryParamsSchema } from '@kitium-ai/schema';
const app = express();
app.use(express.json());
// Automatic validation with middleware
app.post(
'/api/users',
validateBody(CreateUserSchema),
(req: Request, res: Response) => {
// req.body is already validated and type-safe
const user = req.body;
res.status(201).json({ success: true, data: user });
},
);
// Error handling
app.use(validationErrorHandler());import express, { Request, Response } from 'express';
import { CreateUserSchema, validate } from '@kitium-ai/schema';
const app = express();
app.post('/api/users', (req: Request, res: Response) => {
const result = validate(CreateUserSchema, req.body);
if (!result.success) {
return res.status(400).json({
success: false,
errors: result.errors,
});
}
// Process valid user
const user = result.data;
// ...
});import { UserSchema, validate } from '@kitium-ai/schema';
const UserType = new GraphQLObjectType({
name: 'User',
fields: {
id: { type: GraphQLID },
email: { type: GraphQLString },
firstName: { type: GraphQLString },
lastName: { type: GraphQLString },
},
});
const resolvers = {
Mutation: {
createUser: async (_: any, args: any) => {
const result = validate(CreateUserSchema, args);
if (!result.success) {
throw new Error('Validation failed');
}
return createUserInDB(result.data);
},
},
};import { NextApiRequest, NextApiResponse } from 'next';
import { validate, CreateUserSchema } from '@kitium-ai/schema';
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
const result = validate(CreateUserSchema, req.body);
if (!result.success) {
return res.status(400).json({
success: false,
errors: result.errors,
});
}
// Process valid user
const user = await db.users.create(result.data);
res.status(201).json({ success: true, data: user });
}// Before
interface User {
id: string;
email: string;
firstName: string;
lastName: string;
}
// After
import { UserSchema, ValidatedUser } from '@kitium-ai/schema';
const result = validate(UserSchema, userData);
const user: ValidatedUser = result.data!;// Before
function validateUser(data: any) {
if (!data.email || !data.email.includes('@')) {
throw new Error('Invalid email');
}
// ... more validation
}
// After
import { CreateUserSchema, validate } from '@kitium-ai/schema';
const result = validate(CreateUserSchema, data);
if (!result.success) {
// Handle validation errors
}For detailed API reference, see API_REFERENCE.md
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
MIT
- π Documentation
- π Issues
- π¬ Discussions