From 5087fcd1e445a7ef309cf2f8addf1962466219df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Varela?= Date: Mon, 15 Aug 2022 14:58:43 +0100 Subject: [PATCH] Graphql: Fix geometry type in arguments (#15050) * Handle matrixes as args This was the less intrusive way I figure out. We may need to refactor this parseArgs properly in order to handle this types * App/Graphql: Send filter query as proper JSON instead of escaped string * Make panel variables readonly when no-editing Prevents Geometry type mismatch error * Fix proper way to parse args --- api/src/services/graphql/index.ts | 62 +++++++++------------- app/src/panels/variable/panel-variable.vue | 1 + app/src/utils/query-to-gql-string.ts | 9 ++++ 3 files changed, 34 insertions(+), 38 deletions(-) diff --git a/api/src/services/graphql/index.ts b/api/src/services/graphql/index.ts index 1e25b0830c..62df83ce5a 100644 --- a/api/src/services/graphql/index.ts +++ b/api/src/services/graphql/index.ts @@ -3,7 +3,6 @@ import { Accountability, Action, Aggregate, Filter, Query, SchemaOverview } from import argon2 from 'argon2'; import { ArgumentNode, - BooleanValueNode, execute, ExecutionResult, FieldNode, @@ -26,14 +25,11 @@ import { GraphQLString, GraphQLUnionType, InlineFragmentNode, - IntValueNode, NoSchemaIntrospectionCustomRule, - ObjectFieldNode, - ObjectValueNode, SelectionNode, specifiedRules, - StringValueNode, validate, + ValueNode, } from 'graphql'; import { GraphQLJSON, @@ -1459,43 +1455,33 @@ export class GraphQLService { * In order to do that, we'll parse over all ArgumentNodes and ObjectFieldNodes to manually recreate an object structure * of arguments */ - parseArgs( - args: readonly ArgumentNode[] | readonly ObjectFieldNode[], - variableValues: GraphQLResolveInfo['variableValues'] - ): Record { + parseArgs(args: readonly ArgumentNode[], variableValues: GraphQLResolveInfo['variableValues']): Record { if (!args || args.length === 0) return {}; - const parseObjectValue = (arg: ObjectValueNode) => { - return this.parseArgs(arg.fields, variableValues); + const parse = (node: ValueNode): any => { + switch (node.kind) { + case 'Variable': + return variableValues[node.name.value]; + case 'ListValue': + return node.values.map(parse); + case 'ObjectValue': + return Object.fromEntries(node.fields.map((node) => [node.name.value, parse(node.value)])); + case 'NullValue': + return null; + case 'StringValue': + return String(node.value); + case 'IntValue': + case 'FloatValue': + return Number(node.value); + case 'BooleanValue': + return Boolean(node.value); + case 'EnumValue': + default: + return node.value; + } }; - const argsObject: any = {}; - - for (const argument of args) { - if (argument.value.kind === 'ObjectValue') { - argsObject[argument.name.value] = parseObjectValue(argument.value); - } else if (argument.value.kind === 'Variable') { - argsObject[argument.name.value] = variableValues[argument.value.name.value]; - } else if (argument.value.kind === 'ListValue') { - const values: any = []; - - for (const valueNode of argument.value.values) { - if (valueNode.kind === 'ObjectValue') { - values.push(this.parseArgs(valueNode.fields, variableValues)); - } else { - if (valueNode.kind === 'Variable') { - values.push(variableValues[valueNode.name.value]); - } else { - values.push((valueNode as any).value); - } - } - } - - argsObject[argument.name.value] = values; - } else { - argsObject[argument.name.value] = (argument.value as IntValueNode | StringValueNode | BooleanValueNode).value; - } - } + const argsObject = Object.fromEntries(args.map((arg) => [arg.name.value, parse(arg.value)])); return argsObject; } diff --git a/app/src/panels/variable/panel-variable.vue b/app/src/panels/variable/panel-variable.vue index 25bf431b6f..05cdf65eec 100644 --- a/app/src/panels/variable/panel-variable.vue +++ b/app/src/panels/variable/panel-variable.vue @@ -3,6 +3,7 @@