AshScim.Filter (ash_scim v0.1.0)

Copy Markdown View Source

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}. Chained and/or flatten to a single list.

Operator support

SCIMAsh
eqeq
nenot_eq
cocontains
swstring_starts_with?
ewstring_ends_with?
pris_nil: false
gtgreater_than
gegreater_than_or_equal
ltless_than
leless_than_or_equal

Summary

Functions

Parse a SCIM filter string against resource's SCIM mappings.

Types

opts()

@type opts() :: [{:prefix, [String.t()]}]

Functions

parse(input, resource, opts \\ [])

@spec parse(String.t(), module(), opts()) :: {:ok, map()} | {:error, term()}

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 filter value eq "x" written inside members[…] is parsed with prefix: ["members"] so it resolves as if it were members.value eq "x".

Returns {:ok, filter} where filter is a map suitable for Ash.Query.filter_input/2, or {:error, reason}.