Documentation Index
Fetch the complete documentation index at: https://www.orionjs.com/llms.txt
Use this file to discover all available pages before exploring further.
The schema package in Orionjs provides a powerful type-safe way to define data structures in your application. Schemas serve two main purposes:
- Define data structures: Schemas describe the structure, types, and validation rules for your data models.
- Automatic integration: Schemas automatically integrate with GraphQL for API generation and MongoDB for document validation.
Structure and Naming
- Use
schemaWithName() function from @orion-js/schema
- Follow naming conventions:
{EntityName}Schema for the schema, {EntityName} for the type
- Keep schemas focused on a single entity or concept
- Put schemas in
app/{component}/schemas/{EntityName}/index.ts
- Prefer
createEnum for enum types
- Avoid big entities; split them into smaller ones and use composition
- Use
typedId() for MongoDB document IDs
- Schema validation errors should be camelCase (e.g.,
priceMustBePositive)
Basic Usage
import {schemaWithName, InferSchemaType, createEnum} from '@orion-js/schema'
import {typedId} from '@orion-js/mongodb'
// Create a type-safe enum for product status
export const ProductStatusEnum = createEnum('ProductStatusEnum', [
'draft',
'active',
'discontinued'
] as const)
// Create a typed ID for products
export const typedProductId = typedId('prd')
export type ProductId = typeof typedProductId.__tsFieldType
export const ProductSchema = schemaWithName('Product', {
_id: {type: typedProductId},
name: {type: String, label: 'Product Name', min: 3, max: 100},
description: {type: String, optional: true},
status: {type: ProductStatusEnum, defaultValue: 'draft'},
price: {
type: Number,
validate: (value) => {
if (value < 0) return 'priceMustBePositive'
}
},
createdAt: {type: Date, defaultValue: () => new Date()}
})
// Infer the TypeScript type from your schema
export type Product = InferSchemaType<typeof ProductSchema>
// The type will be inferred as:
// type Product = {
// _id: `prd-${string}`;
// name: string;
// description?: string;
// status: "draft" | "active" | "discontinued";
// price: number;
// createdAt: Date;
// }
Nested Schemas
Create nested schemas for complex data structures:
import {schemaWithName, InferSchemaType} from '@orion-js/schema'
// Create a nested schema for product variants
export const ProductVariantSchema = schemaWithName('ProductVariant', {
name: {type: String, label: 'Variant Name', min: 2},
price: {type: Number, min: 0},
sku: {type: String, optional: true}
})
export type ProductVariant = InferSchemaType<typeof ProductVariantSchema>
export const ProductSchema = schemaWithName('Product', {
_id: {type: typedProductId},
name: {type: String},
variants: {type: [ProductVariantSchema], optional: true},
tags: {type: [String], optional: true}
})
export type Product = InferSchemaType<typeof ProductSchema>
Integration with GraphQL
Schemas defined with schemaWithName are automatically converted to GraphQL types when used in your API:
import {Query, Resolvers, createQuery} from '@orion-js/graphql'
import {ProductSchema} from '../schemas/Product'
@Resolvers()
export class ProductResolvers {
@Query()
product = createQuery({
params: {
productId: {type: typedProductId}
},
returns: ProductSchema,
resolve: async (params) => {
return product
}
})
}
When the above resolver is registered, Orionjs automatically:
- Creates a GraphQL type for
ProductSchema
- Sets up the appropriate field types based on your schema definition
- Handles type conversions between your application and GraphQL
Integration with MongoDB
When using schemas with MongoDB collections, Orionjs automatically validates documents:
import {createCollection} from '@orion-js/mongodb'
import {ProductSchema} from '../schemas/Product'
const Products = createCollection({
name: 'store.products',
schema: ProductSchema
})
// Document will be automatically validated against ProductSchema
await Products.insertOne({
name: 'Widget',
price: 29.99,
createdAt: new Date()
})
Common Schema Types
export const TypeExamplesSchema = schemaWithName('TypeExamples', {
stringField: {type: String}, // Text values
numberField: {type: Number}, // Numeric values (integers or floats)
integerField: {type: 'integer'}, // Force whole numbers only
booleanField: {type: Boolean}, // true/false values
dateField: {type: Date}, // Date and time values
emailField: {type: 'email'}, // Email with automatic validation
dynamicField: {type: 'blackbox'}, // Any object without specific schema
stringArrayField: {type: [String]} // Array of strings
})
Property Options
Properties can be configured with the following options:
{
// Core options
type: String, // Required type definition
label: 'Human-readable label', // For UI and error messages
description: 'Field description', // For documentation
optional: true, // Make field optional (default: false)
private: true, // Hide from GraphQL API
// Validation options
min: 0, // Min value/length
max: 100, // Max value/length
allowedValues: ['small', 'medium'], // Restrict to allowed values
// Default and transformation
defaultValue: 'draft', // Static default
defaultValue: () => new Date(), // Dynamic default
clean: (value) => value.trim(), // Transform before validation
// Custom validation
validate: (value) => {
if (someCondition) return 'errorCode' // camelCase error codes
}
}
Next Steps
Explore more about schemas: