shopify_draft_proxy/search_query_parser

Mirrors src/search-query-parser.ts.

Shopify Admin’s “search query” string is a small DSL: terms, optional fields, comparators, parens for grouping, OR keyword, optional NOT keyword, and prefix - for negation. Domain handlers run user-supplied query strings against in-memory record lists, so every domain that accepts a query: "..." argument depends on this module.

The TS parser is a hand-rolled recursive-descent over a tiny tokenizer. The Gleam port mirrors it: tokenizer first, then a pratt-style cascade parse_or → parse_and → parse_unary. The result type is a recursive SearchQueryNode ADT.

Generic apply_* and matches_* helpers stay parametric over the item type and take a positive-term matcher callback, mirroring the TS SearchQueryTermMatcher<T> signature.

Types

Mirrors SearchQueryComparator.

pub type SearchQueryComparator {
  LessThanOrEqual
  GreaterThanOrEqual
  LessThan
  GreaterThan
  Equal
}

Constructors

  • LessThanOrEqual
  • GreaterThanOrEqual
  • LessThan
  • GreaterThan
  • Equal

Mirrors SearchQueryNode.

pub type SearchQueryNode {
  TermNode(term: SearchQueryTerm)
  AndNode(children: List(SearchQueryNode))
  OrNode(children: List(SearchQueryNode))
  NotNode(child: SearchQueryNode)
}

Constructors

Mirrors SearchQueryParseOptions. Defaults via default_parse_options().

pub type SearchQueryParseOptions {
  SearchQueryParseOptions(
    quote_characters: List(String),
    recognize_not_keyword: Bool,
    preserve_quotes_in_terms: Bool,
  )
}

Constructors

  • SearchQueryParseOptions(
      quote_characters: List(String),
      recognize_not_keyword: Bool,
      preserve_quotes_in_terms: Bool,
    )

Mirrors SearchQueryStringMatchMode.

pub type SearchQueryStringMatchMode {
  ExactMatch
  IncludesMatch
}

Constructors

  • ExactMatch
  • IncludesMatch

Mirrors SearchQueryStringMatchOptions.

pub type SearchQueryStringMatchOptions {
  SearchQueryStringMatchOptions(word_prefix: Bool)
}

Constructors

  • SearchQueryStringMatchOptions(word_prefix: Bool)

Mirrors SearchQueryTerm.

pub type SearchQueryTerm {
  SearchQueryTerm(
    raw: String,
    negated: Bool,
    field: option.Option(String),
    comparator: option.Option(SearchQueryComparator),
    value: String,
  )
}

Constructors

Mirrors SearchQueryTermListOptions and SearchQueryTermListParseOptions. The TS keeps them separate; in Gleam we collapse them into one record with drop_empty_values so callers don’t have to construct two record types — when calling parse_search_query_terms the field is ignored.

pub type SearchQueryTermListOptions {
  SearchQueryTermListOptions(
    quote_characters: List(String),
    preserve_quotes_in_terms: Bool,
    ignored_keywords: List(String),
    drop_empty_values: Bool,
  )
}

Constructors

  • SearchQueryTermListOptions(
      quote_characters: List(String),
      preserve_quotes_in_terms: Bool,
      ignored_keywords: List(String),
      drop_empty_values: Bool,
    )

Values

pub fn apply_search_query(
  items: List(a),
  raw_query: option.Option(String),
  options: SearchQueryParseOptions,
  matches_positive_term: fn(a, SearchQueryTerm) -> Bool,
) -> List(a)

Mirrors applySearchQuery. Empty / whitespace-only / unparseable queries leave the list untouched.

pub fn apply_search_query_terms(
  items: List(a),
  raw_query: option.Option(String),
  options: SearchQueryTermListOptions,
  matches_positive_term: fn(a, SearchQueryTerm) -> Bool,
) -> List(a)

Mirrors applySearchQueryTerms. AND semantics across all terms.

pub fn default_parse_options() -> SearchQueryParseOptions
pub fn default_string_match_options() -> SearchQueryStringMatchOptions
pub fn default_term_list_options() -> SearchQueryTermListOptions
pub fn matches_search_query_date(
  value: option.Option(String),
  term: SearchQueryTerm,
  now_ms: Int,
) -> Bool

Mirrors matchesSearchQueryDate. The TS uses Date.parse; we use the existing iso_timestamp.parse_iso FFI which wraps the same platform native on JS and calendar:rfc3339_to_system_time on Erlang.

pub fn matches_search_query_node(
  item: a,
  node: SearchQueryNode,
  matches_positive_term: fn(a, SearchQueryTerm) -> Bool,
) -> Bool

Mirrors matchesSearchQueryNode.

pub fn matches_search_query_number(
  value: option.Option(Float),
  term: SearchQueryTerm,
) -> Bool

Mirrors matchesSearchQueryNumber.

pub fn matches_search_query_string(
  candidate: option.Option(String),
  raw_value: String,
  match_mode: SearchQueryStringMatchMode,
  options: SearchQueryStringMatchOptions,
) -> Bool

Mirrors matchesSearchQueryString.

pub fn matches_search_query_term(
  item: a,
  term: SearchQueryTerm,
  matches_positive_term: fn(a, SearchQueryTerm) -> Bool,
) -> Bool

Mirrors matchesSearchQueryTerm. Empty raw or pure-negation (negated + empty value + no field) trivially passes. Otherwise delegate to the positive matcher, then flip if negated.

pub fn matches_search_query_text(
  value: option.Option(String),
  term: SearchQueryTerm,
) -> Bool

Mirrors matchesSearchQueryText. Substring match on lowercased value, ignoring the comparator entirely (TS does the same).

pub fn normalize_search_query_value(value: String) -> String

Mirrors normalizeSearchQueryValue. Trim, strip leading/trailing quote, lowercase. Note the TS regex ^['"]|['"]$ strips ONE char from each end if it’s a quote — not a balanced pair check.

pub fn parse_search_query(
  query: String,
  options: SearchQueryParseOptions,
) -> option.Option(SearchQueryNode)

Mirrors parseSearchQuery. Returns None for empty token streams.

pub fn parse_search_query_term(
  raw_value: String,
) -> SearchQueryTerm

Mirrors parseSearchQueryTerm. Trims the input, strips a leading - for negation, and splits on the first : into field + (optional comparator) + value.

pub fn parse_search_query_term_list(
  raw_query: option.Option(String),
  options: SearchQueryTermListOptions,
) -> List(SearchQueryTerm)

Mirrors parseSearchQueryTermList. Accepts an Option(String) (TS uses unknown, but the only case we care about is “string or not-a-string-which-is-treated-as-empty”). Empty / whitespace-only inputs return [].

pub fn parse_search_query_terms(
  query: String,
  options: SearchQueryTermListOptions,
) -> List(SearchQueryTerm)

Mirrors parseSearchQueryTerms. Splits on whitespace outside quotes, dropping ignored keywords, returning a flat term list.

pub fn search_query_term_value(term: SearchQueryTerm) -> String

Mirrors searchQueryTermValue. Returns the value with the comparator prefix re-attached.

pub fn strip_search_query_value_quotes(value: String) -> String

Mirrors stripSearchQueryValueQuotes. Strips a balanced pair of matching quotes from a trimmed string.

Search Document