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 }andParameterDefault::Listinsrc/types/field_parameter.rs. Validation checks the length bounds, each item (enum membership, or a GraphQLIntValuein range:4.0and007are 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 asstatus=["paused"]).FieldParameterDef::required(...)declares a parameter with no default: a bare selection of the field, or an empty call, fails with "userTierrequires thethresholdsparameter: useuserTier(thresholds=...)".userTierneeds 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,
Intbounds outside the 32-bit GraphQLInt), 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
Intlist items bare and enum items quoted:userTier(thresholds: [4, 25, 100]),totalCount(status: ["paused"]),status: [];orderByparameters carry the list unchanged. - The schema document publishes the kind mirroring the filter
List/itemsshape:{"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.rsspells fields with the parameters the document marksrequired, 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)