UNPKG

@pothos/plugin-errors

Version:

A Pothos plugin for adding typed errors into your schema

378 lines (377 loc) 17.4 kB
"use strict"; 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