graphql-page_cursors 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff87f78e643f6c03c976c91e44d541ccfdb3f9dd1f45614bf9113e048f7125c2
4
- data.tar.gz: 1d0ee957ef5f769cf006e06f88a89fd0481aa5842b6830d1d70dcc0c8fdedf3f
3
+ metadata.gz: 86e6f9c53e954f6da661bd84e583650bf1238c9c20708e7d8b271670d9132917
4
+ data.tar.gz: b145ce2ebc6d45729da5adfe14901cd992f6dec597ca3c84537015b361cc0389
5
5
  SHA512:
6
- metadata.gz: 9334ae540c56fc0ee2cc9e928e1e17b45f65bf54660162746d1fab70e07a89b1cab4e21122a0d9526575366748765cfe0079b6146d38a2f2f3b517fb92107fcd
7
- data.tar.gz: 00ec1948134ea669e920e57e33d958d2455980c445e51a3e78c68e6ee6d8c58b4606d11aab0ac2855cf55caae87006624e2a8fe8eaba3303da8b540cd90eadcf
6
+ metadata.gz: fd4075765ff52c8d216824e21b62f265522498f196fcd07eb297c344382823ffd797e2856b07dfa9454847193fa108f67815acfe4afe41ef18dae41d06afc6a9
7
+ data.tar.gz: 957064f909047bb83a7761e8d75f21f31ee4bba38d47812ec6c3380f6a7b4a5ed6ed06e3f0a0becb2c02b42e76a1a128674f6a5ebf176b4bd3ae2beaaf99e821
@@ -4,5 +4,9 @@ AllCops:
4
4
  NewCops: enable
5
5
  TargetRubyVersion: 2.7.1
6
6
 
7
+ Metrics/BlockLength:
8
+ Exclude:
9
+ - spec/**/*.rb
10
+
7
11
  Style/Documentation:
8
12
  Enabled: false
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'graphql'
4
4
 
5
+ require 'page_cursor_resolver'
6
+
5
7
  module GraphQL
6
8
  class PageCursor < GraphQL::Schema::Object
7
9
  field :cursor, String, 'first cursor on the page', null: false
@@ -21,116 +23,23 @@ module GraphQL
21
23
  field :total_pages, Int, null: true
22
24
  field :total_count, Int, null: true
23
25
 
24
- MAX_CURSOR_COUNT = 5
26
+ attr_reader :resolver
25
27
 
26
- def page_cursors
27
- return if total_pages <= 1
28
+ def initialize(object, context)
29
+ super(object, context)
30
+ @resolver = PageCursorResolver.new(object, context)
31
+ end
28
32
 
29
- {
30
- around: around_cursors,
31
- first: first_cursor,
32
- last: last_cursor,
33
- previous: previous_cursor
34
- }.compact
33
+ def page_cursors
34
+ resolver.page_cursors
35
35
  end
36
36
 
37
37
  def total_pages
38
- return 0 if object.items.size.zero?
39
- return 1 if nodes_per_page.nil?
40
-
41
- (object.items.size.to_f / nodes_per_page).ceil
38
+ resolver.total_pages
42
39
  end
43
40
 
44
41
  def total_count
45
- object.items.size
46
- end
47
-
48
- private
49
-
50
- def around_cursors
51
- around_page_numbers.map { |page_num| page_cursor(page_num) }
52
- end
53
-
54
- def first_cursor
55
- exceeds_max_cursor_count = total_pages > MAX_CURSOR_COUNT
56
- include_first_cursor =
57
- exceeds_max_cursor_count && around_page_numbers.exclude?(1)
58
- return unless include_first_cursor
59
-
60
- page_cursor(1)
61
- end
62
-
63
- def last_cursor
64
- exceeds_max_cursor_count = total_pages > MAX_CURSOR_COUNT
65
- include_last_cursor =
66
- exceeds_max_cursor_count && around_page_numbers.exclude?(total_pages)
67
- return unless include_last_cursor
68
-
69
- page_cursor(total_pages)
70
- end
71
-
72
- def previous_cursor
73
- include_previous_cursor = current_page > 1
74
- return unless include_previous_cursor
75
-
76
- page_cursor(current_page - 1)
77
- end
78
-
79
- def page_cursor(page_num)
80
- {
81
- cursor: cursor_for_page(page_num),
82
- is_current: current_page == page_num,
83
- page: page_num
84
- }
85
- end
86
-
87
- def cursor_for_page(page_num)
88
- return '' if page_num == 1
89
-
90
- after_cursor = (page_num - 1) * nodes_per_page
91
- encode(after_cursor.to_s)
92
- end
93
-
94
- def current_page
95
- nodes_before / nodes_per_page + 1
96
- end
97
-
98
- def around_page_numbers # rubocop:disable Metrics/AbcSize
99
- if total_pages <= MAX_CURSOR_COUNT
100
- (1..total_pages).to_a
101
- elsif current_page <= 3
102
- (1..4).to_a
103
- elsif current_page >= total_pages - 2
104
- ((total_pages - 3)..total_pages).to_a
105
- else
106
- [current_page - 1, current_page, current_page + 1]
107
- end
108
- end
109
-
110
- def nodes_before
111
- node_offset(object.edge_nodes.first) - 1
112
- end
113
-
114
- def nodes_after
115
- node_offset(object.edge_nodes.last)
116
- end
117
-
118
- def node_offset(node)
119
- # this was previously accomplished by calling a private method:
120
- # object.send(:offset_from_cursor, object.cursor_from_node(object.edge_nodes.first))
121
- object.items.index(node) + 1
122
- end
123
-
124
- def nodes_per_page
125
- object.first || object.last
126
- end
127
-
128
- # borrowed from https://graphql-ruby.org/api-doc/1.10.6/Base64Bp.html
129
- def encode(value)
130
- str = Base64.strict_encode64(value)
131
- str.tr!('+/', '-_')
132
- str.delete!('=')
133
- str
42
+ resolver.total_count
134
43
  end
135
44
  end
136
45
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'base64'
4
+
5
+ class PageCursor
6
+ def self.as_hash(current_page, page_number, per_page)
7
+ new(current_page, page_number, per_page).to_hash
8
+ end
9
+
10
+ attr_reader :current_page, :page_number, :per_page
11
+
12
+ def initialize(current_page, page_number, per_page)
13
+ @current_page = current_page
14
+ @page_number = page_number
15
+ @per_page = per_page
16
+ end
17
+
18
+ def to_hash
19
+ {
20
+ cursor: encoded_cursor,
21
+ is_current: current?,
22
+ page: page_number
23
+ }
24
+ end
25
+
26
+ private
27
+
28
+ def current?
29
+ current_page == page_number
30
+ end
31
+
32
+ def encoded_cursor
33
+ previous_page = page_number - 1
34
+ return '' if previous_page.zero?
35
+
36
+ after_cursor = previous_page * per_page
37
+ encoded = Base64.strict_encode64(after_cursor.to_s)
38
+ encoded.tr('+/', '-_').delete('=')
39
+ end
40
+ end
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'page_cursor'
4
+
5
+ class PageCursorResolver
6
+ MAX_CURSOR_COUNT = 5
7
+
8
+ attr_reader :object, :context
9
+
10
+ def initialize(object, context)
11
+ @object = object
12
+ @context = context
13
+ end
14
+
15
+ def page_cursors
16
+ return if total_pages <= 1
17
+
18
+ {
19
+ around: around_cursors,
20
+ first: first_cursor,
21
+ last: last_cursor,
22
+ previous: previous_cursor
23
+ }.compact
24
+ end
25
+
26
+ def total_pages
27
+ return 0 if object_items.size.zero?
28
+ return 1 if nodes_per_page.nil?
29
+
30
+ (object_items.size.to_f / nodes_per_page).ceil
31
+ end
32
+
33
+ def total_count
34
+ object_items.size
35
+ end
36
+
37
+ private
38
+
39
+ def object_items
40
+ return object.nodes unless object.respond_to?(:items)
41
+
42
+ object.items
43
+ end
44
+
45
+ def around_cursors
46
+ around_page_numbers.map { |page_num| page_cursor(page_num) }
47
+ end
48
+
49
+ def first_cursor
50
+ exceeds_max_cursor_count = total_pages > MAX_CURSOR_COUNT
51
+ include_first_cursor =
52
+ exceeds_max_cursor_count && !around_page_numbers.include?(1)
53
+ return unless include_first_cursor
54
+
55
+ page_cursor(1)
56
+ end
57
+
58
+ def last_cursor
59
+ exceeds_max_cursor_count = total_pages > MAX_CURSOR_COUNT
60
+ include_last_cursor =
61
+ exceeds_max_cursor_count && !around_page_numbers.include?(total_pages)
62
+ return unless include_last_cursor
63
+
64
+ page_cursor(total_pages)
65
+ end
66
+
67
+ def previous_cursor
68
+ include_previous_cursor = current_page > 1
69
+ return unless include_previous_cursor
70
+
71
+ page_cursor(current_page - 1)
72
+ end
73
+
74
+ def page_cursor(page_number)
75
+ PageCursor.as_hash(current_page, page_number, nodes_per_page)
76
+ end
77
+
78
+ def current_page
79
+ nodes_before / nodes_per_page + 1
80
+ end
81
+
82
+ def around_page_numbers # rubocop:disable Metrics/AbcSize
83
+ if total_pages <= MAX_CURSOR_COUNT
84
+ (1..total_pages).to_a
85
+ elsif current_page <= 3
86
+ (1..4).to_a
87
+ elsif current_page >= total_pages - 2
88
+ ((total_pages - 3)..total_pages).to_a
89
+ else
90
+ [current_page - 1, current_page, current_page + 1]
91
+ end
92
+ end
93
+
94
+ def nodes_before
95
+ node_offset(object.edge_nodes.first) - 1
96
+ end
97
+
98
+ def nodes_after
99
+ node_offset(object.edge_nodes.last)
100
+ end
101
+
102
+ def node_offset(node)
103
+ # this was previously accomplished by calling a private method:
104
+ # object.send(:offset_from_cursor, object.cursor_from_node(object.edge_nodes.first))
105
+ object_items.index(node) + 1
106
+ end
107
+
108
+ def nodes_per_page
109
+ object.first || object.last
110
+ end
111
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class PageCursors
4
- VERSION = '0.0.1'
4
+ VERSION = '0.0.2'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql-page_cursors
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Allured
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-11 00:00:00.000000000 Z
11
+ date: 2020-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -104,6 +104,8 @@ files:
104
104
  - bin/setup
105
105
  - graphql-page_cursors.gemspec
106
106
  - lib/graphql/page_cursors.rb
107
+ - lib/page_cursor.rb
108
+ - lib/page_cursor_resolver.rb
107
109
  - lib/page_cursors/version.rb
108
110
  homepage: https://github.com/artsy/graphql-page_cursors
109
111
  licenses: