UNPKG

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
"use strict"; 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; }