Files
twenty_crm/server/src/workspace/workspace-query-builder/utils/get-field-arguments-by-key.util.ts
Jérémy M b86ada6d2b feat: rename tenant into workspace (#2553)
* feat: rename tenant into workspace

* fix: missing some files and reset not working

* fix: wrong import

* Use link in company seeds

* Use link in company seeds

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2023-11-17 11:26:33 +01:00

96 lines
2.4 KiB
TypeScript

import {
GraphQLResolveInfo,
SelectionSetNode,
Kind,
SelectionNode,
FieldNode,
InlineFragmentNode,
ValueNode,
} from 'graphql';
const isFieldNode = (node: SelectionNode): node is FieldNode =>
node.kind === Kind.FIELD;
const isInlineFragmentNode = (
node: SelectionNode,
): node is InlineFragmentNode => node.kind === Kind.INLINE_FRAGMENT;
const findFieldNode = (
selectionSet: SelectionSetNode | undefined,
key: string,
): FieldNode | null => {
if (!selectionSet) return null;
let field: FieldNode | null = null;
for (const selection of selectionSet.selections) {
// We've found the field
if (isFieldNode(selection) && selection.name.value === key) {
return selection;
}
// Recursively search for the field in nested selections
if (
(isFieldNode(selection) || isInlineFragmentNode(selection)) &&
selection.selectionSet
) {
field = findFieldNode(selection.selectionSet, key);
// If we find the field in a nested selection, stop searching
if (field) break;
}
}
return field;
};
const parseValueNode = (
valueNode: ValueNode,
variables: GraphQLResolveInfo['variableValues'],
) => {
switch (valueNode.kind) {
case Kind.VARIABLE:
return variables[valueNode.name.value];
case Kind.INT:
case Kind.FLOAT:
return Number(valueNode.value);
case Kind.STRING:
case Kind.BOOLEAN:
case Kind.ENUM:
return valueNode.value;
case Kind.LIST:
return valueNode.values.map((value) => parseValueNode(value, variables));
case Kind.OBJECT:
return valueNode.fields.reduce((obj, field) => {
obj[field.name.value] = parseValueNode(field.value, variables);
return obj;
}, {});
default:
return null;
}
};
export const getFieldArgumentsByKey = (
info: GraphQLResolveInfo,
fieldKey: string,
): Record<string, any> => {
// Start from the first top-level field node and search recursively
const targetField = findFieldNode(info.fieldNodes[0].selectionSet, fieldKey);
// If the field is not found, throw an error
if (!targetField) {
throw new Error(`Field "${fieldKey}" not found.`);
}
// Extract the arguments from the field we've found
const args: Record<string, any> = {};
if (targetField.arguments && targetField.arguments.length) {
for (const arg of targetField.arguments) {
args[arg.name.value] = parseValueNode(arg.value, info.variableValues);
}
}
return args;
};