Shared logic for schema generation across all validation library targets.
All resource introspection, topological sorting, field resolution, and structural
code generation lives here. Output syntax is delegated to a module implementing
AshTypescript.Codegen.SchemaFormatter.
Consumers (e.g. ZodSchemaGenerator) pass __MODULE__ as the first formatter
argument to each public function.
Summary
Functions
Whether an RPC action gets an input schema at all.
Returns the exported schema constant name for an RPC action's input.
Builds a JS regex flag string from Elixir Regex opts.
Composes a single input-field schema entry: resolves the field's type through the formatter, then wraps nullable/optional.
Computes the effective minimum length for a string schema.
Generates a schema definition for an RPC action's input. Returns an empty string when the action has no input.
Generates a schema for a single resource.
Generates schemas for a list of resources (embedded resources, struct args). Returns an empty string when generation is disabled or the list is empty.
Maps a type-bearing spec input to a schema string.
Wraps a schema string with wrap_nullable (innermost) and/or wrap_optional
(outermost) based on the two booleans, using the given formatter.
Returns true when a regex source string is safe to emit as a JS literal.
Functions
Whether an RPC action gets an input schema at all.
An action with no inputs produces no schema, so anything that advertises or re-exports a schema name must ask this first — otherwise it points consumers at an export that does not exist.
Returns the exported schema constant name for an RPC action's input.
Single source of truth for the name — used by generate_action_schema/4 (the
export itself), the namespace re-export collection, and both manifests, so
they cannot drift from the configured *_schema_suffix.
Builds a JS regex flag string from Elixir Regex opts.
Composes a single input-field schema entry: resolves the field's type through the formatter, then wraps nullable/optional.
This is the one place that knows how "input argument -> schema field"
works — shared by RPC action input schemas (above) and typed-controller
route argument schemas (RouteRenderer), so the two surfaces cannot drift.
Computes the effective minimum length for a string schema.
Shared by the Zod and Valibot formatters so the rule cannot drift: an
explicit :min_length replaces the implicit non-empty minimum — but when
the string is non-empty (allow_empty?: false), the minimum is floored at
1, since the server nulls "" regardless of a declared min_length: 0.
Returns nil when no minimum applies.
Generates a schema definition for an RPC action's input. Returns an empty string when the action has no input.
Generates a schema for a single resource.
Generates schemas for a list of resources (embedded resources, struct args). Returns an empty string when generation is disabled or the list is empty.
Builds an augmented resource lookup that includes any orphan resources not already present in the cached spec — letting callers pass arbitrary embedded resources (e.g., test fixtures) without pre-registering them.
Maps a type-bearing spec input to a schema string.
Accepted shapes (all %Ash.Info.Manifest.*{}):
%Ash.Info.Manifest.Type{}— the canonical spec form%Ash.Info.Manifest.Argument{}/%Ash.Info.Manifest.Field{}— anything with a:typefield carrying a%Ash.Info.Manifest.Type{}- Aggregate kind atoms (e.g.
:count,:sum) — looked up informatter.aggregate_types()
Callers must feed spec data. Raw Ash types (atom modules, {:array, _}
tuples, %{type: SomeType, constraints: [...]} shapes) are no longer
accepted; resolve via Ash.Info.Manifest.Generator.TypeResolver.resolve/2 first.
Non-empty enforcement for string types is constraint-driven: whenever the
string's folded constraints carry allow_empty?: false (the Ash default),
the schema gets an effective min-length 1 (unless an explicit :min_length
is set) — matching server-side validation regardless of the field's
nilability. Strings with allow_empty?: true stay unconstrained. This
applies uniformly, including nested string fields inside typed containers.
Wraps a schema string with wrap_nullable (innermost) and/or wrap_optional
(outermost) based on the two booleans, using the given formatter.
Returns true when a regex source string is safe to emit as a JS literal.