Skip to content

Commit

Permalink
First
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul Le Cam committed Nov 3, 2016
1 parent 11ecc3c commit 66bde56
Show file tree
Hide file tree
Showing 9 changed files with 338 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"presets": ["latest"],
"plugins": [
"syntax-flow",
"transform-flow-strip-types",
"transform-runtime"
]
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# graphql-fetch-schema

Fetch a GraphQL schema from a server and write it to file

## Usage

```sh
graphql-fetch-schema <url> [options]
```

### Options

```
-h, --help output usage information
-V, --version output the version number
-g, --graphql write schema.graphql file
-j, --json write schema.json file
-o, --output <directory> write to specified directory
```

## License

MIT
2 changes: 2 additions & 0 deletions bin/graphql-fetch-schema
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/env node
require('../lib/cli')
66 changes: 66 additions & 0 deletions lib/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
'use strict';

var _regenerator = require('babel-runtime/regenerator');

var _regenerator2 = _interopRequireDefault(_regenerator);

var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');

var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);

var _commander = require('commander');

var _commander2 = _interopRequireDefault(_commander);

var _index = require('./index');

var _index2 = _interopRequireDefault(_index);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var run = function () {
var _ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(url, options) {
var files;
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.prev = 0;
_context.next = 3;
return (0, _index2.default)(url, options);

case 3:
files = _context.sent;

files.forEach(function (file) {
console.log(file.filePath);
});
_context.next = 10;
break;

case 7:
_context.prev = 7;
_context.t0 = _context['catch'](0);

console.error(_context.t0);

case 10:
case 'end':
return _context.stop();
}
}
}, _callee, undefined, [[0, 7]]);
}));

return function run(_x, _x2) {
return _ref.apply(this, arguments);
};
}();

_commander2.default.version('0.1.0').usage('<url> [options]').option('-g, --graphql', 'write schema.graphql file').option('-j, --json', 'write schema.json file').option('-o, --output <directory>', 'write to specified directory').parse(process.argv);

run(_commander2.default.args[0], {
graphql: !!_commander2.default.graphql,
json: !!_commander2.default.json,
outputPath: _commander2.default.output
});
115 changes: 115 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});

var _regenerator = require('babel-runtime/regenerator');

var _regenerator2 = _interopRequireDefault(_regenerator);

var _stringify = require('babel-runtime/core-js/json/stringify');

var _stringify2 = _interopRequireDefault(_stringify);

var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');

var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);

var _promise = require('babel-runtime/core-js/promise');

var _promise2 = _interopRequireDefault(_promise);

var _utilities = require('graphql/utilities');

var _fs = require('fs');

var _fs2 = _interopRequireDefault(_fs);

var _nodeFetch = require('node-fetch');

var _nodeFetch2 = _interopRequireDefault(_nodeFetch);

var _path = require('path');

var _path2 = _interopRequireDefault(_path);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var writeFile = function writeFile(_ref) {
var filePath = _ref.filePath,
contents = _ref.contents;

return new _promise2.default(function (resolve, reject) {
_fs2.default.writeFile(filePath, contents, function (err) {
if (err) reject(err);else resolve();
});
});
};

exports.default = function () {
var _ref2 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(url) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var pathPrefix, res, schema, files;
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
// If no option is set, consider it's all
if (!options.graphql && !options.json) {
options.graphql = true;
options.json = true;
}
pathPrefix = options.outputPath || './';
_context.next = 4;
return (0, _nodeFetch2.default)(url, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: (0, _stringify2.default)({
query: _utilities.introspectionQuery
})
});

case 4:
res = _context.sent;
_context.next = 7;
return res.json();

case 7:
schema = _context.sent;
files = [];

if (options.graphql) {
files.push({
filePath: _path2.default.resolve(pathPrefix, 'schema.graphql'),
contents: (0, _utilities.printSchema)((0, _utilities.buildClientSchema)(schema.data))
});
}
if (options.json) {
files.push({
filePath: _path2.default.resolve(pathPrefix, 'schema.json'),
contents: (0, _stringify2.default)(schema, null, 2)
});
}

_context.next = 13;
return _promise2.default.all(files.map(writeFile));

case 13:
return _context.abrupt('return', files);

case 14:
case 'end':
return _context.stop();
}
}
}, _callee, undefined);
}));

return function (_x, _x2) {
return _ref2.apply(this, arguments);
};
}();
30 changes: 30 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "graphql-fetch-schema",
"version": "0.1.0",
"description": "Fetch a GraphQL schema from a server and write it to file",
"main": "lib/index.js",
"bin": {
"graphql-fetch-schema": "./bin/graphql-fetch-schema"
},
"scripts": {
"clean": "rm -rf ./lib",
"compile": "babel src --out-dir lib",
"build": "npm run clean && npm run compile",
"start": "npm run compile"
},
"author": "Paul Le Cam <[email protected]>",
"license": "MIT",
"dependencies": {
"babel-runtime": "^6.18.0",
"commander": "^2.9.0",
"graphql": "^0.7.2",
"node-fetch": "^1.6.3"
},
"devDependencies": {
"babel-cli": "^6.18.0",
"babel-plugin-syntax-flow": "^6.18.0",
"babel-plugin-transform-flow-strip-types": "^6.18.0",
"babel-plugin-transform-runtime": "^6.15.0",
"babel-preset-latest": "^6.16.0"
}
}
30 changes: 30 additions & 0 deletions src/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// @flow

import program from 'commander'

import fetchSchema from './index'

const run = async (url: string, options: Object) => {
try {
const files = await fetchSchema(url, options)
files.forEach((file: Object) => {
console.log(file.filePath)
})
} catch (err) {
console.error(err)
}
}

program
.version('0.1.0')
.usage('<url> [options]')
.option('-g, --graphql', 'write schema.graphql file')
.option('-j, --json', 'write schema.json file')
.option('-o, --output <directory>', 'write to specified directory')
.parse(process.argv)

run(program.args[0], {
graphql: !!program.graphql,
json: !!program.json,
outputPath: program.output,
})
63 changes: 63 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// @flow

import {
buildClientSchema,
introspectionQuery,
printSchema,
} from 'graphql/utilities'
import fs from 'fs'
import fetch from 'node-fetch'
import path from 'path'

type Options = {
graphql?: boolean,
json?: boolean,
outputPath?: string,
}

const writeFile = ({filePath, contents}: {filePath: string, contents: string}) => {
return new Promise((resolve, reject) => {
fs.writeFile(filePath, contents, (err) => {
if (err) reject(err)
else resolve()
})
})
}

export default async (url: string, options: Options = {}) => {
// If no option is set, consider it's all
if (!options.graphql && !options.json) {
options.graphql = true
options.json = true
}
const pathPrefix = options.outputPath || './'

const res = await fetch(url, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: introspectionQuery,
}),
})
const schema = await res.json()

const files = []
if (options.graphql) {
files.push({
filePath: path.resolve(pathPrefix, 'schema.graphql'),
contents: printSchema(buildClientSchema(schema.data)),
})
}
if (options.json) {
files.push({
filePath: path.resolve(pathPrefix, 'schema.json'),
contents: JSON.stringify(schema, null, 2),
})
}

await Promise.all(files.map(writeFile))
return files
}

0 comments on commit 66bde56

Please sign in to comment.