@pothos/core
Version:
Pothos (formerly GiraphQL) is a plugin based schema builder for creating code-first GraphQL schemas in typescript
252 lines (251 loc) • 10.7 kB
JavaScript
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;
}
import { PothosSchemaError } from './errors.js';
import { BaseTypeRef } from './refs/base.js';
import { InputObjectRef } from './refs/input-object.js';
import { InterfaceRef } from './refs/interface.js';
import { MutationRef } from './refs/mutation.js';
import { ObjectRef } from './refs/object.js';
import { QueryRef } from './refs/query.js';
import { SubscriptionRef } from './refs/subscription.js';
export class ConfigStore {
addFields(param, fields) {
this.onTypeConfig(param, (_config, ref) => {
if (!(ref instanceof InterfaceRef || ref instanceof ObjectRef || ref instanceof QueryRef || ref instanceof MutationRef || ref instanceof SubscriptionRef)) {
throw new 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 InputObjectRef)) {
throw new 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 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 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 ObjectRef || ref instanceof InterfaceRef || ref instanceof 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 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 PothosSchemaError(`${this.describeRef(ref)} has not been implemented`);
}
const config = this.typeConfigs.get(resolved);
if (kind && config.graphqlKind !== kind) {
throw new 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 BaseTypeRef) {
if (param.kind !== "InputObject" && param.kind !== "Enum" && param.kind !== "Scalar") {
throw new 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 BaseTypeRef) {
if (ref.kind !== "InputObject" && ref.kind !== "Enum" && ref.kind !== "Scalar") {
throw new PothosSchemaError(`Expected ${this.describeRef(ref)} to be an input type but got ${ref.kind}`);
}
return ref;
}
}
throw new PothosSchemaError(`${this.describeRef(param)} has not been implemented`);
}
getOutputTypeRef(param) {
const resolved = this.resolveParamAssociations(param);
if (param instanceof BaseTypeRef) {
if (param.kind === "InputObject" || param.kind === "InputList") {
throw new 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 BaseTypeRef) {
if (ref.kind === "InputObject" || ref.kind === "InputList") {
throw new PothosSchemaError(`Expected ${ref.name} to be an output type but got ${ref.kind}`);
}
return ref;
}
}
throw new 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 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 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);
// biome-ignore lint/correctness/noUnusedPrivateClassMembers: backwards compatibility
_define_property(this, "builder", void 0);
this.builder = builder;
}
}
//# sourceMappingURL=config-store.js.map