Handles field name formatting for input parameters, output fields, and TypeScript generation.
Supports built-in formatters and custom formatter functions.
Summary
Functions
Converts a field name to an atom, applying the formatter for case conversion.
Formats a field name for client output, optionally applying resource/type-level field_names mapping.
Formats a field name using the configured formatter.
Formats a map of fields, converting all keys using the specified formatter.
Parses input field names from client format to internal format.
Parses a map of input fields, converting all keys from client format to internal format.
Recursively parses input values, handling nested structures.
Functions
Converts a field name to an atom, applying the formatter for case conversion.
Unlike parse_input_field/2 which tries to use existing atoms, this function
always creates an atom (using String.to_atom/1 for strings that aren't existing atoms).
Use this when you need guaranteed atom output for field selection.
Examples
iex> AshTypescript.FieldFormatter.convert_to_field_atom("userName", :camel_case)
:user_name
iex> AshTypescript.FieldFormatter.convert_to_field_atom(:user_name, :camel_case)
:user_name
Formats a field name for client output, optionally applying resource/type-level field_names mapping.
Use this when formatting field names for client consumption where the field
might have a custom TypeScript name via the field_names DSL option or the
typescript_field_names callback function.
Examples
iex> AshTypescript.FieldFormatter.format_field_for_client(:user_name, nil, :camel_case)
"userName"
iex> AshTypescript.FieldFormatter.format_field_for_client("already_string", nil, :camel_case)
"alreadyString"When a resource or type module is provided with field_names/typescript_field_names mappings
(e.g., :is_active? → "isActive"), the mapped string value is used directly WITHOUT
additional formatting.
Formats a field name using the configured formatter.
Examples
iex> AshTypescript.FieldFormatter.format_field_name(:user_name, :camel_case)
"userName"
iex> AshTypescript.FieldFormatter.format_field_name(:user_name, :snake_case)
"user_name"
iex> AshTypescript.FieldFormatter.format_field_name("user_name", :pascal_case)
"UserName"
Formats a map of fields, converting all keys using the specified formatter.
Examples
iex> AshTypescript.FieldFormatter.format_fields(%{user_name: "John", user_email: "john@example.com"}, :camel_case)
%{"userName" => "John", "userEmail" => "john@example.com"}
Parses input field names from client format to internal format.
This is used for converting incoming client field names to the internal Elixir atom keys that Ash expects.
Examples
iex> AshTypescript.FieldFormatter.parse_input_field("userName", :camel_case)
:user_name
Parses a map of input fields, converting all keys from client format to internal format.
Recursively processes nested maps and arrays to ensure all field names are properly formatted. This is essential for union types and embedded resources that contain nested field structures.
Examples
iex> AshTypescript.FieldFormatter.parse_input_fields(%{"userName" => "John", "userEmail" => "john@example.com"}, :camel_case)
%{user_name: "John", user_email: "john@example.com"}
iex> AshTypescript.FieldFormatter.parse_input_fields(%{"attachments" => [%{"mimeType" => "pdf", "attachmentType" => "file"}]}, :camel_case)
%{attachments: [%{mime_type: "pdf", attachment_type: "file"}]}
Recursively parses input values, handling nested structures.
This function ensures that all nested maps and arrays containing maps have their field names properly formatted according to the formatter.
Only handles JSON-decoded data (maps, lists, primitives) - no structs.