Skip to content

Commit 96ee4c8

Browse files
author
Thomas Leonard
committed
fix: align previous/next page flag with relay standard
1 parent 611c033 commit 96ee4c8

File tree

2 files changed

+428
-42
lines changed

2 files changed

+428
-42
lines changed

src/graphql_relay/connection/array_connection.py

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,32 +103,39 @@ def connection_from_array_slice(
103103
after = args.get("after")
104104
first = args.get("first")
105105
last = args.get("last")
106+
106107
if array_slice_length is None:
107108
array_slice_length = len(array_slice)
108109
slice_end = slice_start + array_slice_length
109110
if array_length is None:
111+
# Assume that the slice covers until the end of the result set
110112
array_length = slice_end
111113

112114
start_offset = max(slice_start, 0)
113115
end_offset = min(slice_end, array_length)
114116

117+
first_edge_offset = 0
115118
after_offset = get_offset_with_default(after, -1)
116119
if 0 <= after_offset < array_length:
117120
start_offset = max(start_offset, after_offset + 1)
121+
first_edge_offset = after_offset + 1
118122

119-
before_offset = get_offset_with_default(before, end_offset)
123+
last_edge_offset = array_length - 1
124+
before_offset = get_offset_with_default(before, array_length)
120125
if 0 <= before_offset < array_length:
121126
end_offset = min(end_offset, before_offset)
127+
last_edge_offset = before_offset - 1
128+
129+
number_edges_after_cursors = last_edge_offset - first_edge_offset + 1
122130

123131
if isinstance(first, int):
124132
if first < 0:
125133
raise ValueError("Argument 'first' must be a non-negative integer.")
126-
127134
end_offset = min(end_offset, start_offset + first)
135+
128136
if isinstance(last, int):
129137
if last < 0:
130138
raise ValueError("Argument 'last' must be a non-negative integer.")
131-
132139
start_offset = max(start_offset, end_offset - last)
133140

134141
# If supplied slice is too large, trim it down before mapping over it.
@@ -141,16 +148,28 @@ def connection_from_array_slice(
141148

142149
first_edge_cursor = edges[0].cursor if edges else None
143150
last_edge_cursor = edges[-1].cursor if edges else None
144-
lower_bound = after_offset + 1 if after else 0
145-
upper_bound = before_offset if before else array_length
151+
152+
# Determine hasPreviousPage
153+
has_previous_page = False
154+
if isinstance(last, int):
155+
has_previous_page = number_edges_after_cursors > last
156+
elif after is not None:
157+
has_previous_page = after_offset >= 0
158+
159+
# Determine hasNextPage
160+
has_next_page = False
161+
if isinstance(first, int):
162+
has_next_page = number_edges_after_cursors > first
163+
elif before is not None:
164+
has_next_page = before_offset < array_length
146165

147166
return connection_type(
148167
edges=edges,
149168
pageInfo=page_info_type(
150169
startCursor=first_edge_cursor,
151170
endCursor=last_edge_cursor,
152-
hasPreviousPage=isinstance(last, int) and start_offset > lower_bound,
153-
hasNextPage=isinstance(first, int) and end_offset < upper_bound,
171+
hasPreviousPage=has_previous_page,
172+
hasNextPage=has_next_page,
154173
),
155174
)
156175

0 commit comments

Comments
 (0)