When defining properties in a schema, you can configure various options to specify validation rules, labels, and more.

Basic Property Definition

The simplest way to define a property is to specify its type:

import {schemaWithName, InferSchemaType} from '@orion-js/schema'

export const ProductSchema = schemaWithName('ProductSchema', {
  _id: {type: String},
  name: {type: String},
  price: {type: Number}
})

export type ProductType = InferSchemaType<typeof ProductSchema>

In this example, Orionjs applies appropriate validation based on the specified types.

Available Options

Each property in the schema can have the following options:

label

A human-readable label for the field, useful for UI generation and error messages.

name: {
  type: String,
  label: 'Product Name'
}

description

Provides a description for the field, which will be included in GraphQL schema generation.

price: {
  type: Number,
  label: 'Product Price',
  description: 'The price in USD before tax'
}

optional

By default, all fields are required. Set optional: true to make a field optional.

description: {
  type: String,
  optional: true
}

private

Fields marked as private will not be exposed in the GraphQL API.

internalNotes: {
  type: String,
  private: true
}

min / max

These options provide validation constraints based on the field type:

  • For number: Minimum and maximum numeric values
  • For string: Minimum and maximum string length
  • For Date: Minimum and maximum date
price: {
  type: Number,
  min: 0,
  max: 1000
},

name: {
  type: String,
  min: 3,
  max: 50
},

releaseDate: {
  type: Date,
  min: new Date('2023-01-01')
}

allowedValues

Restricts the field to a set of allowed values.

size: {
  type: String,
  allowedValues: ['small', 'medium', 'large']
}

defaultValue

Sets a default value for the field if none is provided.

status: {
  type: String,
  defaultValue: 'draft'
},

createdAt: {
  type: Date,
  defaultValue: () => new Date()
}

Custom Validation

You can create custom validation logic using the validate option:

slug: {
  type: String,
  validate: (value) => {
    if (!/^[a-zA-Z0-9-]+$/.test(value)) {
      return 'slug-format-invalid'
    }
  }
}

The validate function:

  • Receives the field value as its first parameter
  • Should return an error message string if validation fails
  • Should return nothing (undefined) if validation passes
  • Can be an async function

Custom Data Transformation

The clean option allows you to transform data before validation:

email: {
  type: String,
  clean: (value) => value.trim().toLowerCase()
}

The clean function:

  • Receives the field value as its first parameter
  • Should return the transformed value
  • Can be an async function

Working with Arrays

To define an array of values, use the array syntax in the type field:

tags: {
  type: [String]
},

categories: {
  type: [String],
  min: 1, // At least one item required
  maxLength: 10 // Maximum 10 items allowed
}

For arrays of complex types, you can reference other schemas:

import {schemaWithName, InferSchemaType} from '@orion-js/schema'
import {ProductVariantSchema} from './ProductVariantSchema'

export const ProductSchema = schemaWithName('ProductSchema', {
  // Other fields...
  
  variants: {
    type: [ProductVariantSchema]
  }
})

export type ProductType = InferSchemaType<typeof ProductSchema>

Nested Schemas

You can nest schemas inside other schemas:

import {schemaWithName, InferSchemaType} from '@orion-js/schema'

export const AddressSchema = schemaWithName('AddressSchema', {
  street: {type: String},
  city: {type: String},
  zipCode: {type: String}
})

export type AddressType = InferSchemaType<typeof AddressSchema>

export const UserSchema = schemaWithName('UserSchema', {
  name: {type: String},
  email: {type: String},
  
  // Nested schema
  address: {type: AddressSchema}
})

export type UserType = InferSchemaType<typeof UserSchema>