UNPKG

@omnigraph/json-schema

Version:

This package generates GraphQL Schema from JSON Schema and sample JSON request and responses. You can define your root field endpoints like below in your GraphQL Config for example;

110 lines (109 loc) 4.64 kB
import { isSomeInputTypeComposer, ListComposer, } from 'graphql-compose'; import { ResolveRootDirective, StatusCodeTypeNameDirective } from './directives.js'; export function getContainerTC(subgraphName, schemaComposer, output) { const containerTypeName = `${output.getTypeName()}_container`; schemaComposer.addDirective(ResolveRootDirective); return schemaComposer.getOrCreateOTC(containerTypeName, otc => otc.addFields({ [output.getTypeName()]: { type: output, directives: [ { name: 'resolveRoot', args: { subgraph: subgraphName, }, }, ], }, })); } export function getUnionTypeComposers({ subgraphName, schemaComposer, typeComposersList, subSchemaAndTypeComposers, logger, }) { if (new Set(typeComposersList).size === 1) { return typeComposersList[0]; } const unionInputFields = {}; const outputTypeComposers = []; let isOutputPlural = false; typeComposersList.forEach(typeComposers => { let { input, output } = typeComposers; if (output instanceof ListComposer) { output = output.getUnwrappedTC(); isOutputPlural = true; } if (isSomeInputTypeComposer(output)) { outputTypeComposers.push(getContainerTC(subgraphName, schemaComposer, output)); } else { outputTypeComposers.push(output); } if (input) { const inputTypeName = input instanceof ListComposer ? input.getUnwrappedTC().getTypeName() + '_list' : input.getTypeName(); unionInputFields[inputTypeName] = { type: input, }; } if (!input) { logger.debug(`No input type composer found for ${output.getTypeName()}, skipping...`); } }); if (Object.keys(unionInputFields).length === 1) { subSchemaAndTypeComposers.input = Object.values(unionInputFields)[0].type; } else { subSchemaAndTypeComposers.input.addFields(unionInputFields); } if (new Set(outputTypeComposers).size === 1) { subSchemaAndTypeComposers.output = outputTypeComposers[0]; } else { const directives = subSchemaAndTypeComposers.output.getDirectives() || []; const statusCodeOneOfIndexMap = subSchemaAndTypeComposers.output.getExtension('statusCodeOneOfIndexMap'); const statusCodeOneOfIndexMapEntries = Object.entries(statusCodeOneOfIndexMap || {}); for (const outputTypeComposerIndex in outputTypeComposers) { const outputTypeComposer = outputTypeComposers[outputTypeComposerIndex]; const statusCode = statusCodeOneOfIndexMapEntries.find(([statusCode, index]) => index.toString() === outputTypeComposerIndex.toString())?.[0]; if ('getFields' in outputTypeComposer) { if (statusCode != null) { schemaComposer.addDirective(StatusCodeTypeNameDirective); directives.push({ name: 'statusCodeTypeName', args: { subgraph: subgraphName, statusCode, typeName: outputTypeComposer.getTypeName(), }, }); } subSchemaAndTypeComposers.output.addType(outputTypeComposer); } else { for (const possibleType of outputTypeComposer.getTypes()) { subSchemaAndTypeComposers.output.addType(possibleType); } } } subSchemaAndTypeComposers.output.setDirectives(directives); } let flatten = false; // TODO: container suffix might not be coming from us if (subSchemaAndTypeComposers.output.getTypeName().endsWith('_container')) { const fields = subSchemaAndTypeComposers.output.getFields(); const fieldKeys = Object.keys(fields); if (fieldKeys.length === 1) { subSchemaAndTypeComposers.output = fields[fieldKeys[0]].type; flatten = isOutputPlural; } } return { input: subSchemaAndTypeComposers.input, output: isOutputPlural ? subSchemaAndTypeComposers.output.List : subSchemaAndTypeComposers.output, nullable: subSchemaAndTypeComposers.nullable, readOnly: subSchemaAndTypeComposers.readOnly, writeOnly: subSchemaAndTypeComposers.writeOnly, flatten, }; }