UNPKG

@dossierhq/graphql

Version:

A library for creating GraphQL servers with Dossier.

115 lines 4.18 kB
/// <reference types="./TypeRepository.d.ts" /> import { GraphQLEnumType, isEnumType, isInputType, isInterfaceType, isOutputType, } from 'graphql'; import { toAdminComponentInputTypeName, toAdminTypeName, toEnumName } from './NameGenerator.js'; export class TypeRepository { #types = []; getTypes() { return this.#types; } addType(type) { if (this.#types.find((it) => it.name === type.name)) { throw new Error(`Type with name ${type.name} already exists`); } this.#types.push(type); } getType(name) { const type = this.#types.find((x) => x.name === name); if (!type) { throw new Error(`Type with name ${name} doesn't exist`); } return type; } getOutputType(name) { const type = this.getType(name); if (isOutputType(type)) { return type; } throw new Error(`Type ${name} is not an output type`); } getEnumType(name) { const type = this.getType(name); if (isEnumType(type)) { return type; } throw new Error(`Type ${name} is not an enum type`); } getInputType(name) { const type = this.getType(name); if (isInputType(type)) { return type; } throw new Error(`Type ${name} is not an input type`); } getInterface(name) { const type = this.getType(name); if (isInterfaceType(type)) { return type; } throw new Error(`Type ${name} is not an interface`); } getInterfaces(...names) { return names.map((name) => this.getInterface(name)); } getOrCreateEntityUnion(isAdmin, names) { if (names.length === 0) { return this.getOutputType(toAdminTypeName('Entity', isAdmin)); } // Remove duplicates, sort alphabetically const filteredNames = [...new Set(names)]; filteredNames.sort(); if (filteredNames.length === 1) { return this.getOutputType(toAdminTypeName(filteredNames[0], isAdmin)); } const enumName = toEnumName(filteredNames, isAdmin); const existingEnum = this.#types.find((x) => x.name === enumName); if (existingEnum) { if (isOutputType(existingEnum)) { return existingEnum; } throw new Error(`Type ${enumName} is not an output type`); } const enumValues = {}; filteredNames.forEach((name) => (enumValues[toAdminTypeName(name, isAdmin)] = {})); const enumType = new GraphQLEnumType({ name: enumName, values: enumValues, }); this.addType(enumType); return enumType; } getOrCreateValueUnion(isAdmin, names) { if (names.length === 0) { return this.getOutputType(toAdminTypeName('Component', isAdmin)); } // Remove duplicates, sort alphabetically const filteredNames = [...new Set(names)]; filteredNames.sort(); if (filteredNames.length === 1) { return this.getOutputType(toAdminTypeName(filteredNames[0], isAdmin)); } const enumName = `_${toAdminTypeName(filteredNames.join('Or'), isAdmin)}`; const existingEnum = this.#types.find((x) => x.name === enumName); if (existingEnum) { if (isOutputType(existingEnum)) { return existingEnum; } throw new Error(`Type ${enumName} is not an output type`); } const enumValues = {}; filteredNames.forEach((name) => (enumValues[toAdminTypeName(name, isAdmin)] = {})); const enumType = new GraphQLEnumType({ name: enumName, values: enumValues, }); this.addType(enumType); return enumType; } getValueInputType(names) { const uniqueNames = [...new Set(names)]; if (uniqueNames.length !== 1) { return null; //There's no support for polymorphism on input types } return this.getInputType(toAdminComponentInputTypeName(uniqueNames[0])); } } //# sourceMappingURL=TypeRepository.js.map