diff --git a/docs/_docs/04-04-plugins-server.md b/docs/_docs/04-04-plugins-server.md index 13df5564f..f807da141 100644 --- a/docs/_docs/04-04-plugins-server.md +++ b/docs/_docs/04-04-plugins-server.md @@ -85,6 +85,52 @@ configure the context plugin before it would be mounted at `context.plugins`. This plugin above would mount at: `context.plugins.Slack`, or, if you're using [object destructuring](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment), `{plugins: {Slack}}`. +##### `Sort` + +A special context hook, `Sort` will allow plugin authors to provide new +methods to sort data. An example is as follows: + +```js +{ + Sort: () => ({ + Comments: { // <-- (1) + likes: { // <-- (2) + startCursor(ctx, nodes, {cursor}) { // <-- (3) + return cursor != null ? cursor : 0; + }, + endCursor(ctx, nodes, {cursor}) { // <-- (4) + return nodes.length ? (cursor != null ? cursor : 0) + nodes.length : null; + }, + sort(ctx, query, {cursor, sort}) { // <-- (5) + if (cursor) { + query = query.skip(cursor); + } + + return query.sort({ + 'action_counts.like': sort === 'DESC' ? -1 : 1, + created_at: sort === 'DESC' ? -1 : 1, + }); + }, + }, + }, + }), +} +``` + +This has a bunch of special features: + +1. `Comments` is the name of the type being sorted, this is pluralized and + capitalized. +2. `likes` is the `sortBy` field in lowercase. +3. `startCursor` will retrieve the start cursor based on the current set of + nodes and the current cursor. +4. `endCursor` will retrieve the end cursor based on the current set of nodes + and the current cursor. +5. `sort` will mutate the `query` to apply the sort operations. + +All the `startCursor`, `endCursor`, and `sort` functions must be provided in +order for the sorting to apply properly. + #### Field: `loaders` ```js diff --git a/graph/loaders/comments.js b/graph/loaders/comments.js index d637a9ef0..c71777b6b 100644 --- a/graph/loaders/comments.js +++ b/graph/loaders/comments.js @@ -151,11 +151,11 @@ const getStartCursor = (ctx, nodes, {cursor, sortBy}) => { } const SORT_KEY = sortBy.toLowerCase(); - if (!ctx.plugins || !ctx.plugins.CommentSort || !ctx.plugins.CommentSort[SORT_KEY] || !ctx.plugins.CommentSort[SORT_KEY].startCursor) { + if (!ctx.plugins || !ctx.plugins.Sort.Comments || !ctx.plugins.Sort.Comments[SORT_KEY] || !ctx.plugins.Sort.Comments[SORT_KEY].startCursor) { throw new Error(`unable to sort by ${sortBy}, no plugin was provided to handle this type`); } - return ctx.plugins.CommentSort[SORT_KEY].startCursor(ctx, nodes, {cursor}); + return ctx.plugins.Sort.Comments[SORT_KEY].startCursor(ctx, nodes, {cursor}); }; /** @@ -174,11 +174,11 @@ const getEndCursor = (ctx, nodes, {cursor, sortBy}) => { } const SORT_KEY = sortBy.toLowerCase(); - if (!ctx.plugins || !ctx.plugins.CommentSort || !ctx.plugins.CommentSort[SORT_KEY] || !ctx.plugins.CommentSort[SORT_KEY].endCursor) { + if (!ctx.plugins || !ctx.plugins.Sort.Comments || !ctx.plugins.Sort.Comments[SORT_KEY] || !ctx.plugins.Sort.Comments[SORT_KEY].endCursor) { throw new Error(`unable to sort by ${sortBy}, no plugin was provided to handle this type`); } - return ctx.plugins.CommentSort[SORT_KEY].endCursor(ctx, nodes, {cursor}); + return ctx.plugins.Sort.Comments[SORT_KEY].endCursor(ctx, nodes, {cursor}); }; /** @@ -220,11 +220,11 @@ const applySort = (ctx, query, {cursor, sort, sortBy}) => { } const SORT_KEY = sortBy.toLowerCase(); - if (!ctx.plugins || !ctx.plugins.CommentSort || !ctx.plugins.CommentSort[SORT_KEY] || !ctx.plugins.CommentSort[SORT_KEY].sort) { + if (!ctx.plugins || !ctx.plugins.Sort.Comments || !ctx.plugins.Sort.Comments[SORT_KEY] || !ctx.plugins.Sort.Comments[SORT_KEY].sort) { throw new Error(`unable to sort by ${sortBy}, no plugin was provided to handle this type`); } - return ctx.plugins.CommentSort[SORT_KEY].sort(ctx, query, {cursor, sort}); + return ctx.plugins.Sort.Comments[SORT_KEY].sort(ctx, query, {cursor, sort}); }; /** diff --git a/plugin-api/beta/server/getReactionConfig.js b/plugin-api/beta/server/getReactionConfig.js index f0aa23324..46bf0b892 100644 --- a/plugin-api/beta/server/getReactionConfig.js +++ b/plugin-api/beta/server/getReactionConfig.js @@ -118,22 +118,24 @@ function getReactionConfig(reaction) { return { typeDefs, context: { - CommentSort: () => ({ - [reactionPlural]: { - startCursor(ctx, nodes, {cursor}) { + Sort: () => ({ + Comments: { + [reactionPlural]: { + startCursor(ctx, nodes, {cursor}) { - // The cursor is the start! This is using numeric pagination. - return cursor != null ? cursor : 0; - }, - endCursor(ctx, nodes, {cursor}) { - return nodes.length ? (cursor != null ? cursor : 0) + nodes.length : null; - }, - sort(ctx, query, {cursor, sort}) { - if (cursor) { - query = query.skip(cursor); - } + // The cursor is the start! This is using numeric pagination. + return cursor != null ? cursor : 0; + }, + endCursor(ctx, nodes, {cursor}) { + return nodes.length ? (cursor != null ? cursor : 0) + nodes.length : null; + }, + sort(ctx, query, {cursor, sort}) { + if (cursor) { + query = query.skip(cursor); + } - return query.sort({[`action_counts.${reaction}`]: sort === 'DESC' ? -1 : 1, created_at: sort === 'DESC' ? -1 : 1}); + return query.sort({[`action_counts.${reaction}`]: sort === 'DESC' ? -1 : 1, created_at: sort === 'DESC' ? -1 : 1}); + }, }, }, }),