Skip to content

Commit

Permalink
Merge pull request #830 from moonflare/add-default-value-for-args-and…
Browse files Browse the repository at this point in the history
…-input-fields

[Fix]: Add defaultValue for args and input fields
  • Loading branch information
hayes committed Mar 10, 2023
2 parents 23823b8 + 671a993 commit ae5c19b
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 19 deletions.
5 changes: 5 additions & 0 deletions .changeset/nasty-trainers-remember.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@pothos/plugin-directives": patch
---

Add ast nodes for defaultalues for args and input fields
8 changes: 6 additions & 2 deletions packages/deno/packages/core/config-store.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion packages/deno/packages/plugin-directives/mock-ast.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/deno/packages/plugin-relay/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ builder.node(NumberThing, {
the `Node` interface the first time it is used. The `resolve` function for `id` should return a
number or string, which will be converted to a globalID. The relay plugin adds to new query fields
`node` and `nodes` which can be used to directly fetch nodes using global IDs by calling the
provided `loadOne` or `laodMany` method. Each node will only be loaded once by id, and cached if the
provided `loadOne` or `loadMany` method. Each node will only be loaded once by id, and cached if the
same node is loaded multiple times inn the same request. You can provide `loadWithoutCache` or
`loadManyWithoutCache` instead if caching is not desired, or you are already using a caching
datasource like a dataloader.
Expand Down
8 changes: 8 additions & 0 deletions packages/plugin-directives/src/mock-ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import './global-types';
import {
ArgumentNode,
astFromValue,
ConstDirectiveNode,
ConstValueNode,
DirectiveNode,
EnumValueDefinitionNode,
FieldDefinitionNode,
Expand Down Expand Up @@ -237,11 +239,14 @@ function inputFieldNodes(fields: GraphQLInputFieldMap): InputValueDefinitionNode
return Object.keys(fields).map((fieldName) => {
const field: GraphQLInputField = fields[fieldName];

const defaultValueNode = astFromValue(field.defaultValue, field.type) as ConstValueNode;

field.astNode = {
kind: Kind.INPUT_VALUE_DEFINITION,
description: field.description ? { kind: Kind.STRING, value: field.description } : undefined,
name: { kind: Kind.NAME, value: fieldName },
type: typeNode(field.type),
defaultValue: field.defaultValue === undefined ? undefined : defaultValueNode,
directives: directiveNodes(
field.extensions?.directives as DirectiveList,
field.deprecationReason,
Expand All @@ -254,11 +259,14 @@ function inputFieldNodes(fields: GraphQLInputFieldMap): InputValueDefinitionNode

function argumentNodes(args: readonly GraphQLArgument[]): InputValueDefinitionNode[] {
return args.map((arg): InputValueDefinitionNode => {
const defaultValueNode = astFromValue(arg.defaultValue, arg.type) as ConstValueNode;

arg.astNode = {
kind: Kind.INPUT_VALUE_DEFINITION,
description: arg.description ? { kind: Kind.STRING, value: arg.description } : undefined,
name: { kind: Kind.NAME, value: arg.name },
type: typeNode(arg.type),
defaultValue: arg.defaultValue === undefined ? undefined : defaultValueNode,
directives: directiveNodes(
arg.extensions?.directives as DirectiveList,
arg.deprecationReason,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ exports[`extends example schema generates expected schema 1`] = `
enum EN {
ONE
TWO
}
interface IF {
Expand All @@ -15,12 +16,26 @@ input In {
test: String
}
input MyInput {
booleanWithDefault: Boolean = false
enumWithDefault: EN = TWO
id: ID!
idWithDefault: ID = 123
ids: [ID!]!
idsWithDefault: [ID!] = [123, 456]
stringWithDefault: String = "default string"
}
input MyOtherInput {
booleanWithDefault: Boolean = false
}
type Obj {
field: String!
}
type Query {
test(arg1: String): String!
test(arg1: String, myInput: MyInput, myOtherInput: MyOtherInput = {}): String!
}
union UN = Obj"
Expand Down
54 changes: 40 additions & 14 deletions packages/plugin-directives/tests/example/schema/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,44 @@
import { rateLimitDirective } from 'graphql-rate-limit-directive';
import builder from '../builder';

const myInput = builder.inputType('MyInput', {
fields: (t) => ({
id: t.id({ required: true }),
idWithDefault: t.id({ required: false, defaultValue: '123' }),
booleanWithDefault: t.boolean({ required: false, defaultValue: false }),
enumWithDefault: t.field({
defaultValue: 2,
type: myEnum,
}),
stringWithDefault: t.string({ required: false, defaultValue: 'default string' }),
ids: t.idList({ required: true }),
idsWithDefault: t.idList({ required: false, defaultValue: ['123', '456'] }),
}),
});

const myOtherInput = builder.inputType('MyOtherInput', {
fields: (t) => ({
booleanWithDefault: t.boolean({ required: false, defaultValue: false }),
}),
});

const myEnum = builder.enumType('EN', {
directives: {
e: { foo: 123 },
},
values: {
ONE: {
value: 1,
directives: {
ev: { foo: 123 },
},
},
TWO: {
value: 2,
},
},
});

builder.queryType({
directives: {
o: {
Expand All @@ -27,6 +65,8 @@ builder.queryType({
a: { foo: 123 },
},
}),
myOtherInput: t.arg({ type: myOtherInput, required: false, defaultValue: {} }),
myInput: t.arg({ type: myInput, required: false }),
},
resolve: () => 'hi',
}),
Expand Down Expand Up @@ -74,20 +114,6 @@ builder.unionType('UN', {
types: [Obj],
});

builder.enumType('EN', {
directives: {
e: { foo: 123 },
},
values: {
ONE: {
value: 1,
directives: {
ev: { foo: 123 },
},
},
},
});

builder.scalarType('Date', {
directives: {
s: { foo: 123 },
Expand Down
48 changes: 48 additions & 0 deletions packages/plugin-directives/tests/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import {
execute,
GraphQLEnumType,
GraphQLInputField,
GraphQLInputFieldMap,
GraphQLInputObjectType,
GraphQLObjectType,
InputValueDefinitionNode,
Kind,
lexicographicSortSchema,
printSchema,
} from 'graphql';
Expand Down Expand Up @@ -42,6 +46,50 @@ describe('extends example schema', () => {
).toStrictEqual({ if: { foo: 123 } });
});

it('constructs the astNode with defaultValue for inputs and args', () => {
const types = schema.getTypeMap();

const testField = (types.Query as GraphQLObjectType).getFields().test;

const arg1 = testField.args[0];
const myInput = testField.args[1];
const myOtherInput = testField.args[2];

expect(arg1.astNode?.defaultValue).toBeUndefined();
expect(myInput.astNode?.defaultValue).toBeUndefined();
expect(myOtherInput.astNode?.defaultValue).toBeDefined();
expect(myOtherInput.astNode?.defaultValue).toStrictEqual({
kind: Kind.OBJECT,
fields: [],
});

const MyInput = (types.MyInput as GraphQLInputObjectType).getFields();

expect(MyInput.booleanWithDefault.astNode?.defaultValue).toStrictEqual({
kind: Kind.BOOLEAN,
value: false,
});
expect(MyInput.enumWithDefault.astNode?.defaultValue).toStrictEqual({
kind: Kind.ENUM,
value: 'TWO',
});
expect(MyInput.idWithDefault.astNode?.defaultValue).toStrictEqual({
kind: Kind.INT,
value: '123',
});
expect(MyInput.stringWithDefault.astNode?.defaultValue).toStrictEqual({
kind: Kind.STRING,
value: 'default string',
});
expect(MyInput.idsWithDefault.astNode?.defaultValue).toStrictEqual({
kind: Kind.LIST,
values: [
{ kind: Kind.INT, value: '123' },
{ kind: Kind.INT, value: '456' },
],
});
});

it('gatsby format', () => {
const builder = new SchemaBuilder<{
Directives: {
Expand Down

1 comment on commit ae5c19b

@vercel
Copy link

@vercel vercel bot commented on ae5c19b Mar 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.