UNPKG

@pothos/core

Version:

Pothos (formerly GiraphQL) is a plugin based schema builder for creating code-first GraphQL schemas in typescript

257 lines (256 loc) 11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "ConfigStore", { enumerable: true, get: function() { return ConfigStore; } }); const _errors = require("./errors"); const _base = require("./refs/base"); const _inputobject = require("./refs/input-object"); const _interface = require("./refs/interface"); const _mutation = require("./refs/mutation"); const _object = require("./refs/object"); const _query = require("./refs/query"); const _subscription = require("./refs/subscription"); function _define_property(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } class ConfigStore { addFields(param, fields) { this.onTypeConfig(param, (_config, ref)=>{ if (!(ref instanceof _interface.InterfaceRef || ref instanceof _object.ObjectRef || ref instanceof _query.QueryRef || ref instanceof _mutation.MutationRef || ref instanceof _subscription.SubscriptionRef)) { throw new _errors.PothosSchemaError(`Can not add fields to ${ref} because it is not an object`); } ref.addFields(fields); }); } addInputFields(param, fields) { this.onTypeConfig(param, (_config, ref)=>{ if (!(ref instanceof _inputobject.InputObjectRef)) { throw new _errors.PothosSchemaError(`Can not add fields to ${ref} because it is not an input object`); } ref.addFields(fields); }); } associateParamWithRef(param, ref) { const resolved = this.resolveParamAssociations(ref); this.paramAssociations.set(param, resolved); var _this_pendingTypeConfigResolutions_get; const pendingResolutions = (_this_pendingTypeConfigResolutions_get = this.pendingTypeConfigResolutions.get(param)) !== null && _this_pendingTypeConfigResolutions_get !== void 0 ? _this_pendingTypeConfigResolutions_get : []; if (pendingResolutions.length > 0) { if (typeof resolved === 'string' && this.typeConfigs.has(resolved)) { for (const cb of pendingResolutions){ const config = this.typeConfigs.get(resolved); cb(config, this.implementors.get(config.name)); } } else { for (const cb of pendingResolutions){ this.onTypeConfig(resolved, cb); } } } this.pendingTypeConfigResolutions.delete(param); } onTypeConfig(param, onConfig) { const resolved = this.resolveParamAssociations(param); if (typeof resolved === 'string' && this.typeConfigs.has(resolved)) { const config = this.typeConfigs.get(resolved); onConfig(config, this.implementors.get(config.name)); } else { if (!this.pendingTypeConfigResolutions.has(resolved)) { this.pendingTypeConfigResolutions.set(resolved, []); } this.pendingTypeConfigResolutions.get(resolved).push(onConfig); } } onTypeConfigOfKind(param, kind, onConfig) { this.onTypeConfig(param, (config)=>{ if (config.kind !== kind) { throw new _errors.PothosSchemaError(`Expected ${this.describeRef(param)} to be of kind ${kind} but it is of kind ${config.kind}`); } onConfig(config); }); } addTypeRef(ref) { if (this.refs.has(ref)) { return; } if (!this.pending) { ref.prepareForBuild(); } this.refs.add(ref); ref.onConfig((config)=>{ const implementor = this.implementors.get(config.name); if (implementor && implementor !== ref) { throw new _errors.PothosSchemaError(`Duplicate typename: Another type with name ${config.name} already exists.`); } if (!implementor) { this.implementors.set(config.name, ref); this.associateParamWithRef(ref, config.name); if (ref instanceof _object.ObjectRef || ref instanceof _interface.InterfaceRef || ref instanceof _inputobject.InputObjectRef) { if (!this.fields.has(config.name)) { this.fields.set(config.name, new Map()); } this.onPrepare(()=>{ ref.onField((fieldName, field)=>{ const fields = this.fields.get(config.name); if (fields.has(fieldName)) { throw new _errors.PothosSchemaError(`Duplicate field ${fieldName} on ${config.name}`); } var _this_typeConfigs_get; fields.set(fieldName, field.getConfig(fieldName, (_this_typeConfigs_get = this.typeConfigs.get(config.name)) !== null && _this_typeConfigs_get !== void 0 ? _this_typeConfigs_get : config)); }); }); } } this.typeConfigs.set(config.name, config); if (this.pendingTypeConfigResolutions.has(config.name)) { const cbs = this.pendingTypeConfigResolutions.get(config.name); for (const cb of cbs){ cb(config, ref); } } this.pendingTypeConfigResolutions.delete(config.name); }); } subscribeToFields(_ref) {} hasImplementation(typeName) { return this.typeConfigs.has(typeName); } hasConfig(ref) { const resolved = this.resolveParamAssociations(ref); if (typeof resolved !== 'string' || !this.typeConfigs.has(resolved)) { return false; } return true; } getTypeConfig(ref, kind) { const resolved = this.resolveParamAssociations(ref); if (typeof resolved !== 'string' || !this.typeConfigs.has(resolved)) { throw new _errors.PothosSchemaError(`${this.describeRef(ref)} has not been implemented`); } const config = this.typeConfigs.get(resolved); if (kind && config.graphqlKind !== kind) { throw new _errors.PothosSchemaError(`Expected ref to resolve to a ${kind} type, but got ${config.kind}`); } return config; } getInputTypeRef(param) { const resolved = this.resolveParamAssociations(param); if (param instanceof _base.BaseTypeRef) { if (param.kind !== 'InputObject' && param.kind !== 'Enum' && param.kind !== 'Scalar') { throw new _errors.PothosSchemaError(`Expected ${this.describeRef(param)} to be an input type but got ${param.kind}`); } return param; } if (typeof resolved === 'string' && this.typeConfigs.has(resolved)) { const ref = this.implementors.get(resolved); if (ref instanceof _base.BaseTypeRef) { if (ref.kind !== 'InputObject' && ref.kind !== 'Enum' && ref.kind !== 'Scalar') { throw new _errors.PothosSchemaError(`Expected ${this.describeRef(ref)} to be an input type but got ${ref.kind}`); } return ref; } } throw new _errors.PothosSchemaError(`${this.describeRef(param)} has not been implemented`); } getOutputTypeRef(param) { const resolved = this.resolveParamAssociations(param); if (param instanceof _base.BaseTypeRef) { if (param.kind === 'InputObject' || param.kind === 'InputList') { throw new _errors.PothosSchemaError(`Expected ${param.name} to be an output type but got ${param.kind}`); } return param; } if (typeof resolved === 'string' && this.typeConfigs.has(resolved)) { const ref = this.implementors.get(resolved); if (ref instanceof _base.BaseTypeRef) { if (ref.kind === 'InputObject' || ref.kind === 'InputList') { throw new _errors.PothosSchemaError(`Expected ${ref.name} to be an output type but got ${ref.kind}`); } return ref; } } throw new _errors.PothosSchemaError(`${this.describeRef(param)} has not been implemented`); } getFields(name, kind) { const typeConfig = this.getTypeConfig(name); if (!this.fields.has(name)) { this.fields.set(name, new Map()); } const fields = this.fields.get(name); if (kind && typeConfig.graphqlKind !== kind) { throw new _errors.PothosSchemaError(`Expected ${name} to be a ${kind} type, but found ${typeConfig.graphqlKind}`); } return fields; } prepareForBuild() { this.pending = false; for (const ref of this.refs){ ref.prepareForBuild(); } const { pendingActions } = this; this.pendingActions = []; for (const fn of pendingActions){ fn(); } if (this.pendingTypeConfigResolutions.size > 0) { throw new _errors.PothosSchemaError(`Missing implementations for some references (${[ ...this.pendingTypeConfigResolutions.keys() ].map((ref)=>this.describeRef(ref)).join(', ')}).`); } } onPrepare(cb) { if (this.pending) { this.pendingActions.push(cb); } else { cb(); } } resolveParamAssociations(param) { let current = this.paramAssociations.get(param); while(current && this.paramAssociations.has(current)){ current = this.paramAssociations.get(current); } return current !== null && current !== void 0 ? current : param; } describeRef(ref) { if (typeof ref === 'string') { return ref; } if (ref && ref.toString !== ({}).toString) { return String(ref); } if (typeof ref === 'function' && ref.name !== (()=>{}).name) { return `function ${ref.name}`; } return '<unnamed ref or enum>'; } constructor(builder){ _define_property(this, "typeConfigs", new Map()); _define_property(this, "fields", new Map()); _define_property(this, "refs", new Set()); _define_property(this, "implementors", new Map()); _define_property(this, "pendingActions", []); _define_property(this, "paramAssociations", new Map()); _define_property(this, "pendingTypeConfigResolutions", new Map()); _define_property(this, "pending", true); _define_property(this, "builder", void 0); this.builder = builder; } } //# sourceMappingURL=config-store.js.map