graphql-page_cursors 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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: