get-graphql-from-jsonschema
Advanced tools
Comparing version 3.0.1 to 4.0.0
@@ -17,12 +17,5 @@ "use strict"; | ||
const graphqlTypeDefinitions = []; | ||
let currentGraphqlTypeDefinition = ''; | ||
if (direction === 'input') { | ||
currentGraphqlTypeDefinition += 'input'; | ||
} | ||
else { | ||
currentGraphqlTypeDefinition += 'type'; | ||
} | ||
currentGraphqlTypeDefinition += ` ${graphqlTypeName} {\n`; | ||
const lines = []; | ||
for (const [propertyName, propertySchema] of Object.entries(schema.properties)) { | ||
const isRequired = (_a = (schema.required && schema.required.includes(propertyName)), (_a !== null && _a !== void 0 ? _a : false)); | ||
const isRequired = (_a = (schema.required && schema.required.includes(propertyName))) !== null && _a !== void 0 ? _a : false; | ||
const { typeName: propertyGraphqlTypeName, typeDefinitions: propertyGraphqlTypeDefinitions } = parseSchema_1.parseSchema({ | ||
@@ -33,12 +26,29 @@ path: [...path, propertyName], | ||
}); | ||
currentGraphqlTypeDefinition += ` ${propertyName}: ${propertyGraphqlTypeName}`; | ||
let line = ` ${propertyName}: ${propertyGraphqlTypeName}`; | ||
if (isRequired) { | ||
currentGraphqlTypeDefinition += '!\n'; | ||
line += '!\n'; | ||
} | ||
else { | ||
currentGraphqlTypeDefinition += '\n'; | ||
line += '\n'; | ||
} | ||
lines.push(line); | ||
graphqlTypeDefinitions.push(...propertyGraphqlTypeDefinitions); | ||
} | ||
currentGraphqlTypeDefinition += '}'; | ||
let currentGraphqlTypeDefinition = ''; | ||
if (direction === 'input') { | ||
currentGraphqlTypeDefinition += 'input'; | ||
} | ||
else { | ||
currentGraphqlTypeDefinition += 'type'; | ||
} | ||
if (lines.length > 0) { | ||
currentGraphqlTypeDefinition += ` ${graphqlTypeName} {\n`; | ||
for (const line of lines) { | ||
currentGraphqlTypeDefinition += line; | ||
} | ||
currentGraphqlTypeDefinition += '}'; | ||
} | ||
else { | ||
currentGraphqlTypeDefinition += ` ${graphqlTypeName}`; | ||
} | ||
graphqlTypeDefinitions.push(currentGraphqlTypeDefinition); | ||
@@ -45,0 +55,0 @@ return { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const errors_1 = require("./errors"); | ||
const handleArrayType_1 = require("./handleArrayType"); | ||
const handleObjectType_1 = require("./handleObjectType"); | ||
const handleScalarType_1 = require("./handleScalarType"); | ||
const isArrayType_1 = require("./isArrayType"); | ||
const isObjectType_1 = require("./isObjectType"); | ||
const isScalarType_1 = require("./isScalarType"); | ||
const parseAnyOf_1 = require("./parseAnyOf"); | ||
const parseType_1 = require("./parseType"); | ||
const common_tags_1 = require("common-tags"); | ||
const toBreadcrumb_1 = require("./toBreadcrumb"); | ||
const toPascalCase_1 = require("./toPascalCase"); | ||
const parseSchema = function ({ path, schema, direction }) { | ||
if (!schema.type) { | ||
throw new errors_1.errors.SchemaInvalid(`Property 'type' at '${toBreadcrumb_1.toBreadcrumb(path)}' is missing.`); | ||
let result; | ||
if (schema.type) { | ||
result = parseType_1.parseType({ path, schema, direction }); | ||
} | ||
const jsonTypes = [schema.type].flat(); | ||
const graphqlTypeNames = []; | ||
const graphqlTypeDefinitions = []; | ||
for (const jsonType of jsonTypes) { | ||
let result; | ||
if (isScalarType_1.isScalarType({ type: jsonType })) { | ||
result = handleScalarType_1.handleScalarType({ type: jsonType }); | ||
} | ||
else if (isArrayType_1.isArrayType({ type: jsonType })) { | ||
result = handleArrayType_1.handleArrayType({ path, schema, direction }); | ||
} | ||
else if (isObjectType_1.isObjectType({ type: jsonType })) { | ||
result = handleObjectType_1.handleObjectType({ path, schema, direction }); | ||
} | ||
else { | ||
throw new errors_1.errors.TypeInvalid(`Type '${jsonType}' at '${path}' is invalid.`); | ||
} | ||
graphqlTypeNames.push(result.typeName); | ||
graphqlTypeDefinitions.push(...result.typeDefinitions); | ||
else if (schema.anyOf) { | ||
result = parseAnyOf_1.parseAnyOf({ path, schema, direction }); | ||
} | ||
const graphqlTypeName = graphqlTypeNames.join(' | '); | ||
return { | ||
typeName: graphqlTypeName, | ||
typeDefinitions: graphqlTypeDefinitions | ||
}; | ||
else { | ||
throw new errors_1.errors.SchemaInvalid(`Structure at '${toBreadcrumb_1.toBreadcrumb(path)}' not recognized.`); | ||
} | ||
if (result.typeName.includes('|')) { | ||
const typeName = toPascalCase_1.toPascalCase(path); | ||
result.typeDefinitions.push(common_tags_1.stripIndent ` | ||
union ${typeName} = ${result.typeName} | ||
`); | ||
result.typeName = typeName; | ||
} | ||
return result; | ||
}; | ||
exports.parseSchema = parseSchema; |
@@ -0,1 +1,20 @@ | ||
# [4.0.0](https://github.com/thenativeweb/get-graphql-from-jsonschema/compare/3.0.1...4.0.0) (2020-02-26) | ||
### Features | ||
* Parse anyOf and ignore null. ([#91](https://github.com/thenativeweb/get-graphql-from-jsonschema/issues/91)) ([2b6bad7](https://github.com/thenativeweb/get-graphql-from-jsonschema/commit/2b6bad7910a849ea74826ecc0517bfc6ebc6ef0e)) | ||
### BREAKING CHANGES | ||
* Changes the names of resulting types by appending | ||
indexes for types and anyOfs. | ||
* Update README.md | ||
* fix: Update readme. | ||
Co-authored-by: Golo Roden <golo.roden@thenativeweb.io> | ||
## [3.0.1](https://github.com/thenativeweb/get-graphql-from-jsonschema/compare/3.0.0...3.0.1) (2020-02-03) | ||
@@ -2,0 +21,0 @@ |
@@ -23,12 +23,4 @@ import { Direction } from './Direction'; | ||
let currentGraphqlTypeDefinition = ''; | ||
const lines = []; | ||
if (direction === 'input') { | ||
currentGraphqlTypeDefinition += 'input'; | ||
} else { | ||
currentGraphqlTypeDefinition += 'type'; | ||
} | ||
currentGraphqlTypeDefinition += ` ${graphqlTypeName} {\n`; | ||
for (const [ propertyName, propertySchema ] of Object.entries(schema.properties)) { | ||
@@ -48,15 +40,34 @@ const isRequired = ( | ||
currentGraphqlTypeDefinition += ` ${propertyName}: ${propertyGraphqlTypeName}`; | ||
let line = ` ${propertyName}: ${propertyGraphqlTypeName}`; | ||
if (isRequired) { | ||
currentGraphqlTypeDefinition += '!\n'; | ||
line += '!\n'; | ||
} else { | ||
currentGraphqlTypeDefinition += '\n'; | ||
line += '\n'; | ||
} | ||
lines.push(line); | ||
graphqlTypeDefinitions.push(...propertyGraphqlTypeDefinitions); | ||
} | ||
currentGraphqlTypeDefinition += '}'; | ||
let currentGraphqlTypeDefinition = ''; | ||
if (direction === 'input') { | ||
currentGraphqlTypeDefinition += 'input'; | ||
} else { | ||
currentGraphqlTypeDefinition += 'type'; | ||
} | ||
if (lines.length > 0) { | ||
currentGraphqlTypeDefinition += ` ${graphqlTypeName} {\n`; | ||
for (const line of lines) { | ||
currentGraphqlTypeDefinition += line; | ||
} | ||
currentGraphqlTypeDefinition += '}'; | ||
} else { | ||
currentGraphqlTypeDefinition += ` ${graphqlTypeName}`; | ||
} | ||
graphqlTypeDefinitions.push(currentGraphqlTypeDefinition); | ||
@@ -63,0 +74,0 @@ |
import { Direction } from './Direction'; | ||
import { errors } from './errors'; | ||
import { handleArrayType } from './handleArrayType'; | ||
import { handleObjectType } from './handleObjectType'; | ||
import { handleScalarType } from './handleScalarType'; | ||
import { isArrayType } from './isArrayType'; | ||
import { isObjectType } from './isObjectType'; | ||
import { isScalarType } from './isScalarType'; | ||
import { JSONSchema4 } from 'json-schema'; | ||
import { parseAnyOf } from './parseAnyOf'; | ||
import { parseType } from './parseType'; | ||
import { stripIndent } from 'common-tags'; | ||
import { toBreadcrumb } from './toBreadcrumb'; | ||
import { toPascalCase } from './toPascalCase'; | ||
@@ -17,36 +15,24 @@ const parseSchema = function ({ path, schema, direction }: { | ||
}): { typeName: string; typeDefinitions: string[] } { | ||
if (!schema.type) { | ||
throw new errors.SchemaInvalid(`Property 'type' at '${toBreadcrumb(path)}' is missing.`); | ||
let result: { typeName: string; typeDefinitions: string[] }; | ||
if (schema.type) { | ||
result = parseType({ path, schema, direction }); | ||
} else if (schema.anyOf) { | ||
result = parseAnyOf({ path, schema, direction }); | ||
} else { | ||
throw new errors.SchemaInvalid(`Structure at '${toBreadcrumb(path)}' not recognized.`); | ||
} | ||
const jsonTypes: string[] = [ schema.type ].flat(); | ||
if (result.typeName.includes('|')) { | ||
const typeName = toPascalCase(path); | ||
const graphqlTypeNames: string[] = []; | ||
const graphqlTypeDefinitions: string[] = []; | ||
for (const jsonType of jsonTypes) { | ||
let result; | ||
if (isScalarType({ type: jsonType })) { | ||
result = handleScalarType({ type: jsonType }); | ||
} else if (isArrayType({ type: jsonType })) { | ||
result = handleArrayType({ path, schema, direction }); | ||
} else if (isObjectType({ type: jsonType })) { | ||
result = handleObjectType({ path, schema, direction }); | ||
} else { | ||
throw new errors.TypeInvalid(`Type '${jsonType}' at '${path}' is invalid.`); | ||
} | ||
graphqlTypeNames.push(result.typeName); | ||
graphqlTypeDefinitions.push(...result.typeDefinitions); | ||
result.typeDefinitions.push(stripIndent` | ||
union ${typeName} = ${result.typeName} | ||
`); | ||
result.typeName = typeName; | ||
} | ||
const graphqlTypeName = graphqlTypeNames.join(' | '); | ||
return { | ||
typeName: graphqlTypeName, | ||
typeDefinitions: graphqlTypeDefinitions | ||
}; | ||
return result; | ||
}; | ||
export { parseSchema }; |
{ | ||
"name": "get-graphql-from-jsonschema", | ||
"version": "3.0.1", | ||
"version": "4.0.0", | ||
"description": "get-graphql-from-jsonschema gets a GraphQL schema from a JSON schema.", | ||
@@ -25,4 +25,4 @@ "contributors": [ | ||
"common-tags": "1.8.0", | ||
"roboter": "11.0.12", | ||
"semantic-release-configuration": "1.0.16" | ||
"roboter": "11.0.24", | ||
"semantic-release-configuration": "1.0.18" | ||
}, | ||
@@ -29,0 +29,0 @@ "repository": { |
@@ -73,19 +73,19 @@ # get-graphql-from-jsonschema | ||
console.log(typeName); | ||
// => Person | ||
// => PersonT0 | ||
console.log(typeDefinitions); | ||
// => [ | ||
// 'type PersonCoordinates { | ||
// 'type PersonT0CoordinatesT0 { | ||
// latitude: Float! | ||
// longitude: Float! | ||
// }', | ||
// 'type PersonTags { | ||
// 'type PersonT0TagsT0T0 { | ||
// key: String! | ||
// value: String! | ||
// }', | ||
// 'type Person { | ||
// 'type PersonT0 { | ||
// firstName: String! | ||
// lastName: String | ||
// coordinates: PersonCoordinates | ||
// tags: [PersonTags]! | ||
// coordinates: PersonT0CoordinatesT0 | ||
// tags: [PersonT0TagsT0T0]! | ||
// }' | ||
@@ -95,2 +95,4 @@ // ] | ||
The `T0` suffixes are due to enumerating the types in each schema. If a schema has multiple types, they are noted with increasing indexes, to differentiate them in resulting union types. This also happens with `anyOf` constructs. | ||
If you want to use the generated types as input types for a mutation, additionally provide the `direction` option to the call to `getGraphqlFromJsonSchema` and set its value to `input`: | ||
@@ -108,2 +110,9 @@ | ||
### Knowing the limitations | ||
Unfortunately, it is not possible to map every aspect of a JSON schema to a GraphQL schema. When using `getGraphqlFromJsonSchema`, the following limitations apply: | ||
- The `null` type gets ignored, since it can not be mapped to GraphQL directly. | ||
- The keywords `allOf` and `oneOf` get ignored, since their logic can not be mapped to GraphQL. However, the `anyOf` keyword is supported. | ||
## Running the build | ||
@@ -110,0 +119,0 @@ |
29414
52
634
122