@graphql-hive/core
Version:
104 lines (103 loc) • 5.25 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.errorPathToCoordinate = errorPathToCoordinate;
const graphql_1 = require("graphql");
const add_hive_typenames_js_1 = require("../add-hive-typenames.js");
function findFieldAndTypeInSelections(selections, responseName, fragments, currentTypeName = null) {
var _a, _b, _c, _d;
for (const selection of selections) {
switch (selection.kind) {
case 'Field': {
const nameOrAlias = (_b = (_a = selection.alias) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : selection.name.value;
if (nameOrAlias === responseName) {
return { fieldNode: selection, typeName: currentTypeName };
}
break;
}
case 'InlineFragment': {
const typeConditionName = (_d = (_c = selection.typeCondition) === null || _c === void 0 ? void 0 : _c.name.value) !== null && _d !== void 0 ? _d : currentTypeName;
const found = findFieldAndTypeInSelections(selection.selectionSet.selections, responseName, fragments, typeConditionName);
if (found)
return found;
break;
}
case 'FragmentSpread': {
const fragment = fragments[selection.name.value];
if (fragment) {
const typeConditionName = fragment.typeCondition.name.value;
const found = findFieldAndTypeInSelections(fragment.selectionSet.selections, responseName, fragments, typeConditionName);
if (found)
return found;
}
break;
}
}
}
return undefined;
}
function errorPathToCoordinate(schema, errorPath, document, data) {
var _a, _b, _c;
let operation;
const fragments = {};
for (const def of document.definitions) {
if (def.kind === 'OperationDefinition' && !operation) {
operation = def;
}
else if (def.kind === 'FragmentDefinition') {
fragments[def.name.value] = def;
}
}
const operationType = (_a = operation === null || operation === void 0 ? void 0 : operation.operation) !== null && _a !== void 0 ? _a : 'query';
const rootTypeMap = {
query: schema.getQueryType(),
mutation: schema.getMutationType(),
subscription: schema.getSubscriptionType(),
};
let currentType = rootTypeMap[operationType];
let coordinate = null;
let currentSelections = operation === null || operation === void 0 ? void 0 : operation.selectionSet.selections;
let currentData = data;
for (const segment of errorPath) {
if (typeof segment === 'number') {
currentData = currentData === null || currentData === void 0 ? void 0 : currentData[segment];
continue;
}
let nextType = (0, graphql_1.getNamedType)(currentType);
if (currentData && typeof currentData === 'object' && !Array.isArray(currentData)) {
const typeName = (_b = currentData[add_hive_typenames_js_1.HIVE_INTERNAL_TYPENAME]) !== null && _b !== void 0 ? _b : currentData.__typename;
if (typeof typeName === 'string') {
const runtimeType = schema.getType(typeName);
if (runtimeType && ((0, graphql_1.isObjectType)(runtimeType) || (0, graphql_1.isInterfaceType)(runtimeType))) {
nextType = runtimeType;
}
}
}
currentType = nextType;
let astMatch;
if (currentSelections) {
astMatch = findFieldAndTypeInSelections(currentSelections, segment, fragments);
}
if ((0, graphql_1.isAbstractType)(currentType) && (astMatch === null || astMatch === void 0 ? void 0 : astMatch.typeName)) {
const concreteType = schema.getType(astMatch.typeName);
if (concreteType &&
(0, graphql_1.isObjectType)(concreteType) &&
schema.getPossibleTypes(currentType).includes(concreteType)) {
currentType = concreteType;
}
}
if ((0, graphql_1.isObjectType)(currentType) || (0, graphql_1.isInterfaceType)(currentType)) {
// Map alias back to original schema field name using our cached astMatch
const fieldName = astMatch ? astMatch.fieldNode.name.value : segment;
const field = currentType.getFields()[fieldName];
if (!field) {
console.warn(`Hive Usage Client: Field '${fieldName}' (segment '${segment}') not found on type '${currentType.name}'. Error ignored.`);
return;
}
coordinate = `${currentType.name}.${field.name}`;
currentType = field.type;
currentSelections = (_c = astMatch === null || astMatch === void 0 ? void 0 : astMatch.fieldNode.selectionSet) === null || _c === void 0 ? void 0 : _c.selections;
currentData = currentData === null || currentData === void 0 ? void 0 : currentData[segment];
}
}
return coordinate !== null && coordinate !== void 0 ? coordinate : undefined;
}