@pothos/core
Version:
Pothos (formerly GiraphQL) is a plugin based schema builder for creating code-first GraphQL schemas in typescript
387 lines (386 loc) • 15.9 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 { GraphQLBoolean, GraphQLFloat, GraphQLID, GraphQLInt, GraphQLSchema, GraphQLString, lexicographicSortSchema } from 'graphql';
import { BuildCache } from './build-cache.js';
import { ConfigStore } from './config-store.js';
import { PothosError } from './errors.js';
import { InputFieldBuilder } from './fieldUtils/input.js';
import { InterfaceFieldBuilder } from './fieldUtils/interface.js';
import { MutationFieldBuilder } from './fieldUtils/mutation.js';
import { ObjectFieldBuilder } from './fieldUtils/object.js';
import { QueryFieldBuilder } from './fieldUtils/query.js';
import { SubscriptionFieldBuilder } from './fieldUtils/subscription.js';
import { BaseTypeRef } from './refs/base.js';
import { EnumRef } from './refs/enum.js';
import { ImplementableInputObjectRef, InputObjectRef } from './refs/input-object.js';
import { ImplementableInterfaceRef, InterfaceRef } from './refs/interface.js';
import { MutationRef } from './refs/mutation.js';
import { ImplementableObjectRef, ObjectRef } from './refs/object.js';
import { QueryRef } from './refs/query.js';
import { ScalarRef } from './refs/scalar.js';
import { SubscriptionRef } from './refs/subscription.js';
import { UnionRef } from './refs/union.js';
import { normalizeEnumValues, valuesFromEnum, verifyInterfaces, verifyRef } from './utils/index.js';
export class SchemaBuilder {
static registerPlugin(name, plugin, normalizeOptions) {
if (!SchemaBuilder.allowPluginReRegistration && SchemaBuilder.plugins[name]) {
throw new PothosError(`Received multiple implementations for plugin ${name}`);
}
SchemaBuilder.plugins[name] = plugin;
if (normalizeOptions) {
SchemaBuilder.optionNormalizers.set(name, normalizeOptions);
}
}
objectType(param, options, fields) {
verifyRef(param);
verifyInterfaces(options.interfaces);
var _options_name;
const name = typeof param === "string" ? param : (_options_name = options.name) !== null && _options_name !== void 0 ? _options_name : param.name;
const ref = param instanceof BaseTypeRef ? param : new ObjectRef(name);
ref.updateConfig({
kind: "Object",
graphqlKind: "Object",
name,
interfaces: [],
description: options.description,
extensions: options.extensions,
isTypeOf: options.isTypeOf,
pothosOptions: options
});
if (options.interfaces) {
ref.addInterfaces(options.interfaces);
}
if (ref !== param && typeof param !== "string") {
this.configStore.associateParamWithRef(param, ref);
}
if (fields) {
ref.addFields(() => fields(new ObjectFieldBuilder(this)));
}
if (options.fields) {
ref.addFields(() => {
const t = new ObjectFieldBuilder(this);
return options.fields(t);
});
}
this.configStore.addTypeRef(ref);
return ref;
}
objectFields(param, fields) {
verifyRef(param);
this.configStore.addFields(param, () => fields(new ObjectFieldBuilder(this)));
}
objectField(param, fieldName, field) {
verifyRef(param);
this.configStore.addFields(param, () => ({
[fieldName]: field(new ObjectFieldBuilder(this))
}));
}
queryType(...args) {
const [options = {}, fields] = args;
var _options_name;
this.queryRef.updateConfig({
kind: "Query",
graphqlKind: "Object",
name: (_options_name = options.name) !== null && _options_name !== void 0 ? _options_name : "Query",
description: options.description,
pothosOptions: options,
extensions: options.extensions
});
if (options.name) {
this.queryRef.name = options.name;
}
this.configStore.addTypeRef(this.queryRef);
if (fields) {
this.queryRef.addFields(() => fields(new QueryFieldBuilder(this)));
}
if (options.fields) {
this.queryRef.addFields(() => options.fields(new QueryFieldBuilder(this)));
}
return this.queryRef;
}
queryFields(fields) {
this.configStore.addFields(this.queryRef, () => fields(new QueryFieldBuilder(this)));
}
queryField(name, field) {
this.configStore.addFields(this.queryRef, () => ({
[name]: field(new QueryFieldBuilder(this))
}));
}
mutationType(...args) {
const [options = {}, fields] = args;
var _options_name;
this.mutationRef.updateConfig({
kind: "Mutation",
graphqlKind: "Object",
name: (_options_name = options.name) !== null && _options_name !== void 0 ? _options_name : "Mutation",
description: options.description,
pothosOptions: options,
extensions: options.extensions
});
this.configStore.addTypeRef(this.mutationRef);
if (options.name) {
this.mutationRef.name = options.name;
}
if (fields) {
this.configStore.addFields(this.mutationRef, () => fields(new MutationFieldBuilder(this)));
}
if (options.fields) {
this.configStore.addFields(this.mutationRef, () => options.fields(new MutationFieldBuilder(this)));
}
return this.mutationRef;
}
mutationFields(fields) {
this.configStore.addFields(this.mutationRef, () => fields(new MutationFieldBuilder(this)));
}
mutationField(name, field) {
this.configStore.addFields(this.mutationRef, () => ({
[name]: field(new MutationFieldBuilder(this))
}));
}
subscriptionType(...args) {
const [options = {}, fields] = args;
var _options_name;
this.subscriptionRef.updateConfig({
kind: "Subscription",
graphqlKind: "Object",
name: (_options_name = options.name) !== null && _options_name !== void 0 ? _options_name : "Subscription",
description: options.description,
pothosOptions: options,
extensions: options.extensions
});
this.configStore.addTypeRef(this.subscriptionRef);
if (options.name) {
this.subscriptionRef.name = options.name;
}
if (fields) {
this.configStore.addFields(this.subscriptionRef, () => fields(new SubscriptionFieldBuilder(this)));
}
if (options.fields) {
this.configStore.addFields(this.subscriptionRef, () => options.fields(new SubscriptionFieldBuilder(this)));
}
return this.subscriptionRef;
}
subscriptionFields(fields) {
this.configStore.addFields(this.subscriptionRef, () => fields(new SubscriptionFieldBuilder(this)));
}
subscriptionField(name, field) {
this.configStore.addFields(this.subscriptionRef, () => ({
[name]: field(new SubscriptionFieldBuilder(this))
}));
}
args(fields) {
return fields(new InputFieldBuilder(this, "Arg"));
}
interfaceType(param, options, fields) {
verifyRef(param);
verifyInterfaces(options.interfaces);
var _options_name;
const name = typeof param === "string" ? param : (_options_name = options.name) !== null && _options_name !== void 0 ? _options_name : param.name;
const ref = param instanceof BaseTypeRef ? param : new InterfaceRef(name);
const typename = ref.name;
ref.updateConfig({
kind: "Interface",
graphqlKind: "Interface",
name: typename,
interfaces: [],
description: options.description,
pothosOptions: options,
extensions: options.extensions,
resolveType: options.resolveType
});
this.configStore.addTypeRef(ref);
if (options.interfaces) {
ref.addInterfaces(options.interfaces);
}
if (ref !== param && typeof param !== "string") {
this.configStore.associateParamWithRef(param, ref);
}
if (fields) {
this.configStore.addFields(ref, () => fields(new InterfaceFieldBuilder(this)));
}
if (options.fields) {
this.configStore.addFields(ref, () => options.fields(new InterfaceFieldBuilder(this)));
}
return ref;
}
interfaceFields(ref, fields) {
verifyRef(ref);
this.configStore.addFields(ref, () => fields(new InterfaceFieldBuilder(this)));
}
interfaceField(ref, fieldName, field) {
verifyRef(ref);
this.configStore.addFields(ref, () => ({
[fieldName]: field(new InterfaceFieldBuilder(this))
}));
}
unionType(name, options) {
const ref = new UnionRef(name, {
kind: "Union",
graphqlKind: "Union",
name,
types: [],
description: options.description,
resolveType: options.resolveType,
pothosOptions: options,
extensions: options.extensions
});
if (Array.isArray(options.types)) {
for (const type of options.types) {
verifyRef(type);
}
}
this.configStore.addTypeRef(ref);
ref.addTypes(options.types);
return ref;
}
enumType(param, options) {
verifyRef(param);
const name = typeof param === "string" ? param : options.name;
const values = typeof param === "object" ? valuesFromEnum(param, options === null || options === void 0 ? void 0 : options.values) : normalizeEnumValues(options.values);
const ref = new EnumRef(name, {
kind: "Enum",
graphqlKind: "Enum",
name,
values,
description: options.description,
pothosOptions: options,
extensions: options.extensions
});
this.configStore.addTypeRef(ref);
if (typeof param !== "string") {
this.configStore.associateParamWithRef(param, ref);
}
return ref;
}
scalarType(name, options) {
const ref = new ScalarRef(name, {
kind: "Scalar",
graphqlKind: "Scalar",
name,
description: options.description,
parseLiteral: options.parseLiteral,
parseValue: options.parseValue,
serialize: options.serialize,
pothosOptions: options,
extensions: options.extensions
});
this.configStore.addTypeRef(ref);
return ref;
}
addScalarType(name, scalar, ...args) {
const [options = {}] = args;
const config = scalar.toConfig();
return this.scalarType(name, {
...config,
...options,
extensions: {
...config.extensions,
...options.extensions
}
});
}
inputType(param, options) {
verifyRef(param);
const name = typeof param === "string" ? param : param.name;
const ref = typeof param === "string" ? new InputObjectRef(name) : param;
ref.updateConfig({
kind: "InputObject",
graphqlKind: "InputObject",
name,
isOneOf: options.isOneOf,
description: options.description,
pothosOptions: options,
extensions: options.extensions
});
this.configStore.addTypeRef(ref);
if (param !== ref && typeof param !== "string") {
this.configStore.associateParamWithRef(param, ref);
}
this.configStore.addInputFields(ref, () => options.fields(new InputFieldBuilder(this, "InputObject")));
return ref;
}
inputRef(name) {
return new ImplementableInputObjectRef(this, name);
}
objectRef(name) {
return new ImplementableObjectRef(this, name);
}
interfaceRef(name) {
return new ImplementableInterfaceRef(this, name);
}
toSchema(...args) {
const [options = {}] = args;
const { directives, extensions } = options;
const scalars = [
GraphQLID,
GraphQLInt,
GraphQLFloat,
GraphQLString,
GraphQLBoolean
];
for (const scalar of scalars) {
if (!this.configStore.hasImplementation(scalar.name)) {
this.addScalarType(scalar.name, scalar);
}
}
const buildCache = new BuildCache(this, options);
buildCache.plugin.beforeBuild();
buildCache.buildAll();
const builtTypes = [
...buildCache.types.values()
];
const queryName = this.configStore.hasConfig(this.queryRef) ? this.configStore.getTypeConfig(this.queryRef).name : "Query";
const mutationName = this.configStore.hasConfig(this.mutationRef) ? this.configStore.getTypeConfig(this.mutationRef).name : "Mutation";
const subscriptionName = this.configStore.hasConfig(this.subscriptionRef) ? this.configStore.getTypeConfig(this.subscriptionRef).name : "Subscription";
const schema = new GraphQLSchema({
query: buildCache.types.get(queryName),
mutation: buildCache.types.get(mutationName),
subscription: buildCache.types.get(subscriptionName),
extensions: extensions !== null && extensions !== void 0 ? extensions : {},
directives: directives,
types: builtTypes
});
const processedSchema = buildCache.plugin.afterBuild(schema);
return options.sortSchema === false ? processedSchema : lexicographicSortSchema(processedSchema);
}
constructor(options) {
_define_property(this, "$inferSchemaTypes", void 0);
_define_property(this, "queryRef", new QueryRef("Query"));
_define_property(this, "mutationRef", new MutationRef("Mutation"));
_define_property(this, "subscriptionRef", new SubscriptionRef("Subscription"));
_define_property(this, "configStore", void 0);
_define_property(this, "options", void 0);
_define_property(this, "defaultFieldNullability", void 0);
_define_property(this, "defaultInputFieldRequiredness", void 0);
this.options = [
...SchemaBuilder.optionNormalizers.values()
].reduce((opts, normalize) => {
if (options.defaults && typeof normalize[options.defaults] === "function") {
// biome-ignore lint/performance/noAccumulatingSpread: this is fine
return Object.assign(opts, normalize[options.defaults](opts));
}
return opts;
}, options);
this.configStore = new ConfigStore(this);
var _options_defaultFieldNullability;
this.defaultFieldNullability = (_options_defaultFieldNullability = options.defaultFieldNullability) !== null && _options_defaultFieldNullability !== void 0 ? _options_defaultFieldNullability : options.defaults !== "v3";
var _options_defaultInputFieldRequiredness;
this.defaultInputFieldRequiredness = (_options_defaultInputFieldRequiredness = options.defaultInputFieldRequiredness) !== null && _options_defaultInputFieldRequiredness !== void 0 ? _options_defaultInputFieldRequiredness : false;
}
}
_define_property(SchemaBuilder, "plugins", {});
_define_property(SchemaBuilder, "optionNormalizers", new Map());
_define_property(SchemaBuilder, "allowPluginReRegistration", false);
//# sourceMappingURL=builder.js.map