Parses a SCIM 2.0 filter expression (RFC 7644 §3.4.2.2) directly into the
map-shaped filter input accepted by Ash.Query.filter/2 and
Ash.Filter.parse_input/2.
Performs the security-critical resolution in the same pass: every attribute
path mentioned in the filter must be declared in the resource's scim
mappings, otherwise the parse fails. Unmapped fields can never reach Ash.
Output shape
- Simple comparison:
%{email: %{eq: "alice"}} - Presence:
%{email: %{is_nil: false}} - Complex sub-attribute: flattens to the underlying scalar attribute,
e.g.
name.givenName→%{first_name: %{eq: "Alice"}}. - Single-attribute multivalued: same flattening.
- Relationship-backed multivalued: emits Ash's native nested filter
form, e.g.
members.value eq "u1"→%{memberships: %{user_id: %{eq: "u1"}}}. - Boolean composition:
%{and: [filter, …]}/%{or: [filter, …]}/%{not: filter}. Chainedand/orflatten to a single list.
Operator support
| SCIM | Ash |
|---|---|
eq | eq |
ne | not_eq |
co | contains |
sw | string_starts_with? |
ew | string_ends_with? |
pr | is_nil: false |
gt | greater_than |
ge | greater_than_or_equal |
lt | less_than |
le | less_than_or_equal |
Summary
Functions
Parse a SCIM filter string against resource's SCIM mappings.
Types
@type opts() :: [{:prefix, [String.t()]}]
Functions
Parse a SCIM filter string against resource's SCIM mappings.
Options
:prefix— a list of SCIM attribute names to virtually prepend to every attribute path inside the filter. Used by the PATCH bracket-filter parser: a filtervalue eq "x"written insidemembers[…]is parsed withprefix: ["members"]so it resolves as if it weremembers.value eq "x".
Returns {:ok, filter} where filter is a map suitable for
Ash.Query.filter_input/2, or {:error, reason}.