@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
JavaScript
"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