Skip to content

Commit

Permalink
Added graphql to fql converter
Browse files Browse the repository at this point in the history
  • Loading branch information
agbhanu1996 committed Oct 14, 2022
1 parent 64c9d8f commit 6f18537
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
113 changes: 113 additions & 0 deletions graphqlToFQLConverter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
const { parse } = require('graphql/language/parser');

const capitalizeFirstLetter = (string) => {
return string.charAt(0).toUpperCase() + string.slice(1);
}

const composeOperator = (stringArray) => {
let result = stringArray[1];
for (let index = 2; index < stringArray.length; index++) {
result += capitalizeFirstLetter(stringArray[index]);
}
return result;
}

const getCollectionSortCriteria = (arg) => {
const [key, direction] = arg.value.value.split('_');
return `order(${direction.toLowerCase()}(.${key}))`;
}

const buildCriteriaString = (fields) => {
let criteriaString = '';
for (let index = 0; index < fields.length; index++) {
const splittedString = fields[index].name.value.split("_");
const key = splittedString[0];
const operator = composeOperator(splittedString);
const value = fields[index].value.value;

criteriaString += `.${key}.${operator}("${value}")`;
criteriaString += index < fields.length - 1 ? ' && ' : '';
}
return criteriaString;
}

const getCollectionFilterCriteria = (arg) => {
const { fields } = arg.value;
const criteriaString = buildCriteriaString(fields);
return `firstWhere(${criteriaString})`;
}

const getCollectionLevelCriteria = (args) => {
let sortCriteria = null;
let filterCriteria = null;
for (const arg of args) {
const keyword = arg.name.value;
if (keyword === 'orderBy') {
sortCriteria = getCollectionSortCriteria(arg);
}
else if (keyword === 'where') {
filterCriteria = getCollectionFilterCriteria(arg);
}
}
return { sortCriteria, filterCriteria };
}

const buildArrayExpression = (name, args) => {
const { fields } = args[0].value;
const criteriaString = buildCriteriaString(fields);
return `${name}.filter(${criteriaString}).at(0)`;
}

const getLastExpression = (input, result) => {
if (!input) return result;
result += '.';
const selections = input.selections[0];
const name = selections?.name?.value;
const args = selections?.arguments;
if (!args || args.length == 0) {
result += name;
}
else {
result += buildArrayExpression(name, args);
}
return getLastExpression(selections.selectionSet, result);
}

// TRP_TreatmentPlans.all.order(asc(.name)).firstWhere(.name.startsWith("Jamie"))
//.treatments.filter(.title.startsWith("Union")).at(0).selectedItems

const query = `
query MyQuery {
TRP_TreatmentPlans(orderBy: name_ASC, where: {name_starts_with: "Jamie"}) {
treatments(where: {title_starts_with: "Union"}) {
selectedItems {
quantity {
items
}
}
}
}
}
`;

const convertGraphQLToFQL = (query) => {
let fqlString = '';
const parsedQuery = parse(query);
const selections = parsedQuery.definitions[0].selectionSet.selections[0];
const collectionName = selections.name.value;
const args = selections.arguments;

fqlString += `${collectionName}.all`;
const { sortCriteria, filterCriteria } = getCollectionLevelCriteria(args);

fqlString += sortCriteria ? `.${sortCriteria}` : '';
fqlString += filterCriteria ? `.${filterCriteria}` : '';

const input = selections.selectionSet;
const lastExpression = getLastExpression(input, '');
fqlString += lastExpression;

return fqlString;
};

console.log(convertGraphQLToFQL(query));
31 changes: 31 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "rules-engine",
"version": "1.0.0",
"description": "",
"main": "composer.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Dechea/rules-engine.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/Dechea/rules-engine/issues"
},
"homepage": "https://github.com/Dechea/rules-engine#readme",
"dependencies": {
"graphql": "^16.6.0"
}
}

0 comments on commit 6f18537

Please sign in to comment.