Files
bodyshop/client/src/utils/graphQLmodifier.js
Dave Richer 85d1fd3c39 - Progress check
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-02-08 10:55:35 -05:00

115 lines
4.3 KiB
JavaScript

import {Kind, visit} from "graphql";
/**
* Apply sorters to the AST
* @param ast
* @param sorters
*/
export function applySorters(ast, sorters) {
sorters.forEach((sorter) => {
const [table, field] = sorter.field.split('.');
visit(ast, {
OperationDefinition: {
enter(node) {
node.selectionSet.selections.forEach((selection) => {
if (selection.name.value === table) {
let orderByArg = selection.arguments.find(arg => arg.name.value === 'order_by');
if (!orderByArg) {
orderByArg = {
kind: Kind.ARGUMENT,
name: {kind: Kind.NAME, value: 'order_by'},
value: {kind: Kind.OBJECT, fields: []}
};
selection.arguments.push(orderByArg);
}
const sorterField = {
kind: Kind.OBJECT_FIELD,
name: {kind: Kind.NAME, value: field},
value: {kind: Kind.ENUM, value: sorter.direction} // 'asc' for ascending order, 'desc' for descending order
};
orderByArg.value.fields.push(sorterField);
}
});
}
}
});
});
}
/**
* Apply filters to the AST
* @param ast
* @param filters
* @param filterFields
*/
export function applyFilters(ast, filters, filterFields) {
filters.forEach((filter) => {
const struct = filter.field.split('.');
visit(ast, {
OperationDefinition: {
enter(node) {
node.selectionSet.selections.forEach((selection) => {
if (selection.name.value === struct[0]) {
let whereArg = selection.arguments.find(arg => arg.name.value === 'where');
if (!whereArg) {
whereArg = {
kind: Kind.ARGUMENT,
name: {kind: Kind.NAME, value: 'where'},
value: {kind: Kind.OBJECT, fields: []}
};
selection.arguments.push(whereArg);
}
const filterField = {
kind: Kind.OBJECT_FIELD,
name: {kind: Kind.NAME, value: struct[1]},
value: {
kind: Kind.OBJECT,
fields: [{
kind: Kind.OBJECT_FIELD,
name: {kind: Kind.NAME, value: filter.operator},
value: {kind: Kind.STRING, value: filter.value}
}]
}
};
filterFields.push({kind: Kind.OBJECT, fields: [filterField]});
}
});
}
}
});
});
}
/**
* Wrap filters in an 'and' object
* @param ast
* @param filterFields
*/
export function wrapFiltersInAnd(ast, filterFields) {
visit(ast, {
OperationDefinition: {
enter(node) {
node.selectionSet.selections.forEach((selection) => {
let whereArg = selection.arguments.find(arg => arg.name.value === 'where');
if (filterFields.length > 1) {
const andFilter = {
kind: Kind.OBJECT_FIELD,
name: {kind: Kind.NAME, value: '_and'},
value: {kind: Kind.LIST, values: filterFields}
};
whereArg.value.fields.push(andFilter);
} else if (filterFields.length === 1) {
whereArg.value.fields.push(filterFields[0].fields[0]);
}
});
}
}
});
}