@giraphql/plugin-errors
Version:
A GiraphQL plugin for adding typed errors into your schema
118 lines (117 loc) • 5.57 kB
JavaScript
import './global-types.js';
import SchemaBuilder, { BasePlugin, sortClasses, } from '@giraphql/core';
export * from './types.js';
const pluginName = "errors";
export default pluginName;
export function capitalize(s) {
return `${s.slice(0, 1).toUpperCase()}${s.slice(1)}`;
}
function createErrorProxy(target) {
return new Proxy(target, {
getPrototypeOf(err) {
const proto = Object.getPrototypeOf(err);
if (!proto) {
return proto;
}
return createErrorProxy(proto);
},
});
}
const errorTypeMap = new WeakMap();
export class GiraphQLErrorsPlugin extends BasePlugin {
onOutputFieldConfig(fieldConfig) {
var _a, _b, _c;
const errorOptions = fieldConfig.giraphqlOptions.errors;
const errorBuilderOptions = this.builder.options.errorOptions;
if (!errorOptions) {
return fieldConfig;
}
const parentTypeName = this.buildCache.getTypeConfig(fieldConfig.parentType).name;
const { types = [], result: { name: resultName = `${parentTypeName}${capitalize(fieldConfig.name)}Success`, fields: resultFieldOptions, ...resultObjectOptions } = {}, union: { name: unionName = `${parentTypeName}${capitalize(fieldConfig.name)}Result`, ...unionOptions } = {}, dataField: { name: dataFieldName = "data", ...dataField } = {}, } = errorOptions;
const errorTypes = sortClasses([
...new Set([...types, ...((_a = errorBuilderOptions === null || errorBuilderOptions === void 0 ? void 0 : errorBuilderOptions.defaultTypes) !== null && _a !== void 0 ? _a : [])]),
]);
const directResult = (_c = (_b = errorOptions.directResult) !== null && _b !== void 0 ? _b : errorBuilderOptions === null || errorBuilderOptions === void 0 ? void 0 : errorBuilderOptions.directResult) !== null && _c !== void 0 ? _c : false;
const typeRef = fieldConfig.type.kind === "List" ? fieldConfig.type.type.ref : fieldConfig.type.ref;
const typeName = this.builder.configStore.getTypeConfig(typeRef).name;
const unionType = this.runUnique(resultName, () => {
var _a;
let resultType;
if (directResult && !Array.isArray(fieldConfig.giraphqlOptions.type)) {
resultType = fieldConfig.giraphqlOptions.type;
const resultConfig = this.builder.configStore.getTypeConfig(resultType);
if (resultConfig.graphqlKind !== "Object") {
throw new TypeError(`Field ${parentTypeName}.${fieldConfig.name} must return an ObjectType when 'directResult' is set to true`);
}
}
else {
resultType = this.builder.objectRef(resultName);
resultType.implement({
...resultObjectOptions,
fields: (t) => ({
...resultFieldOptions === null || resultFieldOptions === void 0 ? void 0 : resultFieldOptions(t),
[dataFieldName]: t.field({
...dataField,
type: fieldConfig.giraphqlOptions.type,
nullable: fieldConfig.type.kind === "List"
? { items: fieldConfig.type.type.nullable, list: false }
: false,
resolve: (data) => data,
}),
}),
});
}
const type = fieldConfig.type.kind === "List" ? fieldConfig.type.type : fieldConfig.type;
const getDataloader = (_a = this.buildCache.getTypeConfig(type.ref).extensions) === null || _a === void 0 ? void 0 : _a.getDataloader;
return this.builder.unionType(unionName, {
types: [...errorTypes, resultType],
resolveType: (obj) => { var _a; return (_a = errorTypeMap.get(obj)) !== null && _a !== void 0 ? _a : resultType; },
...unionOptions,
extensions: {
...unionOptions.extensions,
getDataloader,
giraphQLPrismaIndirectInclude: {
getType: () => typeName,
path: [{ type: resultName, name: dataFieldName }],
},
},
});
});
return {
...fieldConfig,
extensions: {
...fieldConfig.extensions,
giraphqlErrors: errorTypes,
},
type: {
kind: "Union",
ref: unionType,
nullable: fieldConfig.type.nullable,
},
};
}
wrapResolve(resolver, fieldConfig) {
var _a;
const giraphqlErrors = (_a = fieldConfig.extensions) === null || _a === void 0 ? void 0 : _a.giraphqlErrors;
if (!giraphqlErrors) {
return resolver;
}
return async (...args) => {
try {
return (await resolver(...args));
}
catch (error) {
for (const errorType of giraphqlErrors) {
if (error instanceof errorType) {
const result = createErrorProxy(error);
errorTypeMap.set(result, errorType);
return result;
}
}
throw error;
}
};
}
}
SchemaBuilder.registerPlugin(pluginName, GiraphQLErrorsPlugin);
//# sourceMappingURL=index.js.map