-
Notifications
You must be signed in to change notification settings - Fork 469
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Codegen: Also generate a definition file for .graphql fils #604
Comments
This would be nice. It would allow for something like this: import React from 'react'
import { Query } from 'react-apollo'
import PersonQuery, {
PersonQueryData,
PersonQueryVariables,
} from 'queries/Person.gql'
// side-note: TSX really needs to support generics on components because this is annoying
class PersonQueryComponent extends Query<PersonQueryData, PersonQueryVariables> {}
export default () => (
<PersonQueryComponent query={PersonQuery}>
{/* ... */}
</PersonQueryComponent>
) It seems like it would not be too hard of a modification to |
I wrote a very simple and dumb script to get the job done but would be nice if this was part of #!/usr/bin/env node
/* eslint-disable */
const fs = require('fs');
const path = require('path');
const walk = require('walk');
const { EOL } = require('os');
/**
* Generate a definition file of exported members when importing a GraphQL file with
* graphql-tag/loader.
*
* Note: this is different from Apollo CodeGen types. The generated type definition file
* is good for enforcing named import correctness only.
*
* @param {string} file Raw GraphQL file
*/
function generateExportDefinition(file = '') {
const lines = file.split(EOL);
let output = [
'/* tslint:disable */',
'/* eslint-disable */',
'// This file was automatically generated and should not be edited.',
'',
"import { DocumentNode } from 'graphql';",
];
/**
* Process a specific GraphQL keyword
* @param {string} keyword
* @param {RegExp} regex
* @param {string} comment
*/
function processKeyword(keyword, regex, comment) {
const keywordNames = lines
.filter((line) => line.startsWith(keyword) && line.match(regex))
.map((line) => line.match(regex)[1])
.filter(Boolean);
if (keywordNames.length) {
output = [
...output,
'',
'// ====================================================',
'// ' + comment,
'// ====================================================',
];
}
for (const keywordName of keywordNames) {
output.push(`/** \`${keywordName}\` ${keyword} */`);
output.push(`export const ${keywordName}: DocumentNode;`);
output.push('');
}
}
processKeyword('query', /query\s+([A-z]+)/, 'Queries');
processKeyword('mutation', /mutation\s+([A-z]+)/, 'Mutations');
processKeyword('fragment', /fragment\s+([A-z]+)/, 'Fragments');
processKeyword('input', /input\s+([A-z]+)/, 'Inputs');
return output.join(EOL);
}
const walker = walk.walk(path.join(__dirname, 'src'), {
filters: ['node_modules', 'build'],
});
walker.on('file', (root, fileStats, next) => {
if (fileStats.name.endsWith('.graphql')) {
const fullPath = path.join(root, fileStats.name);
const input = fs.readFileSync(fullPath).toString();
const output = generateExportDefinition(input);
fs.writeFileSync(fullPath + '.d.ts', output);
}
next();
}); |
I agree, this would clean up code nicely. |
Similar to typed-css-modules the codegen can generate declaration files for existing query files that has list of exported queries and mutations.
This will help TypeScript enforce correct names when importing queries from
.graphql
file using"graphql-tag/loader"
.The text was updated successfully, but these errors were encountered: