Created
May 20, 2019 00:33
-
-
Save dex4er/330fb7fed04f88b58ec5388744bf78f7 to your computer and use it in GitHub Desktop.
make-ts-from-graphql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ts-node | |
/// <reference types="node" /> | |
import glob from 'fast-glob' | |
import fs from 'fs' | |
import path from 'path' | |
import yargs from 'yargs' | |
const defaultPatterns = ['**/*.graphql', '**/*.gql', '!node_modules'] | |
const argv = yargs | |
.usage('$0 [options] [patterns]\n\n patterns default: ' + defaultPatterns.join(' ')) | |
.option('target', { | |
alias: 't', | |
describe: 'Generate code for language (ts or js)', | |
string: true, | |
default: fs.existsSync('tsconfig.json') ? 'ts' : 'js', | |
}) | |
.option('quiet', { | |
alias: 'q', | |
describe: 'Do not log currently processed files', | |
boolean: true, | |
default: false, | |
}) | |
.help('help') | |
.alias('help', 'h') | |
.alias('version', 'V') | |
.strict().argv | |
const patterns = argv._.length ? argv._ : defaultPatterns | |
function upperFirst(str: string): string { | |
return str[0].toUpperCase() + str.slice(1) | |
} | |
function camelize(str: string): string { | |
return str.split(/[\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/).reduce((result, word, index) => { | |
word = word.toLowerCase() | |
return result + (index ? upperFirst(word) : word) | |
}, '') | |
} | |
const BACKTICK = '`' | |
const LF = '\n' | |
function jsTemplate(variable: string, graphqlContent: string): string { | |
const content = graphqlContent | |
.replace(/\s*$/, '') | |
.replace(/'/g, "\\'") | |
.replace(/\n/g, '\\n') | |
return [ | |
'// eslint:disable', | |
'"use strict"', | |
'var gql = require("graphql-tag")', | |
`module.exports = gql(['${content}'])`, | |
`module.exports.default = module.exports`, | |
`module.exports.${variable} = module.exports`, | |
'', | |
].join('\n') | |
} | |
function tsTemplate(variable: string, graphqlContent: string): string { | |
const content = graphqlContent.replace(/^/gm, ' ').replace(/\s*$/, '') | |
return [ | |
'// tslint:disable', | |
'import {DocumentNode} from "graphql"', | |
'import gql from "graphql-tag"', | |
'// prettier-ignore', | |
`export const ${variable}: DocumentNode = gql${BACKTICK}${LF}${content}${LF}${BACKTICK}`, | |
`export default ${variable}`, | |
'', | |
].join('\n') | |
} | |
function targetTemplate(variable: string, graphqlContent: string): string { | |
if (argv.target === 'ts') { | |
return tsTemplate(variable, graphqlContent) | |
} else { | |
return jsTemplate(variable, graphqlContent) | |
} | |
} | |
glob<string>(patterns, {stats: false}).then(files => { | |
for (const graphqlFile of files) { | |
const graphqlExt = path.extname(graphqlFile) | |
if (graphqlExt !== '.graphql' && graphqlExt !== '.gql') { | |
console.info(`Skipping file ${graphqlFile}`) | |
continue | |
} | |
const graphqlBasename = path.basename(graphqlFile, graphqlExt) | |
const targetExt = argv.target === 'ts' ? '.ts' : '.js' | |
const targetFile = path.join(path.dirname(graphqlFile), graphqlBasename) + targetExt | |
if (!argv.quiet) { | |
console.info(`Creating ${targetFile} from ${graphqlFile}`) | |
} | |
const graphqlContent = fs.readFileSync(graphqlFile).toString() | |
const targetVariable = camelize(`${graphqlBasename} Query`) | |
const targetContent = targetTemplate(targetVariable, graphqlContent) | |
fs.writeFileSync(targetFile, targetContent) | |
} | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment