@omnigraph/odata
Version:
127 lines (126 loc) • 5.88 kB
JavaScript
import { getNamedType, isListType } from 'graphql';
import urljoin from 'url-join';
import { createGraphQLError, getDirectiveExtensions } from '@graphql-tools/utils';
import { addIdentifierToUrl } from './addIdentifierToUrl.js';
import { getUrlString } from './getUrlString.js';
export function handleResponseText(responseText, urlString, info) {
let responseJson;
try {
responseJson = JSON.parse(responseText);
}
catch (error) {
return createGraphQLError(`Failed to parse response JSON: ${error.message}`, {
extensions: {
request: {
url: urlString,
},
response: {
body: responseText,
},
originalError: error,
},
});
}
if (responseJson.error) {
return createGraphQLError(responseJson.error.message || responseJson.error, {
extensions: {
request: {
url: urlString,
},
response: {
body: responseJson,
},
},
});
}
const urlStringWithoutSearchParams = urlString.split('?')[0];
if (isListType(info.returnType)) {
const actualReturnType = getNamedType(info.returnType);
const entityTypeDirectives = getDirectiveExtensions(actualReturnType);
if ('Message' in responseJson && !('value' in responseJson)) {
return createGraphQLError(responseJson.Message, {
extensions: {
request: {
url: urlString,
},
response: {
body: responseJson,
},
},
});
}
const returnList = responseJson.value;
return returnList.map(element => {
if (!entityTypeDirectives?.entityInfo?.[0]) {
return element;
}
const urlOfElement = new URL(urlStringWithoutSearchParams);
addIdentifierToUrl(urlOfElement, entityTypeDirectives.entityInfo[0].identifierFieldName, entityTypeDirectives.entityInfo[0].identifierFieldTypeRef, element);
const identifierUrl = element['@odata.id'] || getUrlString(urlOfElement);
const fieldMap = actualReturnType.getFields();
for (const fieldName in element) {
if (entityTypeDirectives.entityInfo[0].navigationFields.includes(fieldName)) {
const field = element[fieldName];
let fieldType = fieldMap[fieldName].type;
if ('ofType' in fieldType) {
fieldType = fieldType.ofType;
}
const fieldTypeDirectives = getDirectiveExtensions(fieldType);
const fieldEntityInfo = fieldTypeDirectives?.entityInfo?.[0];
if (field instanceof Array) {
for (const fieldElement of field) {
const urlOfField = new URL(urljoin(identifierUrl, fieldName));
addIdentifierToUrl(urlOfField, fieldEntityInfo.identifierFieldName, fieldEntityInfo.identifierFieldTypeRef, fieldElement);
fieldElement['@odata.id'] = fieldElement['@odata.id'] || getUrlString(urlOfField);
}
}
else {
const urlOfField = new URL(urljoin(identifierUrl, fieldName));
addIdentifierToUrl(urlOfField, fieldEntityInfo.identifierFieldName, fieldEntityInfo.identifierFieldTypeRef, field);
field['@odata.id'] = field['@odata.id'] || getUrlString(urlOfField);
}
}
}
return {
'@odata.id': identifierUrl,
...element,
};
});
}
else {
const actualReturnType = info.returnType;
const entityTypeDirectives = getDirectiveExtensions(actualReturnType);
if (!entityTypeDirectives?.entityInfo?.[0]) {
return responseJson;
}
const identifierUrl = responseJson['@odata.id'] || urlStringWithoutSearchParams;
const fieldMap = actualReturnType.getFields();
for (const fieldName in responseJson) {
if (entityTypeDirectives?.entityInfo?.[0]?.navigationFields.includes(fieldName)) {
const field = responseJson[fieldName];
let fieldType = fieldMap[fieldName].type;
if ('ofType' in fieldType) {
fieldType = fieldType.ofType;
}
const fieldTypeDirectives = getDirectiveExtensions(fieldType);
const fieldEntityInfo = fieldTypeDirectives?.entityInfo?.[0];
if (field instanceof Array) {
for (const fieldElement of field) {
const urlOfField = new URL(urljoin(identifierUrl, fieldName));
addIdentifierToUrl(urlOfField, fieldEntityInfo.identifierFieldName, fieldEntityInfo.identifierFieldTypeRef, fieldElement);
fieldElement['@odata.id'] = fieldElement['@odata.id'] || getUrlString(urlOfField);
}
}
else {
const urlOfField = new URL(urljoin(identifierUrl, fieldName));
addIdentifierToUrl(urlOfField, fieldEntityInfo.identifierFieldName, fieldEntityInfo.identifierFieldTypeRef, field);
field['@odata.id'] = field['@odata.id'] || getUrlString(urlOfField);
}
}
}
return {
'@odata.id': responseJson['@odata.id'] || urlStringWithoutSearchParams,
...responseJson,
};
}
}