feat(compiler): declare list-valued and required field parameters

What does this MR do and why?

Second of three MRs for list-valued field-function parameters (#213 (closed)). Stacked on !520 (merged) (typed values); followed by !522 (merged) (the syntax).

Sources can declare list-valued and required parameters; the engine needs both for userTier(thresholds: [Int!]) on DuoWorkflows (#209 (closed)) and totalCount(status: [String!]) (#215 (closed)).

  • ParameterConstraint::List { item: ListItem::Enum(..) | Int { min, max }, min_len, max_len, strictly_ascending } and ParameterDefault::List in src/types/field_parameter.rs. Validation checks the length bounds, each item (enum membership, or a GraphQL IntValue in range: 4.0 and 007 are refused at compile time) and the ordering rule. A single value written for a list parameter is coerced to a one-item list (status="paused" reads as status=["paused"]).
  • FieldParameterDef::required(...) declares a parameter with no default: a bare selection of the field, or an empty call, fails with "userTier requires the thresholds parameter: use userTier(thresholds=...)". userTier needs this because the dashboard pre-scales its thresholds per selected period, so no fixed default is right.
  • Definitions are checked in const context: unsatisfiable constraints (empty enum, inverted bounds, Int bounds outside the 32-bit GraphQL Int), mismatched or invalid defaults, and defaults that break the ascending rule all fail the build.
  • Named arguments resolve to one value per definition in definition order, omitted ones filled from their defaults (a required one left out is an error), so the same selection spelled in any order gets the same parameters, slug and sort snapshot.
  • Codegen renders Int list items bare and enum items quoted: userTier(thresholds: [4, 25, 100]), totalCount(status: ["paused"]), status: []; orderBy parameters carry the list unchanged.
  • The schema document publishes the kind mirroring the filter List/items shape: {"kind": "List", "items": [{"kind": "Number", "min": 1, "max": ...}], "min_length": 1, "max_length": 9, "strictly_ascending": true, "required": true}; an integer list default publishes as numbers. tests/schema_conformance.rs spells fields with the parameters the document marks required, filled from the document's own samples, and samples lists of the published minimum length with ascending items.

No shipped field declares a list yet, so schema.json is unchanged and the parser still reads scalars only: the rules are pinned through a stand-in analyzer in the src/analyzer/analytics.rs tests (both list shapes, sugar, defaults, required, definition order, every validation error).

How to review

src/types/field_parameter.rs (definitions and const checks), src/analyzer/analytics.rs (resolve_named_args, validate_params), src/schema/builder.rs, tests/schema_conformance.rs.

Part of #213 (closed)

Edited by Daniele Rossetti

Merge request reports

Loading
Loading