Skip to content

Instantly share code, notes, and snippets.

@CatTail
Last active March 22, 2018 06:20
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save CatTail/2ed985c5afc5b41a4e06 to your computer and use it in GitHub Desktop.
Save CatTail/2ed985c5afc5b41a4e06 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
},
})
})
@SimonKuldin
Copy link

Thanks for this! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment