graphql-toe
Version:
GraphQL Throw-On-Error - incorporate error handling back into the reading of your data, so you can handle errors in the most natural way.
87 lines (86 loc) • 2.97 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.toe = toe;
function toe(result) {
const { data, errors } = result;
if (!data) {
if (!errors) {
throw new Error("Invalid call to graphql-toe; neither data nor errors were present");
}
else {
throw typeof AggregateError === "undefined"
? errors[0]
: new AggregateError(errors, errors[0].message);
}
}
if (!errors || errors.length === 0) {
return data;
}
return toeObj(data, 0, errors);
}
function toeObj(data, depth, errors) {
// TODO: would it be faster to rule out duplicates via a set?
const keys = errors.map((e) => e.path[depth]);
const obj = Object.create(null);
for (const key of Object.keys(data)) {
const value = data[key];
if (keys.includes(key)) {
if (value == null) {
const error = errors.find((e) => e.path[depth] === key);
// This is where the error is!
// obj[key] = value;
Object.defineProperty(obj, key, {
enumerable: true,
get() {
throw error;
},
});
}
else {
// Guaranteed to have at least one entry
const filteredErrors = errors.filter((e) => e.path[depth] === key);
// Recurse
obj[key] = Array.isArray(value)
? toeArr(value, depth + 1, filteredErrors)
: toeObj(value, depth + 1, filteredErrors);
}
}
else {
obj[key] = value;
}
}
return obj;
}
function toeArr(data, depth, errors) {
// TODO: would it be faster to rule out duplicates via a set?
const keys = errors.map((e) => e.path[depth]);
const arr = new Array(data.length);
for (let index = 0, l = data.length; index < l; index++) {
const value = data[index];
if (keys.includes(index)) {
if (value == null) {
const error = errors.find((e) => e.path[depth] === index);
// This is where the error is!
// arr[index] = value;
Object.defineProperty(arr, index, {
enumerable: true,
get() {
throw error;
},
});
}
else {
// Guaranteed to have at least one entry
const filteredErrors = errors.filter((e) => e.path[depth] === index);
// Recurse
arr[index] = Array.isArray(value)
? toeArr(value, depth + 1, filteredErrors)
: toeObj(value, depth + 1, filteredErrors);
}
}
else {
arr[index] = value;
}
}
return arr;
}