@pothos/plugin-errors
Version:
A Pothos plugin for adding typed errors into your schema
378 lines (377 loc) • 17.4 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: Object.getOwnPropertyDescriptor(all, name).get
});
}
_export(exports, {
get PothosErrorsPlugin () {
return PothosErrorsPlugin;
},
get capitalize () {
return capitalize;
},
get default () {
return _default;
},
get defaultGetListItemResultName () {
return defaultGetListItemResultName;
},
get defaultGetListItemUnionName () {
return defaultGetListItemUnionName;
},
get defaultGetResultName () {
return defaultGetResultName;
},
get defaultGetUnionName () {
return defaultGetUnionName;
},
get unwrapError () {
return unwrapError;
}
});
require("./global-types");
const _core = /*#__PURE__*/ _interop_require_wildcard(require("@pothos/core"));
_export_star(require("./types"), exports);
function _export_star(from, to) {
Object.keys(from).forEach(function(k) {
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
Object.defineProperty(to, k, {
enumerable: true,
get: function() {
return from[k];
}
});
}
});
return from;
}
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function") return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function(nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
})(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
if (!nodeInterop && obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {
__proto__: null
};
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
for(var key in obj){
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
if (desc && (desc.get || desc.set)) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
newObj.default = obj;
if (cache) {
cache.set(obj, newObj);
}
return newObj;
}
const pluginName = 'errors';
const _default = pluginName;
function capitalize(s) {
return `${s.slice(0, 1).toUpperCase()}${s.slice(1)}`;
}
const defaultGetResultName = ({ parentTypeName, fieldName })=>`${parentTypeName}${capitalize(fieldName)}Success`;
const defaultGetListItemResultName = ({ parentTypeName, fieldName })=>`${parentTypeName}${capitalize(fieldName)}ItemSuccess`;
const defaultGetUnionName = ({ parentTypeName, fieldName })=>`${parentTypeName}${capitalize(fieldName)}Result`;
const defaultGetListItemUnionName = ({ parentTypeName, fieldName })=>`${parentTypeName}${capitalize(fieldName)}ItemResult`;
const unwrapError = Symbol.for('Pothos.unwrapErrors');
function createErrorProxy(target, ref, state) {
return new Proxy(target, {
get (err, val, receiver) {
if (val === unwrapError) {
return ()=>{
state.wrapped = false;
};
}
if (val === _core.typeBrandKey) {
return ref;
}
return Reflect.get(err, val, receiver);
},
getPrototypeOf (err) {
const proto = Reflect.getPrototypeOf(err);
if (!state.wrapped || !proto) {
return proto;
}
return createErrorProxy(proto, ref, state);
}
});
}
const errorTypeMap = new WeakMap();
class PothosErrorsPlugin extends _core.BasePlugin {
wrapIsTypeOf(isTypeOf) {
if (isTypeOf) {
return (parent, context, info)=>{
if (typeof parent === 'object' && parent) {
var _parent_unwrapError;
(_parent_unwrapError = parent[unwrapError]) === null || _parent_unwrapError === void 0 ? void 0 : _parent_unwrapError.call(parent);
}
return isTypeOf(parent, context, info);
};
}
return isTypeOf;
}
onOutputFieldConfig(fieldConfig) {
const errorOptions = fieldConfig.pothosOptions.errors;
const itemErrorOptions = fieldConfig.pothosOptions.itemErrors;
const errorBuilderOptions = this.builder.options.errors;
if (!errorOptions && !itemErrorOptions) {
return fieldConfig;
}
const parentTypeName = this.buildCache.getTypeConfig(fieldConfig.parentType).name;
var _itemErrorOptions_types, _errorBuilderOptions_defaultTypes;
const itemErrorTypes = itemErrorOptions && (0, _core.sortClasses)([
...new Set([
...(_itemErrorOptions_types = itemErrorOptions === null || itemErrorOptions === void 0 ? void 0 : itemErrorOptions.types) !== null && _itemErrorOptions_types !== void 0 ? _itemErrorOptions_types : [],
...(_errorBuilderOptions_defaultTypes = errorBuilderOptions === null || errorBuilderOptions === void 0 ? void 0 : errorBuilderOptions.defaultTypes) !== null && _errorBuilderOptions_defaultTypes !== void 0 ? _errorBuilderOptions_defaultTypes : []
])
]);
var _errorOptions_types, _errorBuilderOptions_defaultTypes1;
const errorTypes = errorOptions && (0, _core.sortClasses)([
...new Set([
...(_errorOptions_types = errorOptions === null || errorOptions === void 0 ? void 0 : errorOptions.types) !== null && _errorOptions_types !== void 0 ? _errorOptions_types : [],
...(_errorBuilderOptions_defaultTypes1 = errorBuilderOptions === null || errorBuilderOptions === void 0 ? void 0 : errorBuilderOptions.defaultTypes) !== null && _errorBuilderOptions_defaultTypes1 !== void 0 ? _errorBuilderOptions_defaultTypes1 : []
])
]);
let resultType = fieldConfig.pothosOptions.type;
if (itemErrorOptions) {
if (!Array.isArray(fieldConfig.pothosOptions.type) || fieldConfig.type.kind !== 'List') {
throw new _core.PothosSchemaError(`Field ${parentTypeName}.${fieldConfig.name} must return a list when 'itemErrors' is set`);
}
const itemFieldType = fieldConfig.type.type;
const itemType = fieldConfig.pothosOptions.type[0];
resultType = [
this.createResultType(parentTypeName, fieldConfig.name, itemType, itemFieldType, itemErrorOptions, `Field ${parentTypeName}.${fieldConfig.name} list items must be an ObjectType when 'directResult' is set to true`, defaultGetListItemResultName, defaultGetListItemUnionName, errorBuilderOptions === null || errorBuilderOptions === void 0 ? void 0 : errorBuilderOptions.defaultItemResultOptions, errorBuilderOptions === null || errorBuilderOptions === void 0 ? void 0 : errorBuilderOptions.defaultItemUnionOptions)
];
if (!errorOptions) {
return {
...fieldConfig,
extensions: {
...fieldConfig.extensions,
pothosItemErrors: itemErrorTypes
},
type: {
...fieldConfig.type,
type: {
kind: 'Union',
ref: resultType[0],
nullable: fieldConfig.type.type.nullable
}
}
};
}
}
const unionType = this.createResultType(parentTypeName, fieldConfig.name, resultType, fieldConfig.type, errorOptions, `Field ${parentTypeName}.${fieldConfig.name} must return an ObjectType when 'directResult' is set to true`, defaultGetResultName, defaultGetUnionName, errorBuilderOptions === null || errorBuilderOptions === void 0 ? void 0 : errorBuilderOptions.defaultResultOptions, errorBuilderOptions === null || errorBuilderOptions === void 0 ? void 0 : errorBuilderOptions.defaultUnionOptions);
return {
...fieldConfig,
extensions: {
...fieldConfig.extensions,
pothosErrors: errorTypes,
pothosItemErrors: itemErrorTypes
},
type: {
kind: 'Union',
ref: unionType,
nullable: fieldConfig.type.nullable
}
};
}
wrapResolve(resolver, fieldConfig) {
var _fieldConfig_extensions, _fieldConfig_extensions1;
const pothosErrors = (_fieldConfig_extensions = fieldConfig.extensions) === null || _fieldConfig_extensions === void 0 ? void 0 : _fieldConfig_extensions.pothosErrors;
const pothosItemErrors = (_fieldConfig_extensions1 = fieldConfig.extensions) === null || _fieldConfig_extensions1 === void 0 ? void 0 : _fieldConfig_extensions1.pothosItemErrors;
if (!pothosErrors && !pothosItemErrors) {
return resolver;
}
return async (source, args, context, info)=>{
if (fieldConfig.kind === 'Subscription' && errorTypeMap.has(source)) {
return source;
}
try {
const result = await resolver(source, args, context, info);
if (pothosItemErrors && result && typeof result === 'object' && Symbol.iterator in result) {
return yieldErrors(result, pothosItemErrors);
}
if (pothosItemErrors && result && typeof result === 'object' && Symbol.asyncIterator in result) {
console.log(result, yieldAsyncErrors);
return yieldAsyncErrors(result, pothosItemErrors);
}
return result;
} catch (error) {
return wrapOrThrow(error, pothosErrors !== null && pothosErrors !== void 0 ? pothosErrors : []);
}
};
}
wrapSubscribe(subscribe, fieldConfig) {
var _fieldConfig_extensions;
const pothosErrors = (_fieldConfig_extensions = fieldConfig.extensions) === null || _fieldConfig_extensions === void 0 ? void 0 : _fieldConfig_extensions.pothosErrors;
if (!pothosErrors) {
return subscribe;
}
return (...args)=>{
async function* yieldSubscribeErrors() {
try {
const iter = await subscribe(...args);
if (!iter) {
return iter;
}
for await (const value of iter){
yield value;
}
} catch (error) {
yield wrapOrThrow(error, pothosErrors !== null && pothosErrors !== void 0 ? pothosErrors : []);
}
}
return yieldSubscribeErrors();
};
}
createResultType(parentTypeName, fieldName, type, fieldType, errorOptions, directResultError, defaultResultName, defaultUnionName, builderResultOptions = {}, builderUnionOptions = {}) {
const errorBuilderOptions = this.builder.options.errors;
const { name: getResultName = defaultResultName, ...defaultResultOptions } = builderResultOptions !== null && builderResultOptions !== void 0 ? builderResultOptions : {};
const { name: getUnionName = defaultUnionName, ...defaultUnionOptions } = builderUnionOptions !== null && builderUnionOptions !== void 0 ? builderUnionOptions : {};
const { types = [], result: { name: resultName = getResultName({
parentTypeName,
fieldName
}), fields: resultFieldOptions, ...resultObjectOptions } = {}, union: { name: unionName = getUnionName({
parentTypeName,
fieldName
}), ...unionOptions } = {}, dataField: { name: dataFieldName = 'data', ...dataField } = {} } = errorOptions;
var _errorBuilderOptions_defaultTypes;
const errorTypes = (0, _core.sortClasses)([
...new Set([
...types,
...(_errorBuilderOptions_defaultTypes = errorBuilderOptions === null || errorBuilderOptions === void 0 ? void 0 : errorBuilderOptions.defaultTypes) !== null && _errorBuilderOptions_defaultTypes !== void 0 ? _errorBuilderOptions_defaultTypes : []
])
]);
var _errorOptions_directResult, _ref;
const directResult = (_ref = (_errorOptions_directResult = errorOptions.directResult) !== null && _errorOptions_directResult !== void 0 ? _errorOptions_directResult : errorBuilderOptions === null || errorBuilderOptions === void 0 ? void 0 : errorBuilderOptions.directResult) !== null && _ref !== void 0 ? _ref : false;
const typeRef = (0, _core.unwrapOutputFieldType)(fieldType);
const typeName = this.builder.configStore.getTypeConfig(typeRef).name;
return this.runUnique(resultName, ()=>{
var _this_buildCache_getTypeConfig_extensions;
let resultType;
if (directResult && !Array.isArray(fieldType)) {
resultType = type;
const resultConfig = this.builder.configStore.getTypeConfig(resultType);
if (resultConfig.graphqlKind !== 'Object') {
throw new _core.PothosSchemaError(directResultError);
}
} else {
resultType = this.builder.objectRef(resultName);
resultType.implement({
...defaultResultOptions,
...resultObjectOptions,
fields: (t)=>({
...resultFieldOptions === null || resultFieldOptions === void 0 ? void 0 : resultFieldOptions(t),
[dataFieldName]: t.field({
...dataField,
type,
nullable: fieldType.kind === 'List' ? {
items: fieldType.type.nullable,
list: false
} : false,
resolve: (data)=>data
})
})
});
}
const getDataloader = (_this_buildCache_getTypeConfig_extensions = this.buildCache.getTypeConfig((0, _core.unwrapOutputFieldType)(fieldType)).extensions) === null || _this_buildCache_getTypeConfig_extensions === void 0 ? void 0 : _this_buildCache_getTypeConfig_extensions.getDataloader;
return this.builder.unionType(unionName, {
types: [
...errorTypes,
resultType
],
resolveType: (obj)=>{
var _errorTypeMap_get;
return (_errorTypeMap_get = errorTypeMap.get(obj)) !== null && _errorTypeMap_get !== void 0 ? _errorTypeMap_get : resultType;
},
...defaultUnionOptions,
...unionOptions,
extensions: {
...unionOptions.extensions,
getDataloader,
pothosIndirectInclude: {
getType: ()=>typeName,
path: directResult ? [] : [
{
type: resultName,
name: dataFieldName
}
]
}
}
});
});
}
}
_core.default.registerPlugin(pluginName, PothosErrorsPlugin, {
v3: (options)=>({
errorOptions: undefined,
errors: options === null || options === void 0 ? void 0 : options.errorOptions
})
});
function wrapOrThrow(error, pothosErrors) {
for (const errorType of pothosErrors){
if (error instanceof errorType) {
const result = createErrorProxy(error, errorType, {
wrapped: true
});
errorTypeMap.set(result, errorType);
return result;
}
}
throw error;
}
function* yieldErrors(result, pothosErrors) {
try {
for (const item of result){
if (item instanceof Error) {
yield wrapOrThrow(item, pothosErrors);
} else {
yield item;
}
}
} catch (error) {
yield wrapOrThrow(error, pothosErrors);
}
}
async function* yieldAsyncErrors(result, pothosErrors) {
try {
for await (const item of result){
if (item instanceof Error) {
yield wrapOrThrow(item, pothosErrors);
} else {
yield item;
}
}
} catch (error) {
yield wrapOrThrow(error, pothosErrors);
}
}
//# sourceMappingURL=index.js.map
;