Skip to content

Commit d381068

Browse files
authored
Bugfix/array args (#38)
1 parent 081a59e commit d381068

File tree

5 files changed

+48
-16
lines changed

5 files changed

+48
-16
lines changed

src/common/context.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ query Introspection {
1515
types {
1616
name
1717
description
18-
1918
fields(includeDeprecated: true) {
2019
name
2120
description
@@ -67,7 +66,6 @@ query Introspection {
6766
inputFields {
6867
name
6968
description
70-
7169
type {
7270
name
7371
kind

src/graphql/query-builder.ts

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ export default class QueryBuilder {
3838
const context = Context.getInstance();
3939
model = context.getModel(model);
4040

41-
let params: string = this.buildArguments(model, args, false, filter, allowIdFields);
41+
name = name ? name : model.pluralName;
42+
const field = context.schema!.getMutation(name, true) || context.schema!.getQuery(name, true);
43+
44+
let params: string = this.buildArguments(model, args, false, filter, allowIdFields, field);
4245
path = path.length === 0 ? [model.singularName] : path;
4346

4447
const fields = `
@@ -47,7 +50,7 @@ export default class QueryBuilder {
4750
`;
4851

4952
if (multiple) {
50-
const header: string = `${name ? name : model.pluralName}${params}`;
53+
const header: string = `${name}${params}`;
5154

5255
if (context.connectionQueryMode === 'nodes') {
5356
return `
@@ -118,9 +121,12 @@ export default class QueryBuilder {
118121
// name
119122
if (!name) name = (multiple ? model.pluralName : model.singularName);
120123

124+
// field
125+
const field = context.schema!.getMutation(name, true) || context.schema!.getQuery(name, true);
126+
121127
// build query
122128
const query: string =
123-
`${type} ${upcaseFirstLetter(name)}${this.buildArguments(model, args, true, filter)} {\n` +
129+
`${type} ${upcaseFirstLetter(name)}${this.buildArguments(model, args, true, filter, true, field)} {\n` +
124130
` ${this.buildField(model, multiple, args, [], name, filter, true)}\n` +
125131
`}`;
126132

@@ -149,10 +155,11 @@ export default class QueryBuilder {
149155
* @param {boolean} signature When true, then this method generates a query signature instead of key/value pairs
150156
* @param filter
151157
* @param {boolean} allowIdFields If true, ID fields will be included in the arguments list
158+
* @param {GraphQLField} field Optional. The GraphQL mutation or query field
152159
* @returns {String}
153160
*/
154161
private static buildArguments (model: Model, args?: Arguments, signature: boolean = false, filter: boolean = false,
155-
allowIdFields: boolean = true): string {
162+
allowIdFields: boolean = true, field: GraphQLField | null = null): string {
156163
if (args === undefined) return '';
157164

158165
let returnValue: string = '';
@@ -165,18 +172,23 @@ export default class QueryBuilder {
165172
const isForeignKey = model.skipField(key);
166173
const skipFieldDueId = (key === 'id' || isForeignKey) && !allowIdFields;
167174

175+
const schema = Context.getInstance().schema!;
176+
const type = schema.getType(model.singularName + (filter ? 'Filter' : ''));
177+
const schemaField = (filter ? type.inputFields! : type.fields!).find(f => f.name === key);
178+
const isConnectionField = schemaField && Schema.getTypeNameOfField(schemaField).endsWith('TypeConnection');
179+
168180
// Ignore null fields, ids and connections
169-
if (value && !(value instanceof Array || skipFieldDueId)) {
181+
if (value && !skipFieldDueId && !isConnectionField) {
170182
let typeOrValue: any = '';
171183

172184
if (signature) {
173-
const schema = Context.getInstance().schema!;
174-
const type = schema.getType(model.singularName + (filter ? 'Filter' : ''));
175-
const schemaField = (filter ? type.inputFields! : type.fields!).find(f => f.name === key);
176-
177185
if (_.isObject(value) && value.__type) {
178186
// Case 2 (User!)
179187
typeOrValue = value.__type + 'Input!';
188+
} else if (_.isArray(value) && field) {
189+
const arg = field.args.find(f => f.name === key);
190+
if (!arg) throw new Error("A argument is of type array but it's not possible to determine the type");
191+
typeOrValue = Schema.getTypeNameOfField(arg) + '!';
180192
} else if (schemaField && Schema.getTypeNameOfField(schemaField)) {
181193
// Case 1, 3 and 4
182194
typeOrValue = Schema.getTypeNameOfField(schemaField) + '!';

src/graphql/schema.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ export default class Schema {
7474
}
7575

7676
static getTypeNameOfField (field: GraphQLField): string {
77+
if (field.type.kind === 'LIST') {
78+
return `[${field.type.ofType.name}]`;
79+
}
80+
7781
const name = field.type.name ||
7882
field.type.ofType.name ||
7983
field.type.ofType.ofType.name ||

test/support/mock-schema.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ export const typeDefs = `
134134
title: String
135135
userId: ID
136136
otherId: ID
137+
crazyIDList: [ID]
137138
published: Boolean
138139
user: User
139140
comments: CommentTypeConnection
@@ -144,17 +145,19 @@ export const typeDefs = `
144145
id: ID
145146
content: String
146147
title: String
148+
crazyIDList: [ID]
147149
userId: ID
148150
otherId: ID
149151
published: Boolean
150152
user: UserInput
151153
}
152154
153155
154-
input PostInput {
156+
input PostInput {
155157
id: ID
156158
content: String
157159
title: String
160+
crazyIDList: [ID]
158161
userId: ID
159162
otherId: ID
160163
published: Boolean
@@ -397,6 +400,7 @@ const posts = [
397400
content: 'GraphQL is so nice!',
398401
title: 'GraphQL',
399402
otherId: 123,
403+
crazyIDList: [1, 2, 3],
400404
published: true,
401405
userId: 1
402406
},
@@ -406,6 +410,7 @@ const posts = [
406410
content: 'Vue is so awesome!',
407411
title: 'Vue.js',
408412
otherId: 435,
413+
crazyIDList: [4, 5],
409414
published: true,
410415
userId: 3
411416
},
@@ -415,6 +420,7 @@ const posts = [
415420
content: 'Vuex-ORM is so crisp',
416421
title: 'Vuex-ORM',
417422
otherId: 987,
423+
crazyIDList: [6],
418424
published: false,
419425
userId: 3
420426
}

test/unit/QueryBuilder.spec.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,16 @@ describe('QueryBuilder', () => {
2323
title: 'Example',
2424
otherId: 18,
2525
userId: 5,
26-
user: { __type: 'User' }
26+
user: { __type: 'User' },
27+
crazyIDList: [1, 2, 4, 9, 68],
28+
comments: [{
29+
id: 1,
30+
content: 'test'
31+
}]
2732
}, true, false, false);
2833

29-
expect(args).toEqual('($content: String!, $title: String!, $otherId: ID!, $user: UserInput!)');
34+
expect(args).toEqual('($content: String!, $title: String!, $otherId: ID!, $user: UserInput!, ' +
35+
'$crazyIDList: [ID]!)');
3036
});
3137

3238
it('can generate fields with variables', () => {
@@ -36,10 +42,16 @@ describe('QueryBuilder', () => {
3642
title: 'Example',
3743
otherId: 18,
3844
userId: 5,
39-
user: { __type: 'User' }
45+
user: { __type: 'User' },
46+
crazyIDList: [1, 2, 4, 9, 68],
47+
comments: [{
48+
id: 1,
49+
content: 'test'
50+
}]
4051
}, false, false, false);
4152

42-
expect(args).toEqual('(content: $content, title: $title, otherId: $otherId, user: $user)');
53+
expect(args).toEqual('(content: $content, title: $title, otherId: $otherId, user: $user, ' +
54+
'crazyIDList: $crazyIDList)');
4355
});
4456

4557
it('can generate filter field with variables', () => {

0 commit comments

Comments
 (0)