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
144 lines (143 loc) • 5.11 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 PgConnectionArgOrderBy = function PgConnectionArgOrderBy(builder, {
orderByNullsLast
}) {
builder.hook("init", (_, build) => {
const {
newWithHooks,
pgIntrospectionResultsByKind: introspectionResultsByKind,
graphql: {
GraphQLEnumType
},
inflection,
pgOmit: omit,
sqlCommentByAddingTags,
describePgEntity
} = build;
introspectionResultsByKind.class.forEach(table => {
// PERFORMANCE: These used to be .filter(...) calls
if (!table.isSelectable || omit(table, "order")) return;
if (!table.namespace) return;
const tableTypeName = inflection.tableType(table);
/* const TableOrderByType = */
newWithHooks(GraphQLEnumType, {
name: inflection.orderByType(tableTypeName),
description: build.wrapDescription(`Methods to use when ordering \`${tableTypeName}\`.`, "type"),
values: {
[inflection.builtin("NATURAL")]: {
value: {
alias: null,
specs: []
}
}
}
}, {
__origin: `Adding connection "orderBy" argument for ${describePgEntity(table)}. You can rename the table's GraphQL type via a 'Smart Comment':\n\n ${sqlCommentByAddingTags(table, {
name: "newNameHere"
})}`,
pgIntrospection: table,
isPgRowSortEnum: true
});
});
return _;
}, ["PgConnectionArgOrderBy"]);
builder.hook("GraphQLObjectType:fields:field:args", (args, build, context) => {
const {
extend,
getTypeByName,
pgGetGqlTypeByTypeIdAndModifier,
pgSql: sql,
graphql: {
GraphQLList,
GraphQLNonNull
},
inflection,
pgOmit: omit
} = build;
const {
scope: {
fieldName,
isPgFieldConnection,
isPgFieldSimpleCollection,
pgFieldIntrospection,
pgFieldIntrospectionTable
},
addArgDataGenerator,
Self
} = context;
if (!isPgFieldConnection && !isPgFieldSimpleCollection) {
return args;
}
const proc = pgFieldIntrospection.kind === "procedure" ? pgFieldIntrospection : null;
const table = pgFieldIntrospection.kind === "class" ? pgFieldIntrospection : proc ? pgFieldIntrospectionTable : null;
if (!table || !table.namespace || !table.isSelectable || omit(table, "order")) {
return args;
}
if (proc) {
if (!proc.tags.sortable) {
return args;
}
}
const TableType = pgGetGqlTypeByTypeIdAndModifier(table.type.id, null);
const tableTypeName = TableType.name;
const TableOrderByType = getTypeByName(inflection.orderByType(tableTypeName));
const cursorPrefixFromOrderBy = orderBy => {
if (orderBy) {
const cursorPrefixes = [];
for (let itemIndex = 0, itemCount = orderBy.length; itemIndex < itemCount; itemIndex++) {
const item = orderBy[itemIndex];
if (item.alias) {
cursorPrefixes.push(sql.literal(item.alias));
}
}
if (cursorPrefixes.length > 0) {
return cursorPrefixes;
}
}
return null;
};
addArgDataGenerator(function connectionOrderBy({
orderBy: rawOrderBy
}) {
const orderBy = rawOrderBy ? Array.isArray(rawOrderBy) ? rawOrderBy : [rawOrderBy] : null;
return {
pgCursorPrefix: cursorPrefixFromOrderBy(orderBy),
pgQuery: queryBuilder => {
if (orderBy != null) {
orderBy.forEach(item => {
const {
specs,
unique
} = item;
const orders = Array.isArray(specs[0]) || specs.length === 0 ? specs : [specs];
orders.forEach(([col, ascending, specNullsFirst]) => {
const expr = (0, _isString.default)(col) ? sql.fragment`${queryBuilder.getTableAlias()}.${sql.identifier(col)}` : col;
// If the enum specifies null ordering, use that
// Otherwise, use the orderByNullsLast option if present
const nullsFirst = specNullsFirst != null ? specNullsFirst : orderByNullsLast != null ? !orderByNullsLast : undefined;
queryBuilder.orderBy(expr, ascending, nullsFirst);
});
if (unique) {
queryBuilder.setOrderIsUnique();
}
});
}
}
};
});
return extend(args, {
orderBy: {
description: build.wrapDescription(`The method to use when ordering \`${tableTypeName}\`.`, "arg"),
type: new GraphQLList(new GraphQLNonNull(TableOrderByType))
}
}, `Adding 'orderBy' argument to field '${fieldName}' of '${Self.name}'`);
}, ["PgConnectionArgOrderBy"]);
};
exports.default = PgConnectionArgOrderBy;
//# sourceMappingURL=PgConnectionArgOrderBy.js.map