Skip to content

Instantly share code, notes, and snippets.

@AndreaMorone
Last active August 29, 2025 08:21
Show Gist options
  • Select an option

  • Save AndreaMorone/f98a7a141310bbb8753471991d0d1f8f to your computer and use it in GitHub Desktop.

Select an option

Save AndreaMorone/f98a7a141310bbb8753471991d0d1f8f to your computer and use it in GitHub Desktop.
Calculate Shopify Function Query Cost
const { parse } = require('graphql/language');
/**
* Calculates the cost of a GraphQL query based on its structure.
*
* @param {string} query - The GraphQL query to calculate the cost for.
* @param {boolean} [debug=false] - If true, additional debug information will be logged.
* @return {number} The total cost of the query.
*/
function calculateQueryCost(query, debug = true) {
let cost = 0;
function traverse(node) {
switch (node.kind) {
case 'Document':
node.definitions.forEach(definition => traverse(definition));
break;
case 'OperationDefinition':
if (node.selectionSet) {
traverse(node.selectionSet);
}
break;
case 'SelectionSet':
if (node.selections) {
node.selections.forEach(selection => traverse(selection));
}
break;
case 'Field':
const fieldName = node.name.value;
debug && console.log(`Field name: ${fieldName}`); // Debug output
if (fieldName === 'metafield') {
cost += 3; // Add cost for metafield
debug && console.log(`Added cost 3 for ${fieldName}, total cost: ${cost}`);
return;
} else if (['hasTags', 'hasAnyTag', 'inAnyCollection', 'inCollections'].includes(fieldName)) {
cost += 3; // Add cost for special fields
debug && console.log(`Added cost 3 for ${fieldName}, total cost: ${cost}`);
return;
} else if (!node.selectionSet) {
cost += 1; // Default cost for other leaf nodes
debug && console.log(`Added cost 1 for ${fieldName}, total cost: ${cost}`);
}
if (node.selectionSet) {
traverse(node.selectionSet);
}
break;
case 'InlineFragment':
case 'FragmentSpread':
if (node.selectionSet) {
traverse(node.selectionSet);
}
break;
// Add cases for other node kinds like 'FragmentDefinition' if needed
}
}
const ast = parse(query);
traverse(ast);
return cost;
}
const query = `
query Input {
cart {
cost {
totalAmount {
amount
}
}
}
paymentMethods {
id
name
}
paymentCustomization {
metafield(namespace: "$app:payment-customization", key: "function-configuration") {
value
}
}
}
`;
console.log(calculateQueryCost(query));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment