For the complete documentation index, see llms.txt. This page is also available as Markdown.

schema

The schema package validates unknown values, nested objects, and arrays. Schemas are reusable and immutable: constraint methods return a new schema, leaving the original unchanged.

import "std:schema"

*schema.Schema createUser = schema.object({
  name: schema.string().trim().minLen(1),
  age: schema.integer().min(0).optional(),
  roles: schema.array(schema.enum(["admin", "member"]))
})

auto checked = createUser.safeParse(payload)
if checked.isErr() (
  return err(checked.unwrapErr().message)
)
object user = checked.unwrap()

Creating schemas

schema.any()*schema.Schema

Accepts any value, including null.

schema.string()*schema.Schema

Accepts a string.

schema.number()*schema.Schema

Accepts a finite number.

schema.integer()*schema.Schema

Accepts a finite whole number.

schema.boolean()*schema.Schema

Accepts a boolean.

schema.literal(value)*schema.Schema

Accepts only a value equal to value.

schema.enum(values)*schema.Schema

Accepts one of the supplied values. Values may be strings, numbers, booleans, or other OSL values.

schema.array(itemSchema)*schema.Schema

Accepts an array and validates every element with itemSchema. Errors include the failing index, such as roles[1].

schema.oneOrMany(itemSchema)*schema.Schema

Accepts either one value or an array of values and validates each value with itemSchema. The normalized result is always an array, which is useful for APIs that accept scalar shorthand.

schema.object(shape)*schema.Schema

Accepts an object and validates the named fields with the schemas in shape. Fields not in the shape are preserved unless .strict() is used. Nested error paths use dot notation.

schema.record(valueSchema)*schema.Schema

Accepts an object with arbitrary string keys and validates every value with valueSchema.

schema.union(schemas)*schema.Schema

Accepts a value when any supplied schema accepts it.

Schema modifiers

Each modifier returns a new *schema.Schema and can be chained.

value.optional()*schema.Schema

Allows a field to be absent. Because absent object fields read as null in OSL, optional schemas also accept null.

value.nullable()*schema.Schema

Allows null in addition to the schema's normal type.

value.defaultValue(default)*schema.Schema

Uses default when the input is absent or null. The normalized output contains the default.

value.trim()*schema.Schema

Trims leading and trailing whitespace from a string in the normalized output.

value.min(limit) / value.max(limit)*schema.Schema

Sets an inclusive numeric minimum or maximum on number and integer schemas.

value.minLen(limit) / value.maxLen(limit)*schema.Schema

Sets an inclusive length bound. Strings use Unicode character count; arrays and objects use item or field count.

value.length(size)*schema.Schema

Requires an exact string character count, array item count, or object field count.

value.gt(limit) / value.lt(limit)*schema.Schema

Sets an exclusive numeric bound. For example, .gt(0) accepts positive numbers while .min(0) also accepts zero.

value.partial()*schema.Schema

Returns an object schema where every declared field is optional. This is useful for update payloads.

value.extend(shape)*schema.Schema

Returns an object schema containing its existing fields plus the supplied fields. Supplied fields replace existing fields with the same name.

value.requireAny(fields)*schema.Schema

Requires an object to contain at least one named field. A present field with a null value counts, so this works for patches where null intentionally clears a value.

value.requireAnyValue(fields)*schema.Schema

Requires an object to contain a non-null value for at least one named field. Empty strings and arrays still count; combine the field schema with .minLen(1) when emptiness should be rejected.

Modifier misuse is reported as a schema configuration error instead of silently doing nothing. For example, schema.string().min(2) returns Invalid schema: min() cannot be used with string schemas.

value.strict()*schema.Schema

For an object schema, rejects fields not present in its shape. Other object schemas preserve additional fields.

Validating values

value.safeParse(input)result.Result

Validates input without throwing. Returns ok(normalizedValue) on success. On failure it returns err(error), where error contains message, path, and issues. The current implementation stops at the first issue.

value.parse(input)any

Returns the normalized value or throws a path-based validation message.

value.isValid(input)boolean

Returns whether input passes the schema without returning the normalized value or throwing. This uses a validation-only fast path: it does not copy arrays or objects, construct normalized values, or allocate successful error paths. Define reusable schemas once rather than rebuilding them inside a frequently called function.

Last updated