postgraphile-federation-plugin
Version:
Apollo Federation support for Graphile Engine
82 lines • 4.27 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultResolveReference = void 0;
const tslib_1 = require("tslib");
/**
* The default federation resolve reference.
* @param representation The federation representation.
* @param context The context.
* @param resolveInfo The resolve info.
* @returns The resolved representation value.
*/
async function defaultResolveReference(build,
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
representation,
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
context,
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
resolveInfo) {
var _a;
const { getTypeByName, scopeByType, inflection, nodeIdFieldName, pgSql: sql, parseResolveInfo, pgQueryFromResolveData: queryFromResolveData, pgPrepareAndRun, } = build;
const { pgClient } = context;
const { graphile: { fieldContext }, } = resolveInfo;
const _b = representation, { __typename } = _b, _c = nodeIdFieldName, nodeId = _b[_c], representationKeys = (0, tslib_1.__rest)(_b, ["__typename", typeof _c === "symbol" ? _c : _c + ""]);
const type = getTypeByName(__typename);
if (!type) {
throw new Error(
// eslint-disable-next-line max-len
`The _entities resolver tried to load an entity for type "${__typename}", but no object type of that name was found in the database schema`);
}
function filterByType(object, typeName, parent) {
let result = {};
for (const property in object) {
if (property == typeName && parent.fieldsByTypeName) {
result = parent;
break;
}
if (typeof object[property] === "object") {
result =
Object.keys(result).length === 0
? filterByType(object[property], typeName, object)
: result;
}
}
return result;
}
const { pgIntrospection: table } = scopeByType.get(type);
// Check if the representation key(s) exist in the type.
if (!((_a = table === null || table === void 0 ? void 0 : table.attributes) === null || _a === void 0 ? void 0 : _a.some((attribute) => representationKeys[inflection.column(attribute)] != undefined || null))) {
throw new Error("Incorrect representation key(s)");
}
let whereClause;
// If multiple representation keys are present,
// treat them as `OR` logic. Return after the first match.
for (const representationKey in representationKeys) {
// Get pg column attribute.
const attr = table.attributes.find((attribute) => inflection.column(attribute) === representationKey);
// If we can't find the user specified representation key,
// skip to the next representation key.
if (!attr) {
continue;
}
whereClause = sql.fragment `${sql.identifier(attr.name)} = ${sql.value(representationKeys[representationKey])}`;
// Stop looping. We only want to return first match.
break;
}
// Filter nested resolve info to only the type we need.
// If we don't do this, we won't be able to get to deeply nested types
// since the built-in `fieldContext.getDataFromParsedResolveInfoFragment`
// function only parses down two levels.
const parsedResolveInfo_filtered = filterByType(parseResolveInfo(resolveInfo), __typename, {});
const resolveData = fieldContext.getDataFromParsedResolveInfoFragment(parsedResolveInfo_filtered, type);
const query = queryFromResolveData(sql.identifier(table.namespace.name, table.name), undefined, resolveData, {
useAsterisk: false, // Because it's only a single relation, no need
}, (queryBuilder) => {
queryBuilder.where(whereClause);
}, context, resolveInfo.rootValue);
const { text, values } = sql.compile(query);
const { rows } = await pgPrepareAndRun(pgClient, text, values);
return rows.length > 1 ? rows : rows[0];
}
exports.defaultResolveReference = defaultResolveReference;
//# sourceMappingURL=defaultResolveReference.js.map