Support GraphQL variables
eddyystop opened this issue · 4 comments
Thx @eddyystop for creating a reference to my PR. You are right, after applying the changes to make work passing variables - I have an issue, and I don't have more ideas why this doesn't work, did I miss something?
I found where the problem comes from.
feathers-plus/graphql uses package https://github.com/eddyystop/graphql-resolvers-ast that currently not allow passing argumentValue.kind Variable
function getArgumentValue (argumentValue) {
switch (argumentValue.kind) {
case 'StringValue': // fall through
case 'BooleanValue':
return argumentValue.value;
case 'IntValue':
return parseInt(argumentValue.value, 10);
case 'FloatValue':
return parseFloat(argumentValue.value);
case 'ListValue':
return argumentValue.values.map(elem => getArgumentValue(elem));
case 'ObjectValue':
const obj = {};
argumentValue.fields.forEach(field => {
obj[field.name.value] = getArgumentValue(field.value);
});
return obj;
default:
throw new Error(`Unexpected GraphQL argument type "${argumentValue.kind}"`);
}
}
I think this is a great feature to allow passing variables with query
Currently i have been implemented my solution to pass query object in variables.
This will helps us to avoid use convertArgsToParams function that replace __ to $
Thanks for the info.
Posting here for prosperity, but I do not recommend doing this but make sure you know what you're doing and remember to remove this when it is actually fixed.
- add the following to your scripts in
package.json
:"postinstall": "node src/util/variable-fix.js"
- create a new file at the directory:
src/util/variable-fix.js
- add the following code to the file:
const fs = require('fs');
// eslint-disable-next-line no-console
console.log('Warning!! patching to inject variable support into deps');
const fGQL_dir = `${__dirname}/../../node_modules/@feathers-plus/graphql/lib/index.js`;
const gra_dir = `${__dirname}/../../node_modules/graphql-resolvers-ast/lib/index.js`;
let fGQL = fs.readFileSync(fGQL_dir, {encoding: 'utf8'});
let gra = fs.readFileSync(gra_dir, {encoding: 'utf8'});
fGQL = fGQL.replace('runQuery(query, params) {', 'runQuery(query, params, variables) {');
fGQL = fGQL.replace('graphql(this._schema, query, {}, content)', 'graphql(this._schema, query, {}, content, variables)');
fGQL = fGQL.replace('return this.runQuery(data.query, params);', 'return this.runQuery(data.query, params, data.variables);');
fGQL = fGQL.replace('return this.runQuery(params.query.query, params);', 'return this.runQuery(params.query.query, params, params.query.variables);');
gra = gra.replace('getArgumentValue(argument.value)', 'getArgumentValue(argument.value, ast)');
gra = gra.replace('function getArgumentValue (argumentValue) {', 'function getArgumentValue (argumentValue, ast) {');
gra = gra.replace('elem => getArgumentValue(elem)', 'elem => getArgumentValue(elem, ast)');
gra = gra.replace('getArgumentValue(field.value)', 'getArgumentValue(field.value, ast)');
gra = gra.replace(`
return obj;
default:`, `
return obj;
case 'Variable':
return ast.variableValues[argumentValue.name.value];
default:`);
fs.writeFileSync(fGQL_dir, fGQL);
fs.writeFileSync(gra_dir, gra);
When you run npm install
, it will auto patch the node modules to give variable support. If you already have your node_modules installed, you can run npm run postinstall
Once again, not recommended and no warranty is given. This is only for if you needed variables implemented yesterday like me.