@pothos/plugin-add-graphql
Version:
A Pothos plugin for adding existing GraphQL types to a Pothos schema
243 lines (242 loc) • 11.7 kB
JavaScript
import './global-types.js';
import SchemaBuilder, { InputListRef, ListRef } from '@pothos/core';
import { defaultFieldResolver, isListType, isNonNullType } from 'graphql';
import { addReferencedType } from './utils.js';
const proto = SchemaBuilder.prototype;
function resolveNullableOutputRef(builder, type) {
if (isNonNullType(type)) {
throw new Error("Expected a nullable type");
}
if (isListType(type)) {
const nullable = !isNonNullType(type.ofType);
const listType = nullable ? type.ofType : type.ofType.ofType;
return new ListRef(resolveNullableOutputRef(builder, listType), nullable);
}
addReferencedType(builder, type);
return type.name;
}
function resolveNullableInputRef(builder, type) {
if (isNonNullType(type)) {
throw new Error("Expected a nullable type");
}
if (isListType(type)) {
const required = isNonNullType(type.ofType);
const listType = required ? type.ofType.ofType : type.ofType;
return new InputListRef(resolveNullableInputRef(builder, listType), required);
}
addReferencedType(builder, type);
return type.name;
}
function resolveOutputType(builder, type) {
const isNullable = !isNonNullType(type);
const nonNullable = isNonNullType(type) ? type.ofType : type;
const typeRef = resolveNullableOutputRef(builder, nonNullable);
return {
type: typeRef,
nullable: isNullable
};
}
function resolveInputType(builder, type) {
const isNullable = !isNonNullType(type);
const nonNullable = isNonNullType(type) ? type.ofType : type;
const typeRef = resolveNullableInputRef(builder, nonNullable);
return {
type: typeRef,
required: !isNullable
};
}
proto.addGraphQLObject = function addGraphQLObject(type, { fields, extensions, ...options } = {}) {
var _type_description;
const typeOptions = {
...options,
description: (_type_description = type.description) !== null && _type_description !== void 0 ? _type_description : undefined,
isTypeOf: type.isTypeOf,
extensions: {
...type.extensions,
...extensions
},
interfaces: () => type.getInterfaces().map((i) => resolveNullableOutputRef(this, i)),
fields: (t) => {
const existingFields = type.getFields();
var _fields;
const newFields = (_fields = fields === null || fields === void 0 ? void 0 : fields(t)) !== null && _fields !== void 0 ? _fields : {};
const combinedFields = {
...newFields
};
for (const [fieldName, field] of Object.entries(existingFields)) {
if (newFields[fieldName] !== undefined) {
if (newFields[fieldName] === null) {
delete combinedFields[fieldName];
}
continue;
}
const args = {};
for (const { name, ...arg } of field.args) {
const input = resolveInputType(this, arg.type);
var _arg_description, _arg_deprecationReason;
args[name] = t.arg({
...input,
description: (_arg_description = arg.description) !== null && _arg_description !== void 0 ? _arg_description : undefined,
deprecationReason: (_arg_deprecationReason = arg.deprecationReason) !== null && _arg_deprecationReason !== void 0 ? _arg_deprecationReason : undefined,
defaultValue: arg.defaultValue,
extensions: arg.extensions
});
}
var _field_description, _field_deprecationReason, _field_resolve;
combinedFields[fieldName] = t.field({
...resolveOutputType(this, field.type),
args,
description: (_field_description = field.description) !== null && _field_description !== void 0 ? _field_description : undefined,
deprecationReason: (_field_deprecationReason = field.deprecationReason) !== null && _field_deprecationReason !== void 0 ? _field_deprecationReason : undefined,
extensions: field.extensions,
resolve: (_field_resolve = field.resolve) !== null && _field_resolve !== void 0 ? _field_resolve : defaultFieldResolver,
...field.subscribe ? {
subscribe: field.subscribe
} : {}
});
}
return combinedFields;
}
};
switch (type.name) {
case "Query":
this.queryType(typeOptions);
return "Query";
case "Mutation":
this.mutationType(typeOptions);
return "Mutation";
case "Subscription":
this.subscriptionType(typeOptions);
return "Subscription";
default:
var _options_name;
return this.objectRef((_options_name = options === null || options === void 0 ? void 0 : options.name) !== null && _options_name !== void 0 ? _options_name : type.name).implement(typeOptions);
}
};
proto.addGraphQLInterface = function addGraphQLInterface(type, { fields, extensions, ...options } = {}) {
var _options_name;
const ref = this.interfaceRef((_options_name = options === null || options === void 0 ? void 0 : options.name) !== null && _options_name !== void 0 ? _options_name : type.name);
var _type_description;
ref.implement({
...options,
description: (_type_description = type.description) !== null && _type_description !== void 0 ? _type_description : undefined,
resolveType: type.resolveType,
extensions: {
...type.extensions,
...extensions
},
interfaces: () => type.getInterfaces().map((i) => resolveNullableOutputRef(this, i)),
fields: (t) => {
const existingFields = type.getFields();
var _fields;
const newFields = (_fields = fields === null || fields === void 0 ? void 0 : fields(t)) !== null && _fields !== void 0 ? _fields : {};
const combinedFields = {
...newFields
};
for (const [fieldName, field] of Object.entries(existingFields)) {
if (newFields[fieldName] !== undefined) {
if (newFields[fieldName] === null) {
delete combinedFields[fieldName];
}
continue;
}
const args = {};
for (const { name, ...arg } of field.args) {
var _arg_description, _arg_deprecationReason;
args[name] = t.arg({
...resolveInputType(this, arg.type),
description: (_arg_description = arg.description) !== null && _arg_description !== void 0 ? _arg_description : undefined,
deprecationReason: (_arg_deprecationReason = arg.deprecationReason) !== null && _arg_deprecationReason !== void 0 ? _arg_deprecationReason : undefined,
defaultValue: arg.defaultValue,
extensions: arg.extensions
});
}
var _field_description, _field_deprecationReason;
combinedFields[fieldName] = t.field({
...resolveOutputType(this, field.type),
args,
description: (_field_description = field.description) !== null && _field_description !== void 0 ? _field_description : undefined,
deprecationReason: (_field_deprecationReason = field.deprecationReason) !== null && _field_deprecationReason !== void 0 ? _field_deprecationReason : undefined,
resolve: field.resolve,
extensions: field.extensions
});
}
return combinedFields;
}
});
return ref;
};
proto.addGraphQLUnion = function addGraphQLUnion(type, { types, extensions, ...options } = {}) {
var _options_name, _type_description;
return this.unionType((_options_name = options === null || options === void 0 ? void 0 : options.name) !== null && _options_name !== void 0 ? _options_name : type.name, {
...options,
description: (_type_description = type.description) !== null && _type_description !== void 0 ? _type_description : undefined,
resolveType: type.resolveType,
extensions: {
...type.extensions,
...extensions
},
types: types !== null && types !== void 0 ? types : type.getTypes().map((t) => resolveNullableOutputRef(this, t))
});
};
proto.addGraphQLEnum = function addGraphQLEnum(type, { values, extensions, ...options } = {}) {
const newValues = values !== null && values !== void 0 ? values : type.getValues().reduce((acc, value) => {
var _value_description, _value_deprecationReason;
acc[value.name] = {
value: value.value,
description: (_value_description = value.description) !== null && _value_description !== void 0 ? _value_description : undefined,
deprecationReason: (_value_deprecationReason = value.deprecationReason) !== null && _value_deprecationReason !== void 0 ? _value_deprecationReason : undefined,
extensions: value.extensions
};
return acc;
}, {});
var _options_name, _type_description;
const ref = this.enumType((_options_name = options === null || options === void 0 ? void 0 : options.name) !== null && _options_name !== void 0 ? _options_name : type.name, {
...options,
description: (_type_description = type.description) !== null && _type_description !== void 0 ? _type_description : undefined,
extensions: {
...type.extensions,
...extensions
},
values: newValues
});
return ref;
};
proto.addGraphQLInput = function addGraphQLInput(type, { name = type.name, fields, extensions, ...options } = {}) {
const ref = this.inputRef(name);
var _type_description;
return ref.implement({
...options,
description: (_type_description = type.description) !== null && _type_description !== void 0 ? _type_description : undefined,
extensions: {
...type.extensions,
...extensions
},
isOneOf: type.isOneOf,
fields: (t) => {
const existingFields = type.getFields();
var _fields;
const newFields = (_fields = fields === null || fields === void 0 ? void 0 : fields(t)) !== null && _fields !== void 0 ? _fields : {};
const combinedFields = {
...newFields
};
for (const [fieldName, field] of Object.entries(existingFields)) {
if (newFields[fieldName] !== undefined) {
if (newFields[fieldName] === null) {
delete combinedFields[fieldName];
}
continue;
}
var _field_description;
combinedFields[fieldName] = t.field({
...resolveInputType(this, field.type),
description: (_field_description = field.description) !== null && _field_description !== void 0 ? _field_description : undefined,
defaultValue: field.defaultValue,
extensions: field.extensions
});
}
return combinedFields;
}
});
};
//# sourceMappingURL=schema-builder.js.map