graphile-build-pg
Version:
Build a GraphQL schema by reflection over a PostgreSQL schema. Easy to customize since it's built with plugins on graphile-build
155 lines (154 loc) • 6.03 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _isString = _interopRequireDefault(require("lodash/isString"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var PgMutationPayloadEdgePlugin = function PgMutationPayloadEdgePlugin(builder, {
pgSimpleCollections,
disableIssue397Fix
}) {
builder.hook("GraphQLObjectType:fields", (fields, build, context) => {
const {
extend,
getSafeAliasFromResolveInfo,
getTypeByName,
pgGetGqlTypeByTypeIdAndModifier,
pgSql: sql,
graphql: {
GraphQLList,
GraphQLNonNull
},
inflection,
pgOmit: omit,
describePgEntity,
pgField
} = build;
const {
scope: {
isMutationPayload,
pgIntrospection,
pgIntrospectionTable
},
fieldWithHooks,
Self
} = context;
const table = pgIntrospectionTable || pgIntrospection;
if (!isMutationPayload || !table || table.kind !== "class" || !table.namespace || !table.isSelectable || omit(table, "all") && omit(table, "many")) {
return fields;
}
if (pgIntrospection.kind === "procedure" && (pgIntrospection.returnTypeId !== table.typeId || pgIntrospection.returnsSet)) {
return fields;
}
const simpleCollections = table.tags.simpleCollections || pgSimpleCollections;
const hasConnections = simpleCollections !== "only";
if (!hasConnections && !disableIssue397Fix) {
return fields;
}
const TableType = pgGetGqlTypeByTypeIdAndModifier(table.type.id, null);
const tableTypeName = TableType.name;
const TableOrderByType = getTypeByName(inflection.orderByType(tableTypeName));
const TableEdgeType = getTypeByName(inflection.edge(tableTypeName));
if (!TableEdgeType) {
return fields;
}
const primaryKeyConstraint = table.primaryKeyConstraint;
const primaryKeys = primaryKeyConstraint && primaryKeyConstraint.keyAttributes;
const canOrderBy = !omit(table, "order");
const fieldName = inflection.edgeField(table);
const primaryKeyAsc = inflection.builtin("PRIMARY_KEY_ASC");
const defaultValueEnum = canOrderBy && (TableOrderByType.getValues().find(v => v.name === primaryKeyAsc) || TableOrderByType.getValues()[0]);
return extend(fields, {
[fieldName]: pgField(build, fieldWithHooks, fieldName, {
description: build.wrapDescription(`An edge for our \`${tableTypeName}\`. May be used by Relay 1.`, "field"),
type: TableEdgeType,
args: canOrderBy ? {
orderBy: {
description: build.wrapDescription(`The method to use when ordering \`${tableTypeName}\`.`, "arg"),
type: new GraphQLList(new GraphQLNonNull(TableOrderByType)),
defaultValue: defaultValueEnum ? [defaultValueEnum.value] : null
}
} : {},
resolve(data, {
orderBy: rawOrderBy
}, _context, resolveInfo) {
if (!data.data) {
return null;
}
const safeAlias = getSafeAliasFromResolveInfo(resolveInfo);
const edge = data.data[safeAlias];
if (!edge) {
return null;
}
const orderBy = canOrderBy && rawOrderBy ? Array.isArray(rawOrderBy) ? rawOrderBy : [rawOrderBy] : null;
const order = orderBy && orderBy.some(item => item.alias) ? orderBy.filter(item => item.alias) : null;
if (!order) {
if (edge.__identifiers) {
return {
...edge,
__cursor: ["primary_key_asc", edge.__identifiers]
};
} else {
return edge;
}
}
return {
...edge,
__cursor: edge[`__order_${order.map(item => item.alias).join("__")}`]
};
}
}, {
isPgMutationPayloadEdgeField: true,
pgFieldIntrospection: table
}, false, {
withQueryBuilder(queryBuilder, {
parsedResolveInfoFragment
}) {
const {
args: {
orderBy: rawOrderBy
}
} = parsedResolveInfoFragment;
const orderBy = canOrderBy && rawOrderBy ? Array.isArray(rawOrderBy) ? rawOrderBy : [rawOrderBy] : null;
if (orderBy != null) {
const aliases = [];
const expressions = [];
let unique = false;
orderBy.forEach(item => {
const {
alias,
specs,
unique: itemIsUnique
} = item;
unique = unique || itemIsUnique;
const orders = Array.isArray(specs[0]) ? specs : [specs];
orders.forEach(([col, _ascending]) => {
if (!col) {
return;
}
const expr = (0, _isString.default)(col) ? sql.fragment`${queryBuilder.getTableAlias()}.${sql.identifier(col)}` : typeof col === "function" ? col({
queryBuilder
}) : col;
expressions.push(expr);
});
if (alias == null) return;
aliases.push(alias);
});
if (!unique && primaryKeys) {
// Add PKs
primaryKeys.forEach(key => {
expressions.push(sql.fragment`${queryBuilder.getTableAlias()}.${sql.identifier(key.name)}`);
});
}
if (aliases.length) {
queryBuilder.select(sql.fragment`json_build_array(${sql.join(aliases.map(a => sql.fragment`${sql.literal(a)}::text`), ", ")}, json_build_array(${sql.join(expressions, ", ")}))`, "__order_" + aliases.join("__"));
}
}
}
})
}, `Adding edge field for table ${describePgEntity(table)} to mutation payload '${Self.name}'`);
}, ["PgMutationPayloadEdge"]);
};
exports.default = PgMutationPayloadEdgePlugin;
//# sourceMappingURL=PgMutationPayloadEdgePlugin.js.map