Support for enum values as default argument values
I should be able to write a resolver like so:
/** @gqlEnum */
enum Colour {
Red = 'RED',
Blue = 'BLUE',
}
/** @gqlQueryField */
export function myField(context: Context, colour: Colour = Colour.Red): string {
return 'hello world';
}
It should generate the following schema:
enum Colour {
RED
BLUE
}
type Query {
myField(colour: Colour! = RED): String!
}
The observed behaviour is an error is thrown during schema compilation:
Expected GraphQL field argument default values to be a literal. Grats interprets argument defaults as GraphQL default values, which must be literals. For example:
10or"foo".
Makes sense. Here's a Playground repro of the issue: link.
Implementing this might be a bit tricky since right now we expect input values to be parsable without needing to do type resolution, but it should be possible since we already do type resolution for output types.
As a workaround I think this would work (but would require using a union of string literals rather than a TypeScript enum).
/** @gqlEnum */
type Foo = "BAR" | "BAZ";
/** @gqlQueryField */
export function greeting(myArg: Foo = "BAR"): string {
return "Hello";
}
It's actually a bit interesting because the default value still gets interpreted as a string literal in the generated GraphQL even though the type is an enum. I think this ends up working out because GraphQL will coerce string literals to enums. So, it might be able to unblock you (or someone else) in the short term, but it's a bit odd.
Btw for when args are objects, I had to do this:
/** @gqlEnum */
type Foo = "BAR" | "BAZ";
/** @gqlQueryField */
export function greeting({
// @ts-ignore https://github.com/captbaritone/grats/issues/172#issuecomment-2685496600
myArg = "BAR"
}: {
myArg: Foo
}): string {
return "Hello";
}
Otherwise works just fine
Ok, actually the workaround doesn't work. The request will fail during validation E.g.
Received value: [{"locations": [{"column": 13, "line": 5}], "message": "Field \"locations\" argument \"gender\" of type \"TreatmentGender!\" is required, but it was not provided."}]
And looking at output schema (which clients see) defaultValue is missing
This is reproducible in the playground (Typescript Schema)
Btw for when args are objects, I had to do this:
Could you share the TS error you are suppressing here? When I try that in the playground I don't get a TS error.
And looking at output schema (which clients see) defaultValue is missing
A yeah, I think this is a separate bug. We are currently relying on TypeScript to add the default values. That means we don't need GraphQLJS to know about it. But, in the case of non-nullable fields with defaults the runtime behavior for the two is different, so we need to add the default value to the runtime version of the schema to fix that. I'll open a separate issue for that.
Fixed in https://github.com/captbaritone/grats/commit/db77a72bcfa4074ba5ced686c29e2077dfaf63dc
Can you try this npm release and see if it works for you? https://www.npmjs.com/package/grats/v/0.0.0-main-db77a72b
This seems fixed (in the playground for TS enums, and also for type enums) now. No more type errors and defaultValue is being set in both cases.
Thank you!