Skip to content

Instantly share code, notes, and snippets.

@sekmet
Forked from CatTail/input.json
Created September 23, 2016 18:11
Show Gist options
  • Save sekmet/a942c95b3461c844b9aa6259d2f04c01 to your computer and use it in GitHub Desktop.
Save sekmet/a942c95b3461c844b9aa6259d2f04c01 to your computer and use it in GitHub Desktop.
JSON to Graphql schema generator
{"title":"A New Hope","episode_id":4,"opening_crawl":"It is a period of civil war.\r\nRebel spaceships, striking\r\nfrom a hidden base, have won\r\ntheir first victory against\r\nthe evil Galactic Empire.\r\n\r\nDuring the battle, Rebel\r\nspies managed to steal secret\r\nplans to the Empire's\r\nultimate weapon, the DEATH\r\nSTAR, an armored space\r\nstation with enough power\r\nto destroy an entire planet.\r\n\r\nPursued by the Empire's\r\nsinister agents, Princess\r\nLeia races home aboard her\r\nstarship, custodian of the\r\nstolen plans that can save her\r\npeople and restore\r\nfreedom to the galaxy....","director":"George Lucas","producer":"Gary Kurtz, Rick McCallum","release_date":"1977-05-25","characters":["http://swapi.co/api/people/1/","http://swapi.co/api/people/2/","http://swapi.co/api/people/3/","http://swapi.co/api/people/4/","http://swapi.co/api/people/5/","http://swapi.co/api/people/6/","http://swapi.co/api/people/7/","http://swapi.co/api/people/8/","http://swapi.co/api/people/9/","http://swapi.co/api/people/10/","http://swapi.co/api/people/12/","http://swapi.co/api/people/13/","http://swapi.co/api/people/14/","http://swapi.co/api/people/15/","http://swapi.co/api/people/16/","http://swapi.co/api/people/18/","http://swapi.co/api/people/19/","http://swapi.co/api/people/81/"],"planets":["http://swapi.co/api/planets/2/","http://swapi.co/api/planets/3/","http://swapi.co/api/planets/1/"],"starships":["http://swapi.co/api/starships/2/","http://swapi.co/api/starships/3/","http://swapi.co/api/starships/5/","http://swapi.co/api/starships/9/","http://swapi.co/api/starships/10/","http://swapi.co/api/starships/11/","http://swapi.co/api/starships/12/","http://swapi.co/api/starships/13/"],"vehicles":["http://swapi.co/api/vehicles/4/","http://swapi.co/api/vehicles/6/","http://swapi.co/api/vehicles/7/","http://swapi.co/api/vehicles/8/"],"species":["http://swapi.co/api/species/4/","http://swapi.co/api/species/5/","http://swapi.co/api/species/3/","http://swapi.co/api/species/2/","http://swapi.co/api/species/1/"],"created":"2014-12-10T14:23:31.880000Z","edited":"2015-04-11T09:46:52.774897Z","url":"http://swapi.co/api/films/1/"}
/*
* Usage:
* 1. npm install lodash
* 2. node json-to-graphql.js <filename>
*
* Only support
GraphQLObjectType
GraphQLList
GraphQLString
GraphQLBoolean
GraphQLInt
GraphQLFloat
* See: https://github.com/graphql/graphql-js/blob/master/src/type/index.js
*/
var _ = require('lodash')
var fs = require('fs')
var path = require('path')
var INDENT = 4
var TAB = new Array(INDENT).fill(' ').join('')
function transform(json, level, name) {
var definition
if (_.isArray(json)) {
if (name.slice(-1) === 's') {
name = name.slice(0, -1)
} else {
name = name + 'Item'
}
definition = transform(json[0], level + INDENT, name)
if (!definition) return
return `new GraphQLList(${definition})`
} else if (_.isString(json)) {
return `GraphQLString`
} else if (_.isBoolean(json)) {
return `GraphQLString`
} else if (isInt(json)) {
return `GraphQLInt`
} else if (isFloat(json)) {
return `GraphQLFloat`
} else if (_.isObject(json)) {
if (Object.keys(json).length === 0) return
var field, value
var spaces = new Array(level).fill(' ').join('')
var name = name ? (name[0].toUpperCase() + name.slice(1)) : ''
var schema = `new GraphQLObjectType({
${spaces}${TAB}name: "${name}",
${spaces}${TAB}description: "",
${spaces}${TAB}fields: () => ({`
for (field in json) {
value = json[field]
definition = transform(value, level + INDENT * 2, field)
if (!definition) continue
schema += `
${spaces}${TAB}${TAB}"${field}": {
${spaces}${TAB}${TAB}${TAB}type: ${definition}
${spaces}${TAB}${TAB}},`
}
schema += `
${spaces}${TAB}})
${spaces}})`
return schema
}
}
// http://stackoverflow.com/questions/3885817/how-to-check-that-a-number-is-float-or-integer
function isInt(n){
return Number(n) === n && n % 1 === 0;
}
function isFloat(n){
return n === Number(n) && n % 1 !== 0;
}
if (process.argv.length < 3) {
console.error(`Usage: node json-to-graphql.js <filename>`)
process.exit(1)
}
var filename = process.argv[2]
var json = fs.readFileSync(filename, 'utf8')
json = JSON.parse(json)
var schema = transform(json, 0, path.basename(filename, path.extname(filename)))
schema = `// Auto generate by https://gist.github.com/CatTail/2ed985c5afc5b41a4e06
import {
GraphQLInt,
GraphQLFloat,
GraphQLList,
GraphQLObjectType,
GraphQLString,
} from 'graphql'
var Type = ${schema}
export default Type
`
console.log(schema)
new GraphQLObjectType({
name: "some name",
description: "",
fields: () => ({
"title": {
type: GraphQLString
},
"episode_id": {
type: GraphQLInt
},
"opening_crawl": {
type: GraphQLString
},
"director": {
type: GraphQLString
},
"producer": {
type: GraphQLString
},
"release_date": {
type: GraphQLString
},
"characters": {
type: new GraphQLList(GraphQLString)
},
"planets": {
type: new GraphQLList(GraphQLString)
},
"starships": {
type: new GraphQLList(GraphQLString)
},
"vehicles": {
type: new GraphQLList(GraphQLString)
},
"species": {
type: new GraphQLList(GraphQLString)
},
"created": {
type: GraphQLString
},
"edited": {
type: GraphQLString
},
"url": {
type: GraphQLString
},
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment