Skip to content

Commit 16e17e2

Browse files
committed
Fixed bug resolving gremlin queries without arguments or selection set.
1 parent e190d62 commit 16e17e2

8 files changed

+278
-50
lines changed

templates/JSResolverOCHTTPSTemplate.js

+13-11
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ express or implied. See the License for the specific language governing
1010
permissions and limitations under the License.
1111
*/
1212

13-
import { astFromValue, buildASTSchema, typeFromAST, GraphQLID } from 'graphql';
13+
import { astFromValue, buildASTSchema, typeFromAST, GraphQLID, GraphQLInputObjectType } from 'graphql';
1414
import { gql } from 'graphql-tag'; // GraphQL library to parse the GraphQL query
1515

1616
const useCallSubquery = false;
@@ -36,7 +36,7 @@ export function resolveGraphDBQueryFromAppSyncEvent(event) {
3636
return resolveGraphDBQueryFromEvent({
3737
field: event.field,
3838
arguments: event.arguments,
39-
selectionSet: gql`${event.selectionSetGraphQL}`.definitions[0].selectionSet
39+
selectionSet: event.selectionSetGraphQL ? gql`${event.selectionSetGraphQL}`.definitions[0].selectionSet : {}
4040
});
4141
}
4242

@@ -58,15 +58,17 @@ export function resolveGraphDBQueryFromEvent(event) {
5858
if (value) {
5959
const inputType = typeFromAST(schema, inputDef.type);
6060
const astValue = astFromValue(value, inputType);
61-
// retrieve an ID field which may not necessarily be named 'id'
62-
const idField = Object.values(inputType.getFields()).find(field => field.type.name === GraphQLID.name);
63-
if (idField) {
64-
// check if id was an input arg
65-
const idValue = astValue.fields.find(f => f.name.value === idField.name);
66-
if (idValue?.value?.kind === 'IntValue') {
67-
// graphql astFromValue function can convert ID integer strings into integer type
68-
// if input args contain an id and the graphql library has interpreted the value as an int, change it to treat the value as a string
69-
idValue.value.kind = 'StringValue';
61+
if (inputType instanceof GraphQLInputObjectType) {
62+
// retrieve an ID field which may not necessarily be named 'id'
63+
const idField = Object.values(inputType.getFields()).find(field => field.type.name === GraphQLID.name);
64+
if (idField) {
65+
// check if id was an input arg
66+
const idValue = astValue.fields.find(f => f.name.value === idField.name);
67+
if (idValue?.value?.kind === 'IntValue') {
68+
// graphql astFromValue function can convert ID integer strings into integer type
69+
// if input args contain an id and the graphql library has interpreted the value as an int, change it to treat the value as a string
70+
idValue.value.kind = 'StringValue';
71+
}
7072
}
7173
}
7274
args.push({

test/TestCases/Case01/Case01.05.test.js

+30
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,36 @@ describe('AppSync resolver', () => {
105105
});
106106
});
107107

108+
test('should resolve gremlin query with argument', () => {
109+
const result = resolve({
110+
field: 'getAirportWithGremlin',
111+
arguments: { code: 'YVR' },
112+
selectionSetGraphQL: '{ city }'
113+
});
114+
115+
expect(result).toMatchObject({
116+
query: "g.V().has('airport', 'code', 'YVR').elementMap()",
117+
parameters: {},
118+
language: 'gremlin',
119+
refactorOutput: null
120+
});
121+
});
122+
123+
test('should resolve gremlin query without arguments or selection set', () => {
124+
const result = resolve({
125+
field: 'getCountriesCount',
126+
arguments: { },
127+
selectionSetGraphQL: ''
128+
});
129+
130+
expect(result).toMatchObject({
131+
query: "g.V().hasLabel('country').count()",
132+
parameters: {},
133+
language: 'gremlin',
134+
refactorOutput: null
135+
});
136+
});
137+
108138
function resolve(event) {
109139
return resolverModule.resolveGraphDBQueryFromAppSyncEvent(event);
110140
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
[
22
{ "type": "Airport", "field": "outboundRoutesCountAdd", "action": "add", "value":"outboundRoutesCountAdd: Int @graphQuery(statement: \"MATCH (this)-[r:route]->(a) RETURN count(r)\")"},
33
{ "type": "Mutation", "field": "deleteNodeVersion", "action": "remove", "value": "" },
4-
{ "type": "Mutation", "field": "createNodeVersion", "action": "remove", "value": "" }
4+
{ "type": "Mutation", "field": "createNodeVersion", "action": "remove", "value": "" },
5+
{ "type": "Query", "field": "getAirportWithGremlin", "action": "add", "value":"getAirportWithGremlin(code:String): Airport @graphQuery(statement: \"g.V().has('airport', 'code', '$code').elementMap()\")"},
6+
{ "type": "Query", "field": "getCountriesCount", "action": "add", "value":"getCountriesCount: Int @graphQuery(statement: \"g.V().hasLabel('country').count()\")"}
57
]

test/TestCases/Case01/outputReference/output.jsresolver.graphql.js

+107-13
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ express or implied. See the License for the specific language governing
1010
permissions and limitations under the License.
1111
*/
1212

13-
import { astFromValue, buildASTSchema, typeFromAST, GraphQLID } from 'graphql';
13+
import { astFromValue, buildASTSchema, typeFromAST, GraphQLID, GraphQLInputObjectType } from 'graphql';
1414
import { gql } from 'graphql-tag'; // GraphQL library to parse the GraphQL query
1515

1616
const useCallSubquery = false;
1717

18-
// 2025-02-19T23:41:22.685Z
18+
// 2025-02-21T06:31:13.132Z
1919

2020
const schemaDataModelJSON = `{
2121
"kind": "Document",
@@ -2469,6 +2469,98 @@ const schemaDataModelJSON = `{
24692469
}
24702470
},
24712471
"directives": []
2472+
},
2473+
{
2474+
"kind": "FieldDefinition",
2475+
"name": {
2476+
"kind": "Name",
2477+
"value": "getAirportWithGremlin"
2478+
},
2479+
"arguments": [
2480+
{
2481+
"kind": "InputValueDefinition",
2482+
"name": {
2483+
"kind": "Name",
2484+
"value": "code"
2485+
},
2486+
"type": {
2487+
"kind": "NamedType",
2488+
"name": {
2489+
"kind": "Name",
2490+
"value": "String"
2491+
}
2492+
},
2493+
"directives": []
2494+
}
2495+
],
2496+
"type": {
2497+
"kind": "NamedType",
2498+
"name": {
2499+
"kind": "Name",
2500+
"value": "Airport"
2501+
}
2502+
},
2503+
"directives": [
2504+
{
2505+
"kind": "Directive",
2506+
"name": {
2507+
"kind": "Name",
2508+
"value": "graphQuery"
2509+
},
2510+
"arguments": [
2511+
{
2512+
"kind": "Argument",
2513+
"name": {
2514+
"kind": "Name",
2515+
"value": "statement"
2516+
},
2517+
"value": {
2518+
"kind": "StringValue",
2519+
"value": "g.V().has('airport', 'code', '$code').elementMap()",
2520+
"block": false
2521+
}
2522+
}
2523+
]
2524+
}
2525+
]
2526+
},
2527+
{
2528+
"kind": "FieldDefinition",
2529+
"name": {
2530+
"kind": "Name",
2531+
"value": "getCountriesCount"
2532+
},
2533+
"arguments": [],
2534+
"type": {
2535+
"kind": "NamedType",
2536+
"name": {
2537+
"kind": "Name",
2538+
"value": "Int"
2539+
}
2540+
},
2541+
"directives": [
2542+
{
2543+
"kind": "Directive",
2544+
"name": {
2545+
"kind": "Name",
2546+
"value": "graphQuery"
2547+
},
2548+
"arguments": [
2549+
{
2550+
"kind": "Argument",
2551+
"name": {
2552+
"kind": "Name",
2553+
"value": "statement"
2554+
},
2555+
"value": {
2556+
"kind": "StringValue",
2557+
"value": "g.V().hasLabel('country').count()",
2558+
"block": false
2559+
}
2560+
}
2561+
]
2562+
}
2563+
]
24722564
}
24732565
]
24742566
},
@@ -3466,7 +3558,7 @@ const schemaDataModelJSON = `{
34663558
],
34673559
"loc": {
34683560
"start": 0,
3469-
"end": 4698
3561+
"end": 4902
34703562
}
34713563
}`;
34723564

@@ -3487,7 +3579,7 @@ export function resolveGraphDBQueryFromAppSyncEvent(event) {
34873579
return resolveGraphDBQueryFromEvent({
34883580
field: event.field,
34893581
arguments: event.arguments,
3490-
selectionSet: gql`${event.selectionSetGraphQL}`.definitions[0].selectionSet
3582+
selectionSet: event.selectionSetGraphQL ? gql`${event.selectionSetGraphQL}`.definitions[0].selectionSet : {}
34913583
});
34923584
}
34933585

@@ -3509,15 +3601,17 @@ export function resolveGraphDBQueryFromEvent(event) {
35093601
if (value) {
35103602
const inputType = typeFromAST(schema, inputDef.type);
35113603
const astValue = astFromValue(value, inputType);
3512-
// retrieve an ID field which may not necessarily be named 'id'
3513-
const idField = Object.values(inputType.getFields()).find(field => field.type.name === GraphQLID.name);
3514-
if (idField) {
3515-
// check if id was an input arg
3516-
const idValue = astValue.fields.find(f => f.name.value === idField.name);
3517-
if (idValue?.value?.kind === 'IntValue') {
3518-
// graphql astFromValue function can convert ID integer strings into integer type
3519-
// if input args contain an id and the graphql library has interpreted the value as an int, change it to treat the value as a string
3520-
idValue.value.kind = 'StringValue';
3604+
if (inputType instanceof GraphQLInputObjectType) {
3605+
// retrieve an ID field which may not necessarily be named 'id'
3606+
const idField = Object.values(inputType.getFields()).find(field => field.type.name === GraphQLID.name);
3607+
if (idField) {
3608+
// check if id was an input arg
3609+
const idValue = astValue.fields.find(f => f.name.value === idField.name);
3610+
if (idValue?.value?.kind === 'IntValue') {
3611+
// graphql astFromValue function can convert ID integer strings into integer type
3612+
// if input args contain an id and the graphql library has interpreted the value as an int, change it to treat the value as a string
3613+
idValue.value.kind = 'StringValue';
3614+
}
35213615
}
35223616
}
35233617
args.push({

0 commit comments

Comments
 (0)