UNPKG

react-relay

Version:

A framework for building GraphQL-driven React applications.

98 lines (86 loc) 2.42 kB
/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow strict-local * @format * @oncall relay */ 'use strict'; import type {Direction, ReaderFragment} from 'relay-runtime'; const invariant = require('invariant'); const {ConnectionInterface, getValueAtPath} = require('relay-runtime'); function getConnectionState( direction: Direction, fragmentNode: ReaderFragment, fragmentData: mixed, connectionPathInFragmentData: $ReadOnlyArray<string | number>, ): { cursor: ?string, hasMore: boolean, } { const { EDGES, PAGE_INFO, HAS_NEXT_PAGE, HAS_PREV_PAGE, END_CURSOR, START_CURSOR, } = ConnectionInterface.get(); const connection = getValueAtPath(fragmentData, connectionPathInFragmentData); if (connection == null) { return {cursor: null, hasMore: false}; } invariant( typeof connection === 'object', 'Relay: Expected connection in fragment `%s` to have been `null`, or ' + 'a plain object with %s and %s properties. Instead got `%s`.', fragmentNode.name, EDGES, PAGE_INFO, connection, ); const edges = connection[EDGES]; const pageInfo = connection[PAGE_INFO]; if (edges == null || pageInfo == null) { return {cursor: null, hasMore: false}; } invariant( Array.isArray(edges), 'Relay: Expected connection in fragment `%s` to have a plural `%s` field. ' + 'Instead got `%s`.', fragmentNode.name, EDGES, edges, ); invariant( typeof pageInfo === 'object', 'Relay: Expected connection in fragment `%s` to have a `%s` field. ' + 'Instead got `%s`.', fragmentNode.name, PAGE_INFO, pageInfo, ); const cursor = direction === 'forward' ? pageInfo[END_CURSOR] ?? null : pageInfo[START_CURSOR] ?? null; invariant( cursor === null || typeof cursor === 'string', 'Relay: Expected page info for connection in fragment `%s` to have a ' + 'valid `%s`. Instead got `%s`.', fragmentNode.name, START_CURSOR, cursor, ); let hasMore; if (direction === 'forward') { hasMore = cursor != null && pageInfo[HAS_NEXT_PAGE] === true; } else { hasMore = cursor != null && pageInfo[HAS_PREV_PAGE] === true; } return {cursor, hasMore}; } module.exports = getConnectionState;