UNPKG

3.13 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.relayStylePaginationMock = void 0;
4const utils_js_1 = require("./utils.js");
5/**
6 * Produces a resolver that'll mock a [Relay-style cursor pagination](https://relay.dev/graphql/connections.htm).
7 *
8 * ```ts
9 * const schemaWithMocks = addMocksToSchema({
10 * schema,
11 * resolvers: (store) => ({
12 * User: {
13 * friends: relayStylePaginationMock(store),
14 * }
15 * }),
16 * })
17 * ```
18 * @param store the MockStore
19 */
20const relayStylePaginationMock = (store, { cursorFn = node => `${node.$ref.key}`, applyOnNodes, allNodesFn, } = {}) => {
21 return (parent, args, context, info) => {
22 const source = (0, utils_js_1.isRootType)(info.parentType, info.schema) ? (0, utils_js_1.makeRef)(info.parentType.name, 'ROOT') : parent;
23 const allNodesFn_ = allNodesFn !== null && allNodesFn !== void 0 ? allNodesFn : defaultAllNodesFn(store);
24 let allNodes = allNodesFn_(source, args, context, info);
25 if (applyOnNodes) {
26 allNodes = applyOnNodes(allNodes, args);
27 }
28 const allEdges = allNodes.map(node => ({
29 node,
30 cursor: cursorFn(node),
31 }));
32 let start, end;
33 const { first, after, last, before } = args;
34 if (typeof first === 'number') {
35 // forward pagination
36 if (last || before) {
37 throw new Error("if `first` is provided, `last` or `before` can't be provided");
38 }
39 const afterIndex = after ? allEdges.findIndex(e => e.cursor === after) : -1;
40 start = afterIndex + 1;
41 end = afterIndex + 1 + first;
42 }
43 else if (typeof last === 'number') {
44 // backward pagination
45 if (first || after) {
46 throw new Error("if `last` is provided, `first` or `after` can't be provided");
47 }
48 const foundBeforeIndex = before ? allEdges.findIndex(e => e.cursor === before) : -1;
49 const beforeIndex = foundBeforeIndex !== -1 ? foundBeforeIndex : allNodes.length;
50 start = allEdges.length - (allEdges.length - beforeIndex) - last;
51 // negative index on Array.slice indicate offset from end of sequence => we don't want
52 if (start < 0)
53 start = 0;
54 end = beforeIndex;
55 }
56 else {
57 throw new Error('A `first` or a `last` arguments should be provided');
58 }
59 const edges = allEdges.slice(start, end);
60 const pageInfo = {
61 startCursor: edges.length > 0 ? edges[0].cursor : '',
62 endCursor: edges.length > 0 ? edges[edges.length - 1].cursor : '',
63 hasNextPage: end < allEdges.length - 1,
64 hasPreviousPage: start > 0,
65 };
66 return {
67 edges,
68 pageInfo,
69 totalCount: allEdges.length,
70 };
71 };
72};
73exports.relayStylePaginationMock = relayStylePaginationMock;
74const defaultAllNodesFn = (store) => (parent, _, __, info) => store.get(parent, [info.fieldName, 'edges']).map(e => store.get(e, 'node'));