From 26b8117fe547f9ec5dfd75b248fbe31910d77fc1 Mon Sep 17 00:00:00 2001 From: Domizio Demichelis Date: Fri, 26 Jul 2024 23:10:33 +0700 Subject: [PATCH 1/8] Complete the internal refactoring of version 9: - Remove the pagy*_get_vars methods now useless - Use to_i on the page variable for the search extras --- docs/api/backend.md | 23 +---------------- docs/extras/arel.md | 11 +++------ docs/extras/array.md | 5 ---- docs/extras/countless.md | 5 ---- docs/extras/elasticsearch_rails.md | 5 ---- docs/extras/keyset.md | 6 ----- docs/extras/meilisearch.md | 5 ---- docs/extras/searchkick.md | 5 ---- docs/how-to.md | 4 +-- gem/lib/pagy/backend.rb | 19 ++++++-------- gem/lib/pagy/extras/arel.rb | 10 ++------ gem/lib/pagy/extras/array.rb | 11 +++------ gem/lib/pagy/extras/countless.rb | 13 +++------- gem/lib/pagy/extras/elasticsearch_rails.rb | 23 ++++++----------- gem/lib/pagy/extras/keyset.rb | 12 +++------ gem/lib/pagy/extras/limit.rb | 4 +-- gem/lib/pagy/extras/meilisearch.rb | 12 ++------- gem/lib/pagy/extras/searchkick.rb | 12 ++------- gem/lib/pagy/i18n.rb | 2 +- test/pagy/backend_test.rb | 21 +++++++++------- test/pagy/extras/arel_test.rb | 20 +++++++++------ test/pagy/extras/array_test.rb | 26 -------------------- test/pagy/extras/elasticsearch_rails_test.rb | 22 ----------------- test/pagy/extras/limit_test.rb | 12 --------- test/pagy/extras/meilisearch_test.rb | 22 ----------------- test/pagy/extras/searchkick_test.rb | 22 ----------------- 26 files changed, 63 insertions(+), 269 deletions(-) diff --git a/docs/api/backend.md b/docs/api/backend.md index 34cb89d24..efdb0baca 100644 --- a/docs/api/backend.md +++ b/docs/api/backend.md @@ -31,11 +31,6 @@ and [meilisearch](/docs/extras/meilisearch.md) extras for specific backend custo ```ruby Controller include Pagy::Backend -# optional overriding of some sub-method -def pagy_get_vars(collection, **vars) - #... -end - # use it in some action def index @pagy, @records = pagy(Product.some_scope, some_option: 'some option for this instance') @@ -60,26 +55,10 @@ the `Pagy.new` method) and returns the `Pagy` instance and the page of records. @pagy, @records = pagy(Product.my_scope, some_option: 'get merged in the pagy object') ``` -The built-in `pagy` method is designed to be easy to customize by overriding any of the two sub-methods that it calls internally. -You can independently change the default variables (`pagy_get_vars`) and/or the default page of items from the -collection `pagy_get_items`). - +The built-in `pagy` method is designed to be easy to customize by overriding any sub-methods that it calls internally. If you need to use multiple different types of collections in the same app or action, you may want to define some alternative and self contained custom `pagy` method. (see [Writing your own Pagy methods](#writing-your-own-pagy-methods)) -==- `pagy_get_vars(collection, vars)` - -Sub-method called only by the `pagy` method, it returns the hash of variables used to initialize the Pagy object. - -Override it if you need to add or change some variable. For example you may want to add the `:item_name` in order to customize -the output _(see [How to customize the item name](/docs/how-to.md#customize-the-item-name))_. - -!!!warning Don't remove `:count` and `:page` -If you override it, remember that `:count` and `:page` are the only 2 required Pagy core variables, so be careful not to remove them from the returned hash. -!!! - -See also the [How To](/docs/how-to.md) page for some usage examples. - ==- `pagy_get_count(collection, vars)` Get the count from the collection, considering also the `:count_args` variable. Override it if you need to calculate the count in some special way, or cache it. e.g. overriding [`pagy_get_count` when using mongoid](../how-to/#override-pagy_get_count-use-count_documents-with-mongoid). diff --git a/docs/extras/arel.md b/docs/extras/arel.md index 7e2cfc2f5..77cc3becf 100644 --- a/docs/extras/arel.md +++ b/docs/extras/arel.md @@ -35,15 +35,10 @@ require 'pagy/extras/arel' This method is the same as the generic `pagy` method, but with improved speed for SQL `GROUP BY` collections. (see the [pagy doc](/docs/api/backend.md#pagy-collection-vars-nil)) -==- `pagy_arel_get_vars(collection)` - -This sub-method is the same as the `pagy_get_vars` sub-method, but it is called only by the `pagy_arel` method. (see -the [pagy_get_vars doc](/docs/api/backend.md#pagy-get-vars-collection-vars)). - ==- `pagy_arel_count(collection)` -This sub-method it is called only by the `pagy_get_vars` method. It will detect which query to perform based on the active record -groups (sql `GROUP BY`s). In case there aren't group values performs a normal `.count(:all)`, otherwise it will perform -a `COUNT(*) OVER ()`. The last tells database to perform a count of all the lines after the `GROUP BY` clause is applied. +This sub-method detects which query to perform based on the active record groups (sql `GROUP BY`s). In case there aren't +group values performs a normal `.count(:all)`, otherwise it will perform a `COUNT(*) OVER ()`. The last tells database to +perform a count of all the lines after the `GROUP BY` clause is applied. === diff --git a/docs/extras/array.md b/docs/extras/array.md index a7496bc1b..d936f208e 100644 --- a/docs/extras/array.md +++ b/docs/extras/array.md @@ -50,9 +50,4 @@ require 'pagy/extras/array' This method is the same as the generic `pagy` method, but specialized for an Array. (see the [pagy doc](/docs/api/backend.md#pagy-collection-vars-nil)) -==- `pagy_array_get_vars(array)` - -This sub-method is the same as the `pagy_get_vars` sub-method, but it is called only by the `pagy_array` method. (see -the [pagy_get_vars doc](/docs/api/backend.md#pagy-get-vars-collection-vars)). - === diff --git a/docs/extras/countless.md b/docs/extras/countless.md index 7f4b282d3..c1bd4cb6c 100644 --- a/docs/extras/countless.md +++ b/docs/extras/countless.md @@ -96,11 +96,6 @@ This mode is enabled by the `:countless_minimal` variable. This method is the same as the generic `pagy` method (see the [pagy doc](/docs/api/backend.md#pagy-collection-vars-nil)), however its returned objects will depend on the value of the `:countless_minimal` variable (see [Modes](#modes)) -==- `pagy_countless_get_vars(_collection, vars)` - -This sub-method is similar to the `pagy_get_vars` sub-method, but it is called only by the `pagy_countless` method. (see -the [pagy_get_vars doc](/docs/api/backend.md#pagy-get-vars-collection-vars)). - ==- `pagy_countless_get_items(collection, pagy)` This sub-method is similar to the `pagy_get_items` sub-method, but it is called only by the `pagy_countless` method. (see diff --git a/docs/extras/elasticsearch_rails.md b/docs/extras/elasticsearch_rails.md index 0aeb77867..87e607e55 100644 --- a/docs/extras/elasticsearch_rails.md +++ b/docs/extras/elasticsearch_rails.md @@ -83,9 +83,4 @@ the [pagy doc](/docs/api/backend.md#pagy-collection-vars-nil)). It expects to receive `YourModel.pagy_search(...)` result and returns the paginated response. -==- `pagy_elasticsearch_rails_get_vars(array)` - -This sub-method is similar to the `pagy_get_vars` sub-method, but it is called only by the `pagy_elasticsearch_rails` method. (see -the [pagy_get_vars doc](/docs/api/backend.md#pagy-get-vars-collection-vars)). - === diff --git a/docs/extras/keyset.md b/docs/extras/keyset.md index fa893393a..24b17a75b 100644 --- a/docs/extras/keyset.md +++ b/docs/extras/keyset.md @@ -69,12 +69,6 @@ See the [Pagy::Keyset variables](/docs/api/keyset.md#variables) This method is similar to the offset `pagy` method. It returns the `pagy` object (instance of `Pagy::Keyset::ActiveRecord` or `Pagy::Keyset::Sequel`, depending on the set class) and the array of `records` pulled from the DB. -==- `pagy_keyset_get_vars(vars)` - -This sub-method is internally called only by the `pagy_keyset` method. It automatically sets the `:page` variable and - if you -use the [limit extra](limit.md) also the `:limit` variables from the request `params`. Documented only for -overriding. - ==- `pagy_keyset_first_url(pagy, absolute: false)` Return the first page URL string. (See also the [headers](headers.md) and [jsonapi](jsonapi.md) extras for more complete solutions) diff --git a/docs/extras/meilisearch.md b/docs/extras/meilisearch.md index c6aefca18..74025065d 100644 --- a/docs/extras/meilisearch.md +++ b/docs/extras/meilisearch.md @@ -85,9 +85,4 @@ the [pagy doc](/docs/api/backend.md#pagy-collection-vars-nil)) It expects to receive `YourModel.pagy_search(...)` result and returns the paginated response. -==- `pagy_meilisearch_get_vars(array)` - -This sub-method is similar to the `pagy_get_vars` sub-method, but it is called only by the `pagy_meilisearch` method. (see -the [pagy_get_vars doc](/docs/api/backend.md#pagy-get-vars-collection-vars)). - === diff --git a/docs/extras/searchkick.md b/docs/extras/searchkick.md index bfac3cfae..f138327c5 100644 --- a/docs/extras/searchkick.md +++ b/docs/extras/searchkick.md @@ -86,9 +86,4 @@ the [pagy doc](/docs/api/backend.md#pagy-collection-vars-nil)) It expects to receive `YourModel.pagy_search(...)` result and returns the paginated response. -==- `pagy_searchkick_get_vars(array)` - -This sub-method is similar to the `pagy_get_vars` sub-method, but it is called only by the `pagy_searchkick` method. (see -the [pagy_get_vars doc](/docs/api/backend.md#pagy-get-vars-collection-vars)). - === diff --git a/docs/how-to.md b/docs/how-to.md index e09d83e6b..bf92a077f 100644 --- a/docs/how-to.md +++ b/docs/how-to.md @@ -117,7 +117,7 @@ of gaps) you should override the `series` method. See more details and examples ## Pass the page number -You don't need to explicitly pass the page number to the `pagy` method, because it is pulled in by the `pagy_get_vars` (which is +You don't need to explicitly pass the page number to the `pagy` method, because it is pulled in by the `pagy_get_page` (which is called internally by the `pagy` method). However you can force a `page` number by just passing it to the `pagy` method. For example: @@ -619,7 +619,7 @@ from 301 to 315 for the last page. ## Paginate non-ActiveRecord collections -The `pagy_get_vars` method works out of the box with `ActiveRecord` collections; for other collections (e.g. `mongoid`, etc.) +The `pagy_get_count` method works out of the box with `ActiveRecord` collections; for other collections (e.g. `mongoid`, etc.) you might want to change the `:count_args` default to suite your ORM count method: ```ruby pagy.rb (initializer) diff --git a/gem/lib/pagy/backend.rb b/gem/lib/pagy/backend.rb index cebf2204f..015e944ca 100644 --- a/gem/lib/pagy/backend.rb +++ b/gem/lib/pagy/backend.rb @@ -10,7 +10,10 @@ module Backend # Return Pagy object and paginated results def pagy(collection, **vars) - pagy = Pagy.new(**pagy_get_vars(collection, vars)) + vars[:count] ||= pagy_get_count(collection, vars) + vars[:limit] ||= pagy_get_limit(vars) + vars[:page] ||= pagy_get_page(vars) + pagy = Pagy.new(**vars) [pagy, pagy_get_items(collection, pagy)] end @@ -27,22 +30,14 @@ def pagy_get_items(collection, pagy) end # Override for limit extra - def pagy_get_limit(vars); end + def pagy_get_limit(_vars) + DEFAULT[:limit] + end # Get the page integer from the params # Overridable by the jsonapi extra def pagy_get_page(vars) params[vars[:page_param] || DEFAULT[:page_param]] end - - # Sub-method called only by #pagy: here for easy customization of variables by overriding - # You may need to override the count call for non AR collections - def pagy_get_vars(collection, vars) - vars.tap do |v| - v[:count] ||= pagy_get_count(collection, v) - v[:limit] ||= pagy_get_limit(v) - v[:page] ||= pagy_get_page(v) - end - end end end diff --git a/gem/lib/pagy/extras/arel.rb b/gem/lib/pagy/extras/arel.rb index 3f792dbfc..c804cab71 100644 --- a/gem/lib/pagy/extras/arel.rb +++ b/gem/lib/pagy/extras/arel.rb @@ -8,8 +8,8 @@ module ArelExtra # Return Pagy object and paginated collection/results def pagy_arel(collection, **vars) - pagy = Pagy.new(**pagy_arel_get_vars(collection, vars)) - [pagy, pagy_get_items(collection, pagy)] + vars[:count] ||= pagy_arel_count(collection) + pagy(collection, **vars) end # Count using Arel when grouping @@ -23,12 +23,6 @@ def pagy_arel_count(collection) collection.unscope(:order).limit(1).pluck(sql).first.to_i end end - - # Sub-method called only by #pagy_arel: here for easy customization of variables by overriding - def pagy_arel_get_vars(collection, vars) - vars[:count] ||= pagy_arel_count(collection) - pagy_get_vars(collection, vars) - end end Backend.prepend ArelExtra end diff --git a/gem/lib/pagy/extras/array.rb b/gem/lib/pagy/extras/array.rb index cf672c3da..61097f402 100644 --- a/gem/lib/pagy/extras/array.rb +++ b/gem/lib/pagy/extras/array.rb @@ -8,14 +8,11 @@ module ArrayExtra # Return Pagy object and paginated items def pagy_array(array, **vars) - pagy = Pagy.new(**pagy_array_get_vars(array, vars)) - [pagy, array[pagy.offset, pagy.limit]] - end - - # Sub-method called only by #pagy_array: here for easy customization of variables by overriding - def pagy_array_get_vars(array, vars) + vars[:limit] ||= pagy_get_limit(vars) + vars[:page] ||= pagy_get_page(vars) vars[:count] ||= array.size - pagy_get_vars(array, vars) + pagy = Pagy.new(**vars) + [pagy, array[pagy.offset, pagy.limit]] end end Backend.prepend ArrayExtra diff --git a/gem/lib/pagy/extras/countless.rb b/gem/lib/pagy/extras/countless.rb index d83d05d8b..5c2286843 100644 --- a/gem/lib/pagy/extras/countless.rb +++ b/gem/lib/pagy/extras/countless.rb @@ -12,7 +12,9 @@ module CountlessExtra # Return Pagy object and records def pagy_countless(collection, **vars) - pagy = Countless.new(**pagy_countless_get_vars(collection, vars)) + vars[:limit] ||= pagy_get_limit(vars) + vars[:page] ||= pagy_get_page(vars) + pagy = Countless.new(**vars) [pagy, pagy_countless_get_items(collection, pagy)] end @@ -25,15 +27,6 @@ def pagy_countless_get_items(collection, pagy) pagy.finalize(fetched.size) # finalize the pagy object fetched[0, pagy.limit] # ignore eventual extra item end - - # Sub-method called only by #pagy: here for easy customization of variables by overriding - # You may need to override the count call for non AR collections - def pagy_countless_get_vars(_collection, vars) - vars.tap do |v| - v[:limit] ||= pagy_get_limit(v) - v[:page] ||= pagy_get_page(v) - end - end end Backend.prepend CountlessExtra end diff --git a/gem/lib/pagy/extras/elasticsearch_rails.rb b/gem/lib/pagy/extras/elasticsearch_rails.rb index c92c996fc..5eb9bf8ee 100644 --- a/gem/lib/pagy/extras/elasticsearch_rails.rb +++ b/gem/lib/pagy/extras/elasticsearch_rails.rb @@ -50,13 +50,13 @@ module BackendAddOn # Return Pagy object and records def pagy_elasticsearch_rails(pagy_search_args, **vars) - model, query_or_payload, - options, *called = pagy_search_args - vars = pagy_elasticsearch_rails_get_vars(nil, vars) - options[:size] = vars[:limit] - options[:from] = vars[:limit] * ((vars[:page] || 1) - 1) - response = model.send(DEFAULT[:elasticsearch_rails_search], query_or_payload, **options) - vars[:count] = ElasticsearchRailsExtra.total_count(response) + vars[:page] ||= (pagy_get_page(vars) || 1).to_i + vars[:limit] ||= pagy_get_limit(vars) + model, query_or_payload, options, *called = pagy_search_args + options[:size] = vars[:limit] + options[:from] = vars[:limit] * ((vars[:page] || 1) - 1) + response = model.send(DEFAULT[:elasticsearch_rails_search], query_or_payload, **options) + vars[:count] = ElasticsearchRailsExtra.total_count(response) pagy = ::Pagy.new(**vars) # with :last_page overflow we need to re-run the method in order to get the hits @@ -65,15 +65,6 @@ def pagy_elasticsearch_rails(pagy_search_args, **vars) [pagy, called.empty? ? response : response.send(*called)] end - - # Sub-method called only by #pagy_elasticsearch_rails: here for easy customization of variables by overriding - # the _collection argument is not available when the method is called - def pagy_elasticsearch_rails_get_vars(_collection, vars) - vars.tap do |v| - v[:page] ||= pagy_get_page(v) - v[:limit] ||= pagy_get_limit(v) || DEFAULT[:limit] - end - end end Backend.prepend BackendAddOn end diff --git a/gem/lib/pagy/extras/keyset.rb b/gem/lib/pagy/extras/keyset.rb index 814b22e81..5962c633f 100644 --- a/gem/lib/pagy/extras/keyset.rb +++ b/gem/lib/pagy/extras/keyset.rb @@ -10,18 +10,12 @@ module KeysetExtra # Return Pagy::Keyset object and paginated records def pagy_keyset(set, **vars) - pagy = Keyset.new(set, **pagy_keyset_get_vars(vars)) + vars[:page] ||= pagy_get_page(vars) + vars[:limit] ||= pagy_get_limit(vars) + pagy = Keyset.new(set, **vars) [pagy, pagy.records] end - # Sub-method called only by #pagy_keyset: here for easy customization of variables by overriding - def pagy_keyset_get_vars(vars) - vars.tap do |v| - v[:page] ||= pagy_get_page(v) - v[:limit] ||= pagy_get_limit(v) - end - end - # Return the URL string for the first page def pagy_keyset_first_url(pagy, **vars) pagy_url_for(pagy, nil, **vars) diff --git a/gem/lib/pagy/extras/limit.rb b/gem/lib/pagy/extras/limit.rb index a60d7db2d..ecfc7f70b 100644 --- a/gem/lib/pagy/extras/limit.rb +++ b/gem/lib/pagy/extras/limit.rb @@ -16,8 +16,8 @@ module BackendAddOn # Set the limit variable considering the params and other pagy variables def pagy_get_limit(vars) - return unless vars.key?(:limit_extra) ? vars[:limit_extra] : DEFAULT[:limit_extra] # :limit_extra is false - return unless (limit_count = pagy_get_limit_param(vars)) # no limit from request params + return super unless vars.key?(:limit_extra) ? vars[:limit_extra] : DEFAULT[:limit_extra] # :limit_extra is false + return super unless (limit_count = pagy_get_limit_param(vars)) # no limit from request params vars[:limit] = [limit_count.to_i, vars.key?(:limit_max) ? vars[:limit_max] : DEFAULT[:limit_max]].compact.min end diff --git a/gem/lib/pagy/extras/meilisearch.rb b/gem/lib/pagy/extras/meilisearch.rb index 7fb3eddb7..386eab590 100644 --- a/gem/lib/pagy/extras/meilisearch.rb +++ b/gem/lib/pagy/extras/meilisearch.rb @@ -36,8 +36,9 @@ module BackendAddOn # Return Pagy object and results def pagy_meilisearch(pagy_search_args, **vars) + vars[:page] ||= (pagy_get_page(vars) || 1).to_i + vars[:limit] ||= pagy_get_limit(vars) model, term, options = pagy_search_args - vars = pagy_meilisearch_get_vars(nil, vars) options[:hits_per_page] = vars[:limit] options[:page] = vars[:page] results = model.send(:ms_search, term, options) @@ -50,15 +51,6 @@ def pagy_meilisearch(pagy_search_args, **vars) [pagy, results] end - - # Sub-method called only by #pagy_meilisearch: here for easy customization of variables by overriding. - # The _collection argument is not available when the method is called. - def pagy_meilisearch_get_vars(_collection, vars) - vars.tap do |v| - v[:page] ||= pagy_get_page(v) - v[:limit] ||= pagy_get_limit(v) || DEFAULT[:limit] - end - end end Backend.prepend BackendAddOn end diff --git a/gem/lib/pagy/extras/searchkick.rb b/gem/lib/pagy/extras/searchkick.rb index 9bc6198f9..5f11b37e5 100644 --- a/gem/lib/pagy/extras/searchkick.rb +++ b/gem/lib/pagy/extras/searchkick.rb @@ -38,8 +38,9 @@ module BackendAddOn # Return Pagy object and results def pagy_searchkick(pagy_search_args, **vars) + vars[:page] ||= (pagy_get_page(vars) || 1).to_i + vars[:limit] ||= pagy_get_limit(vars) model, term, options, block, *called = pagy_search_args - vars = pagy_searchkick_get_vars(nil, vars) options[:per_page] = vars[:limit] options[:page] = vars[:page] results = model.send(DEFAULT[:searchkick_search], term, **options, &block) @@ -52,15 +53,6 @@ def pagy_searchkick(pagy_search_args, **vars) [pagy, called.empty? ? results : results.send(*called)] end - - # Sub-method called only by #pagy_searchkick: here for easy customization of variables by overriding - # the _collection argument is not available when the method is called - def pagy_searchkick_get_vars(_collection, vars) - vars.tap do |v| - v[:page] ||= pagy_get_page(v) - v[:limit] ||= pagy_get_limit(v) || DEFAULT[:limit] - end - end end Backend.prepend BackendAddOn end diff --git a/gem/lib/pagy/i18n.rb b/gem/lib/pagy/i18n.rb index 2d2b64cb0..7b64a58fd 100644 --- a/gem/lib/pagy/i18n.rb +++ b/gem/lib/pagy/i18n.rb @@ -118,7 +118,7 @@ module P11n # Stores the i18n DATA structure for each loaded locale # default on the first locale DATA - DATA = Hash.new { |hash, _| hash.first[1] } + DATA = Hash.new { |hash,| hash.first[1] } private diff --git a/test/pagy/backend_test.rb b/test/pagy/backend_test.rb index 995af25df..707b54117 100644 --- a/test/pagy/backend_test.rb +++ b/test/pagy/backend_test.rb @@ -33,13 +33,14 @@ end end - describe '#pagy_get_vars' do + describe '#pagy vars' do before do @collection = MockCollection.new end it 'gets defaults' do vars = {} - merged = app.send :pagy_get_vars, @collection, vars + pagy, = app.send :pagy, @collection, **vars + merged = pagy.vars _(merged.keys).must_include :count _(merged.keys).must_include :page _(merged[:count]).must_equal 1000 @@ -47,7 +48,8 @@ end it 'gets vars' do vars = { page: 2, limit: 10, anchor_string: 'X' } - merged = app.send :pagy_get_vars, @collection, vars + pagy, = app.send :pagy, @collection, **vars + merged = pagy.vars _(merged.keys).must_include :count _(merged.keys).must_include :page _(merged.keys).must_include :limit @@ -60,8 +62,8 @@ it 'works with grouped collections' do collection = MockCollection::Grouped.new((1..1000).to_a) vars = { page: 2, limit: 10, anchor_string: 'X' } - merged = app.send :pagy_get_vars, collection, vars - _(collection.count.size).must_equal 1000 + pagy, = app.send :pagy, collection, **vars + merged = pagy.vars _(merged.keys).must_include :count _(merged.keys).must_include :page _(merged.keys).must_include :limit @@ -72,12 +74,13 @@ _(merged[:anchor_string]).must_equal 'X' end it 'overrides count and page' do - vars = { count: 10, page: 32 } - merged = app.send :pagy_get_vars, @collection, vars + vars = { count: 100, page: 3 } + pagy, = app.send :pagy, @collection, **vars + merged = pagy.vars _(merged.keys).must_include :count - _(merged[:count]).must_equal 10 + _(merged[:count]).must_equal 100 _(merged.keys).must_include :page - _(merged[:page]).must_equal 32 + _(merged[:page]).must_equal 3 end end diff --git a/test/pagy/extras/arel_test.rb b/test/pagy/extras/arel_test.rb index f73f3efa3..7f3a9ea94 100644 --- a/test/pagy/extras/arel_test.rb +++ b/test/pagy/extras/arel_test.rb @@ -35,13 +35,14 @@ end end - describe '#pagy_arel_get_vars' do + describe '#pagy_arel vars' do before do @collection = MockCollection.new end it 'gets defaults' do vars = {} - merged = app.send :pagy_arel_get_vars, @collection, vars + pagy, = app.send :pagy_arel, @collection, **vars + merged = pagy.vars _(merged.keys).must_include :count _(merged.keys).must_include :page _(merged[:count]).must_equal 1000 @@ -49,7 +50,8 @@ end it 'gets vars' do vars = { page: 2, limit: 10, anchor_string: 'X' } - merged = app.send :pagy_arel_get_vars, @collection, vars + pagy, = app.send :pagy_arel, @collection, **vars + merged = pagy.vars _(merged.keys).must_include :count _(merged.keys).must_include :page _(merged.keys).must_include :limit @@ -62,7 +64,8 @@ it 'works with grouped collections' do collection = MockCollection::Grouped.new((1..1000).to_a) vars = { page: 2, limit: 10, anchor_string: 'X' } - merged = app.send :pagy_arel_get_vars, collection, vars + pagy, = app.send :pagy_arel, collection, **vars + merged = pagy.vars _(merged.keys).must_include :count _(merged.keys).must_include :page _(merged.keys).must_include :limit @@ -73,12 +76,13 @@ _(merged[:anchor_string]).must_equal 'X' end it 'overrides count and page' do - vars = { count: 10, page: 32 } - merged = app.send :pagy_arel_get_vars, @collection, vars + vars = { count: 100, page: 3 } + pagy, = app.send :pagy_arel, @collection, **vars + merged = pagy.vars _(merged.keys).must_include :count - _(merged[:count]).must_equal 10 + _(merged[:count]).must_equal 100 _(merged.keys).must_include :page - _(merged[:page]).must_equal 32 + _(merged[:page]).must_equal 3 end end end diff --git a/test/pagy/extras/array_test.rb b/test/pagy/extras/array_test.rb index ea677d7fb..68b4ae9ef 100644 --- a/test/pagy/extras/array_test.rb +++ b/test/pagy/extras/array_test.rb @@ -32,30 +32,4 @@ _(records).must_equal [11, 12, 13, 14, 15, 16, 17, 18, 19, 20] end end - - describe '#pagy_array_get_vars' do - before do - @collection = (1..1000).to_a - end - it 'gets defaults' do - vars = {} - merged = app.send :pagy_array_get_vars, @collection, vars - _(merged.keys).must_include :count - _(merged.keys).must_include :page - _(merged[:count]).must_equal 1000 - _(merged[:page]).must_equal 3 - end - it 'gets vars' do - vars = { page: 2, limit: 10, anchor_string: 'X' } - merged = app.send :pagy_array_get_vars, @collection, vars - _(merged.keys).must_include :count - _(merged.keys).must_include :page - _(merged.keys).must_include :limit - _(merged.keys).must_include :anchor_string - _(merged[:count]).must_equal 1000 - _(merged[:page]).must_equal 2 - _(merged[:limit]).must_equal 10 - _(merged[:anchor_string]).must_equal 'X' - end - end end diff --git a/test/pagy/extras/elasticsearch_rails_test.rb b/test/pagy/extras/elasticsearch_rails_test.rb index 4f84fbb55..b329421fb 100644 --- a/test/pagy/extras/elasticsearch_rails_test.rb +++ b/test/pagy/extras/elasticsearch_rails_test.rb @@ -125,28 +125,6 @@ _(records).must_rematch :records end end - - describe '#pagy_elasticsearch_rails_get_vars' do - it 'gets defaults' do - vars = {} - merged = app.send :pagy_elasticsearch_rails_get_vars, nil, vars - _(merged.keys).must_include :page - _(merged.keys).must_include :limit - _(merged[:page]).must_equal 3 - _(merged[:limit]).must_equal 20 - end - it 'gets vars' do - vars = { page: 2, limit: 10, anchor_string: 'X' } - merged = app.send :pagy_elasticsearch_rails_get_vars, nil, vars - _(merged.keys).must_include :page - _(merged.keys).must_include :limit - _(merged.keys).must_include :anchor_string - _(merged[:page]).must_equal 2 - _(merged[:limit]).must_equal 10 - _(merged[:anchor_string]).must_equal 'X' - end - end - describe 'Pagy.new_from_elasticsearch_rails' do it 'paginates response with defaults' do response = MockElasticsearchRails::Model.search('a') diff --git a/test/pagy/extras/limit_test.rb b/test/pagy/extras/limit_test.rb index 8723332ba..d072f9e7b 100644 --- a/test/pagy/extras/limit_test.rb +++ b/test/pagy/extras/limit_test.rb @@ -41,18 +41,6 @@ def test_limit_vars_params(limit, vars, params) before do @collection = MockCollection.new end - it 'uses the defaults' do - vars = {} - app = MockApp.new - %i[pagy_elasticsearch_rails_get_vars pagy_searchkick_get_vars pagy_meilisearch_get_vars].each do |method| - merged = app.send method, nil, vars - _(merged[:limit]).must_equal 20 - end - %i[pagy_get_vars pagy_array_get_vars pagy_arel_get_vars].each do |method| - merged = app.send method, @collection, {} - _(merged[:limit]).must_be_nil - end - end it 'uses the vars' do limit = 15 vars = { limit: limit } # force limit diff --git a/test/pagy/extras/meilisearch_test.rb b/test/pagy/extras/meilisearch_test.rb index 63401f198..85daeaa3f 100644 --- a/test/pagy/extras/meilisearch_test.rb +++ b/test/pagy/extras/meilisearch_test.rb @@ -59,28 +59,6 @@ _(results.to_a).must_rematch :results end end - - describe '#pagy_meilisearch_get_vars' do - it 'gets defaults' do - vars = {} - merged = app.send :pagy_meilisearch_get_vars, nil, vars - _(merged.keys).must_include :page - _(merged.keys).must_include :limit - _(merged[:page]).must_equal 3 - _(merged[:limit]).must_equal 20 - end - it 'gets vars' do - vars = { page: 2, limit: 10, anchor_string: 'X' } - merged = app.send :pagy_meilisearch_get_vars, nil, vars - _(merged.keys).must_include :page - _(merged.keys).must_include :limit - _(merged.keys).must_include :anchor_string - _(merged[:page]).must_equal 2 - _(merged[:limit]).must_equal 10 - _(merged[:anchor_string]).must_equal 'X' - end - end - describe 'Pagy.new_from_meilisearch' do it 'paginates results with defaults' do results = MockMeilisearch::Model.ms_search('a') diff --git a/test/pagy/extras/searchkick_test.rb b/test/pagy/extras/searchkick_test.rb index 6fd29df28..dd77f13e2 100644 --- a/test/pagy/extras/searchkick_test.rb +++ b/test/pagy/extras/searchkick_test.rb @@ -85,28 +85,6 @@ _(results).must_rematch :results end end - - describe '#pagy_searchkick_get_vars' do - it 'gets defaults' do - vars = {} - merged = app.send :pagy_searchkick_get_vars, nil, vars - _(merged.keys).must_include :page - _(merged.keys).must_include :limit - _(merged[:page]).must_equal 3 - _(merged[:limit]).must_equal 20 - end - it 'gets vars' do - vars = { page: 2, limit: 10, anchor_string: 'X' } - merged = app.send :pagy_searchkick_get_vars, nil, vars - _(merged.keys).must_include :page - _(merged.keys).must_include :limit - _(merged.keys).must_include :anchor_string - _(merged[:page]).must_equal 2 - _(merged[:limit]).must_equal 10 - _(merged[:anchor_string]).must_equal 'X' - end - end - describe 'Pagy.new_from_searchkick' do it 'paginates results with defaults' do results = MockSearchkick::Model.search('a') From ef7c0523e6ec7dd509e2d46cdf5b9eb4a35c49ec Mon Sep 17 00:00:00 2001 From: Domizio Demichelis Date: Fri, 26 Jul 2024 23:20:43 +0700 Subject: [PATCH 2/8] Update gems --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 317b8b690..42248f4ae 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -91,7 +91,7 @@ GEM connection_pool (2.4.1) crass (1.0.6) date (3.3.4) - docile (1.4.0) + docile (1.4.1) domain_name (0.6.20240107) drb (2.2.1) erubi (1.13.0) @@ -169,7 +169,7 @@ GEM racc psych (5.1.2) stringio - public_suffix (6.0.0) + public_suffix (6.0.1) puma (6.4.2) nio4r (~> 2.0) racc (1.8.0) From 8c21069cf8da96ea274db630437498762ebe6013 Mon Sep 17 00:00:00 2001 From: Domizio Demichelis Date: Sat, 27 Jul 2024 09:37:35 +0700 Subject: [PATCH 3/8] Fix jsonapi with keyset --- gem/lib/pagy/extras/jsonapi.rb | 9 +++------ test/pagy/extras/jsonapi_test.rb.yaml | 4 ++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/gem/lib/pagy/extras/jsonapi.rb b/gem/lib/pagy/extras/jsonapi.rb index 418753110..5dd07e9fb 100644 --- a/gem/lib/pagy/extras/jsonapi.rb +++ b/gem/lib/pagy/extras/jsonapi.rb @@ -47,7 +47,7 @@ def pagy_skip_jsonapi?(vars) # Override the Backend method def pagy_get_page(vars) return super if pagy_skip_jsonapi?(vars) - return if params[:page].nil? + return unless params[:page] params[:page][vars[:page_param] || DEFAULT[:page_param]] end @@ -61,7 +61,7 @@ module LimitExtraOverride # Override the LimitExtra::Backend method def pagy_get_limit_param(vars) return super if pagy_skip_jsonapi?(vars) - return if params[:page].nil? + return unless params[:page] params[:page][vars[:limit_param] || DEFAULT[:limit_param]] end @@ -77,11 +77,8 @@ def pagy_set_query_params(page, vars, query_params) return super unless vars[:jsonapi] query_params['page'] ||= {} - query_params['page'][vars[:page_param].to_s] = page if page + query_params['page'][vars[:page_param].to_s] = page query_params['page'][vars[:limit_param].to_s] = vars[:limit] if vars[:limit_extra] - # :nocov: - query_params.delete(:page) if query_params['page'].empty? - # :nocov: end end UrlHelpers.prepend UrlHelperOverride diff --git a/test/pagy/extras/jsonapi_test.rb.yaml b/test/pagy/extras/jsonapi_test.rb.yaml index 421e14942..5ada83907 100644 --- a/test/pagy/extras/jsonapi_test.rb.yaml +++ b/test/pagy/extras/jsonapi_test.rb.yaml @@ -1,13 +1,13 @@ --- pagy/extras/jsonapi___pagy_jsonapi_links_(keyset)_test_0002_sets_the_next_value_to_null_when_the_link_is_unavailable: :keyset_result: - :first: "/foo?page%5Bsize%5D=50" + :first: "/foo?page%5Bsize%5D=50&page%5Blatest%5D" :last: :prev: :next: pagy/extras/jsonapi___pagy_jsonapi_links_(keyset)_test_0001_returns_the_ordered_links: :keyset_result: - :first: "/foo?page%5Blatest%5D=eyJpZCI6MTB9&page%5Bsize%5D=10" + :first: "/foo?page%5Blatest%5D&page%5Bsize%5D=10" :last: :prev: :next: "/foo?page%5Blatest%5D=eyJpZCI6MjB9&page%5Bsize%5D=10" From b99bcced43222a76ce693c3f333ee1a47ec0f119 Mon Sep 17 00:00:00 2001 From: Domizio Demichelis Date: Sat, 27 Jul 2024 10:30:22 +0700 Subject: [PATCH 4/8] Update js modules --- bun.lockb | Bin 161143 -> 161143 bytes package.json | 14 +++++++------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bun.lockb b/bun.lockb index 31893769612e953672875c8c0ce4f7ffd611613c..14e0364b230bb13073b1a00efb65093ee684c977 100755 GIT binary patch delta 3324 zcmcJRdpwls9>Cw{HG|P0iQMm@l?kzf$hc-g6HC}iSCQNmDU~SI+Ae!u+tbz-DxqCk zhDNs1P2@lRRHRX<)ejF(x{f4_lq}Pb3ICcTh?xYD8Y)W=aOrgi;^c1vyW=K*n>@O) zGNRW!mZYLU#`)#Rosh=UlJgxLBDseOlkCuRcr8 zQGxVo-)rb7^M)_%nmt>Zvi7qUnrhao(F$d1%@)gWi7b%FfsayXYE#enm}oCal*j`6 z}JiRBNzU1VKoeX~?pw zBrBxEML&SWg&YNO`_JLXKQ^S>Zvl%hu2y2eW!?j8DP?Z7h%yaeQxlrj!tj8Z2GoSV zDb=OH5*8+HnB|M0(VuQ`~Ofj3iG6S zrCF9GGajV%N3)hZ_j_J@`T0e&bKjMFC9L`(GC@koYpho<(sDO^U7S9FiNy98SM#**u@K9X}8K};q9P^;U?#+ zTkec9if8Sc+iVi0G}i1qM7D3VG*3AaP`uH)OF6YcG*0>4P}_51;6zGTPTzs>{F>sD zs+xZWFLK$CHMpz)dRgAAh&Tk>Lzt>=12T7zRqm?hQs1nUtc?L?UXV9VxMx$cVrm#4yJSWO?&AnurIP+E@l6R$M9El6hZXF8D6t zsI>oCw#BqP?wP*FOWp3rqkXpO9$MYd8oVhf<@|+5tceR=7RsbrY01&VJFherDIp6v z^$^3T{GDBdRC)D@z-NV?wr(cY_maLT>oTDn@5S=0S}(u4l}>mljudY2m?5yw8nb&f z?!MV?@Rx@VWIL3*%9dmduX&bLr__{ux5mQnK10OP`(xLcHSwBRzctGocq1IS_md9q z<~28#)2T^*2eXlLWR^A(n7VF@`klP!^vBNea~IM*v+H(@C4}Ey(mZwgQG@@(&GX)$ zGv|deW>&ZFdPKQ+%26EyYTjmb`C${R`;MpQ=LgRXm|D5N;fB^|*5l> zUvF(u{nA90#d_XgoAkEcVLab<(E3<)8hPw!hGFT%w1euPa)$z`6NB;;bJz<#rdT6^ zl;=<=6*b~Ty&jUMLZ5n}9?E$zkSZ9K_qKc!EmJakkIG2Z_NqUI^k1|I$?J;jBPQ8V zHW_uh3-g9bEmRxk^=)*%lk%Eab0FNn?~+4IccbF!^FJ<|pXN|It#KdaI~+&_J(Z`* zp>aQjo(58~Bl6zTD-`ku-XcXtReQk2N|lkK&y9+jj?L8IKFqeb`EF%S?s)L>}L5cWKKDvZ@ zMRo;9is{3Ia4IkW^Z~s91Ly&C0eH$1YXCO@t~vyL#pwpRfX6@xKu>1}bl~J-v`D@a zR2@JIc!E(eQkJKy(5w4_-*IjsnsdAuu`LHBZn$O<3xIauDL@aU2#f*rP@{l&DC}O0 z43+3A|It?jeXE$r7Tc8}TV#df%aA8nKbN6}$QqB8p*c)0$AV*lXOyG8;5l55)CAyx zZNbT?!3oGL+nE$QZ`6fET#ltUvI-*V5ZUybQ)z&?ZQoxJ`U}^CNNs(?kjC;5&c_JO z`4>{fIkku-Qof9)*iujh&%BK+#Y)$0G)Jt2fP%PxCd=Zi+lc?)DPqrf&EImD-a#dQ z=0cT_X86IFS0gRjDe|sHcI2O72E7X$_Y!I1>osV>|1M};i&Vss#kG<_r}Y%UW^~v% z=L*umplj`^@SC~~z zmQ=vAoJo7U!=03aI^r>)t1J#tAZO!N7xEYuo5k*=E*y;|j&>&Z<7_u5?e9h!;1YHC apgW1c7iEO?O-Vhh8$q%}Hk(No_P+t!b!Gf3Lh$_xatM>r`U~!nC83JJKz zj$H>n`i`PCUM7)YrS+=e1CPh+{(P!!X5%;mEoB#V>{*{O-bL}Ih*zM#Gsj!BKg z+&!Qmd8+~}SIoT$N(@SUI1{^5lmjSbn#mM{VltIzsfn1I0LmT|m+o6H=H`9Qgeth% zo$gxbN?R>ag_YRL!k6&O>0&2lNnF{fgkUW{3a$`DQ3_zg!7|ra%eW%ohQY1@%LN-h zlE+x4U&2T{k@3q`?k-pTKa^cdBpgZq?QrcQ+eNNrc^_tPczWirJbg0%AroFi(U)Ft8U@r00_l@*@7uC(m zh!FbwY%x7!69dGemfpWl>Mi*`-$go3cKT{2M{;y`Yq|Mlq?R8gr=8vkT zBc5?lN3SS0?j2`dJmu{LXUQMui`_zVX2e`ze!ZhlAbIQ>mlb)vPP&%Gj!)~>JUm~> zch0ITw<&vKlM#%J_kTeSCS959p^=|ra5a0+%%<3s_x;$Jcj*RiaCdNTOY; zV>9C!cDAu^MB7Oc+<1;=Dq!0nx1|sPwsQxt=^G#%yH3p+m>6V-pIqam3H2t zo)zlCY3`Uua}kejc+U6Ix81DqaiXDM2YX0o zMQ;_qxLLTOs#1KemR#v`n)o>U<}Ys=sCNPCLwhCS$@}9w3V58L{!_Q_ubT5LM=lX4 zjM=CL+V6!w{X?gkm%B+P0g`$ zpG?2JEMUJjeK)ne=4^04+mwUaE^2cOgxeR7DcVE_b^FtEyFzI1PEY!6ml}Pd(-XDP z=%qiM`$CNldFhGT=^{`8FV$%F3s3K7W1p9@(P1^koWvpZxl4O57!7z$kZN-anx6aG z=hY0Dy#1B7&$nN`w_MoH7Tp& z>C$dBiE&@e%<0IyD$e4z^{@D#m9!*hNb^o;bMs$==PKRbM0OnPD%zF5a8hZ{(fN<} z=_Zm=ELhfZ|I@XXYf^Hz{7@!i_tc3b2anvzE?2dAVHfS1yVo@NoUg{zMvINrw_b(! zS8Q>~cl1vEO}4FJ0ty&ByztV%j7=78TjX~{MHRPo*PV1Jel}NbVuHfPkwRCL2`_9G zd1Z}e3^$C0D4uD^>t~{if#aBeD|0dLappY@$2|4Th%b!UXL;E%q=MLMq0N<7A4mNd z%^_ERLE6Yme)kuYg(9P%%UXar=~IAIfO(y71a?C^4cGz10}>z!*bHn1HUi%Q>wyFY z=o14-fjD3h_!a}qu@ZtvV>Y^{wG*@(;0`1L8z@q60vU3cqb3rO))S~iZ5R0A!-NU| z7LpSu5m9DVunush$m|^Cj^fF8Ip_>}CU?w53T(1H7x7Gs0L?%n&;T&sLt6nhzyg>9uL*!}rQwpTU`+vI08Zgy ze>>Qxr0+BuPwG!2C7Vvrwm>s54Zy%lfT^hg^a9NIJpeOC1DRET#%nTVMpwa1vqhd* zfXdlOOdN~R3}i!Mi_u(A7mAS`vLn64NS{4j@AW$?KA)?=qv0SSJ zeNa_^5`UhzP^w6$eKu>KzVh>p;dwOSTG_*GRu$;d{vXJ%m{vu z;bGd=Az!(|BP2$owhlRvlse>17Cb^a@{Gr*RRNOako;i$@WupSywg}6_CpjOwlO|V z7!(sBB+(f24+}7haLw=z#gQO6F2HLgwx^^ zV?yGD%x{GBx#Ds1b^(6F`maP5(YD0;W1VD`CDsIo-z;oJV%S)PY*fO!q|6e#B0Kq8 zODr`Q`GKyJU{6@=c?q6JHoL>EU=}u0guP`JLV9OGuk{>k#Iz<8OAnZC0~?Pg9d6iy zEa1Xzq8t92BpYHS5~z-Ki29fKdvaU{8r4MY7lfo5Mc@;#P8SthFFTJS-q)k(euYh`{cu{{m1HfI$EN diff --git a/package.json b/package.json index 4bf38b5fb..0f2e1b83a 100644 --- a/package.json +++ b/package.json @@ -5,21 +5,21 @@ "type": "module", "devDependencies": { "@cypress/snapshot": "^2.1.7", - "@types/node": "20.14.11", + "@types/node": "20.14.12", "cypress": "13.13.1", "cypress-html-validate": "6.1.0", - "eslint-plugin-cypress": "3.3.0", - "eslint-plugin-promise": "6.5.1", + "eslint-plugin-cypress": "3.4.0", + "eslint-plugin-promise": "7.0.0", "html-validate": "8.21.0", "start-server-and-test": "2.0.4", - "@eslint/js": "9.7.0", + "@eslint/js": "9.8.0", "@types/eslint__js": "^8.42.3", - "eslint": "9.7.0", + "eslint": "9.8.0", "eslint-plugin-align-assignments": "^1.1.2", "retypeapp-linux-x64": "3.5.0", "retypeapp-darwin-x64": "3.5.0", - "typescript": "5.5.3", - "typescript-eslint": "7.16.1" + "typescript": "5.5.4", + "typescript-eslint": "7.17.0" }, "workspaces": ["e2e"] } From 4b8e98ad6286b5ffc2f7a41ce7e56fb91b12c159 Mon Sep 17 00:00:00 2001 From: Domizio Demichelis Date: Sat, 27 Jul 2024 11:59:08 +0700 Subject: [PATCH 5/8] Improve pagy_get_page with force_integer option --- gem/lib/pagy/backend.rb | 5 +++-- gem/lib/pagy/extras/elasticsearch_rails.rb | 2 +- gem/lib/pagy/extras/jsonapi.rb | 8 ++++---- gem/lib/pagy/extras/keyset.rb | 2 +- gem/lib/pagy/extras/meilisearch.rb | 2 +- gem/lib/pagy/extras/searchkick.rb | 2 +- 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/gem/lib/pagy/backend.rb b/gem/lib/pagy/backend.rb index 015e944ca..38897ee99 100644 --- a/gem/lib/pagy/backend.rb +++ b/gem/lib/pagy/backend.rb @@ -36,8 +36,9 @@ def pagy_get_limit(_vars) # Get the page integer from the params # Overridable by the jsonapi extra - def pagy_get_page(vars) - params[vars[:page_param] || DEFAULT[:page_param]] + def pagy_get_page(vars, force_integer: true) + page = params[vars[:page_param] || DEFAULT[:page_param]] + force_integer ? (page || 1).to_i : page end end end diff --git a/gem/lib/pagy/extras/elasticsearch_rails.rb b/gem/lib/pagy/extras/elasticsearch_rails.rb index 5eb9bf8ee..2a7e66834 100644 --- a/gem/lib/pagy/extras/elasticsearch_rails.rb +++ b/gem/lib/pagy/extras/elasticsearch_rails.rb @@ -50,7 +50,7 @@ module BackendAddOn # Return Pagy object and records def pagy_elasticsearch_rails(pagy_search_args, **vars) - vars[:page] ||= (pagy_get_page(vars) || 1).to_i + vars[:page] ||= pagy_get_page(vars) vars[:limit] ||= pagy_get_limit(vars) model, query_or_payload, options, *called = pagy_search_args options[:size] = vars[:limit] diff --git a/gem/lib/pagy/extras/jsonapi.rb b/gem/lib/pagy/extras/jsonapi.rb index 5dd07e9fb..2f2dfc161 100644 --- a/gem/lib/pagy/extras/jsonapi.rb +++ b/gem/lib/pagy/extras/jsonapi.rb @@ -45,11 +45,11 @@ def pagy_skip_jsonapi?(vars) end # Override the Backend method - def pagy_get_page(vars) - return super if pagy_skip_jsonapi?(vars) - return unless params[:page] + def pagy_get_page(vars, force_integer: true) + return super if pagy_skip_jsonapi?(vars) || params[:page].nil? - params[:page][vars[:page_param] || DEFAULT[:page_param]] + page = params[:page][vars[:page_param] || DEFAULT[:page_param]] + force_integer ? (page || 1).to_i : page end end Backend.prepend BackendOverride diff --git a/gem/lib/pagy/extras/keyset.rb b/gem/lib/pagy/extras/keyset.rb index 5962c633f..475f293d6 100644 --- a/gem/lib/pagy/extras/keyset.rb +++ b/gem/lib/pagy/extras/keyset.rb @@ -10,7 +10,7 @@ module KeysetExtra # Return Pagy::Keyset object and paginated records def pagy_keyset(set, **vars) - vars[:page] ||= pagy_get_page(vars) + vars[:page] ||= pagy_get_page(vars, force_integer: false) # allow nil vars[:limit] ||= pagy_get_limit(vars) pagy = Keyset.new(set, **vars) [pagy, pagy.records] diff --git a/gem/lib/pagy/extras/meilisearch.rb b/gem/lib/pagy/extras/meilisearch.rb index 386eab590..cddfcfec3 100644 --- a/gem/lib/pagy/extras/meilisearch.rb +++ b/gem/lib/pagy/extras/meilisearch.rb @@ -36,7 +36,7 @@ module BackendAddOn # Return Pagy object and results def pagy_meilisearch(pagy_search_args, **vars) - vars[:page] ||= (pagy_get_page(vars) || 1).to_i + vars[:page] ||= pagy_get_page(vars) vars[:limit] ||= pagy_get_limit(vars) model, term, options = pagy_search_args options[:hits_per_page] = vars[:limit] diff --git a/gem/lib/pagy/extras/searchkick.rb b/gem/lib/pagy/extras/searchkick.rb index 5f11b37e5..02248a826 100644 --- a/gem/lib/pagy/extras/searchkick.rb +++ b/gem/lib/pagy/extras/searchkick.rb @@ -38,7 +38,7 @@ module BackendAddOn # Return Pagy object and results def pagy_searchkick(pagy_search_args, **vars) - vars[:page] ||= (pagy_get_page(vars) || 1).to_i + vars[:page] ||= pagy_get_page(vars) vars[:limit] ||= pagy_get_limit(vars) model, term, options, block, *called = pagy_search_args options[:per_page] = vars[:limit] From 830e90814ffb0faa0bef6b85615a6156271cbb94 Mon Sep 17 00:00:00 2001 From: Domizio Demichelis Date: Sat, 27 Jul 2024 12:20:09 +0700 Subject: [PATCH 6/8] Replace shell based bump script with bump.rb script --- .idea/runConfigurations/Bump_Version.xml | 8 +- README.md | 6 +- scripts/bump | 129 ----------------------- scripts/bump.rb | 103 ++++++++++++++++++ scripts/scripty.rb | 58 ++++++++++ scripts/update_top100.rb | 12 +-- test/pagy/version_test.rb | 41 +++++++ test/pagy_test.rb | 38 ------- 8 files changed, 213 insertions(+), 182 deletions(-) delete mode 100755 scripts/bump create mode 100755 scripts/bump.rb create mode 100644 scripts/scripty.rb create mode 100644 test/pagy/version_test.rb diff --git a/.idea/runConfigurations/Bump_Version.xml b/.idea/runConfigurations/Bump_Version.xml index d57dc4db9..466ba5cac 100644 --- a/.idea/runConfigurations/Bump_Version.xml +++ b/.idea/runConfigurations/Bump_Version.xml @@ -1,16 +1,16 @@ - diff --git a/README.md b/README.md index 07b085592..9e7c1b9ef 100644 --- a/README.md +++ b/README.md @@ -280,9 +280,9 @@ See also the [How To Page](https://ddnexus.github.io/pagy/docs/how-to) ## Top 💯 Contributors - -[](https://github.com/ddnexus/pagy/commits?author=ddnexus)[](https://github.com/ddnexus/pagy/commits?author=benkoshy)[](https://github.com/ddnexus/pagy/commits?author=grosser)[](https://github.com/ddnexus/pagy/commits?author=Earlopain)[](https://github.com/ddnexus/pagy/commits?author=workgena)[](https://github.com/ddnexus/pagy/commits?author=espen)[](https://github.com/ddnexus/pagy/commits?author=enzinia)[](https://github.com/ddnexus/pagy/commits?author=sunny)[](https://github.com/ddnexus/pagy/commits?author=molfar)[](https://github.com/ddnexus/pagy/commits?author=bquorning)[](https://github.com/ddnexus/pagy/commits?author=djpremier)[](https://github.com/ddnexus/pagy/commits?author=747)[](https://github.com/ddnexus/pagy/commits?author=tersor)[](https://github.com/ddnexus/pagy/commits?author=thomasklemm)[](https://github.com/ddnexus/pagy/commits?author=gamafranco)[](https://github.com/ddnexus/pagy/commits?author=tiagotex)[](https://github.com/ddnexus/pagy/commits?author=wimdavies)[](https://github.com/ddnexus/pagy/commits?author=renshuki)[](https://github.com/ddnexus/pagy/commits?author=berniechiu)[](https://github.com/ddnexus/pagy/commits?author=ashmaroli)[](https://github.com/ddnexus/pagy/commits?author=cseelus)[](https://github.com/ddnexus/pagy/commits?author=sabljak)[](https://github.com/ddnexus/pagy/commits?author=petergoldstein)[](https://github.com/ddnexus/pagy/commits?author=rainerborene)[](https://github.com/ddnexus/pagy/commits?author=rbngzlv)[](https://github.com/ddnexus/pagy/commits?author=simonneutert)[](https://github.com/ddnexus/pagy/commits?author=sliminas)[](https://github.com/ddnexus/pagy/commits?author=serghost)[](https://github.com/ddnexus/pagy/commits?author=Tolchi)[](https://github.com/ddnexus/pagy/commits?author=rogermarlow)[](https://github.com/ddnexus/pagy/commits?author=yenshirak)[](https://github.com/ddnexus/pagy/commits?author=rafaelmontas)[](https://github.com/ddnexus/pagy/commits?author=rafaeelaudibert)[](https://github.com/ddnexus/pagy/commits?author=pedrocarmona)[](https://github.com/ddnexus/pagy/commits?author=olleolleolle)[](https://github.com/ddnexus/pagy/commits?author=okuramasafumi)[](https://github.com/ddnexus/pagy/commits?author=WilliamHorel)[](https://github.com/ddnexus/pagy/commits?author=woller)[](https://github.com/ddnexus/pagy/commits?author=sk8higher)[](https://github.com/ddnexus/pagy/commits?author=muhammadnawzad)[](https://github.com/ddnexus/pagy/commits?author=ronald)[](https://github.com/ddnexus/pagy/commits?author=achmiral)[](https://github.com/ddnexus/pagy/commits?author=mauro-ni)[](https://github.com/ddnexus/pagy/commits?author=borama)[](https://github.com/ddnexus/pagy/commits?author=creativetags)[](https://github.com/ddnexus/pagy/commits?author=mcary)[](https://github.com/ddnexus/pagy/commits?author=marckohlbrugge)[](https://github.com/ddnexus/pagy/commits?author=tulak)[](https://github.com/ddnexus/pagy/commits?author=artplan1)[](https://github.com/ddnexus/pagy/commits?author=AngelGuerra)[](https://github.com/ddnexus/pagy/commits?author=tr4b4nt)[](https://github.com/ddnexus/pagy/commits?author=tiejianluo)[](https://github.com/ddnexus/pagy/commits?author=szTheory)[](https://github.com/ddnexus/pagy/commits?author=smoothdvd)[](https://github.com/ddnexus/pagy/commits?author=rhodes-david)[](https://github.com/ddnexus/pagy/commits?author=radinreth)[](https://github.com/ddnexus/pagy/commits?author=okliv)[](https://github.com/ddnexus/pagy/commits?author=nedimdz)[](https://github.com/ddnexus/pagy/commits?author=msdundar)[](https://github.com/ddnexus/pagy/commits?author=m-abdurrehman)[](https://github.com/ddnexus/pagy/commits?author=dwieringa)[](https://github.com/ddnexus/pagy/commits?author=jyuvaraj03)[](https://github.com/ddnexus/pagy/commits?author=YutoYasunaga)[](https://github.com/ddnexus/pagy/commits?author=iamyujinwon)[](https://github.com/ddnexus/pagy/commits?author=yhk1038)[](https://github.com/ddnexus/pagy/commits?author=ya-s-u)[](https://github.com/ddnexus/pagy/commits?author=yshmarov)[](https://github.com/ddnexus/pagy/commits?author=thattimc)[](https://github.com/ddnexus/pagy/commits?author=thomaschauffour)[](https://github.com/ddnexus/pagy/commits?author=snkashis)[](https://github.com/ddnexus/pagy/commits?author=Federico-G)[](https://github.com/ddnexus/pagy/commits?author=egimenos)[](https://github.com/ddnexus/pagy/commits?author=elliotlarson)[](https://github.com/ddnexus/pagy/commits?author=hungdiep97)[](https://github.com/ddnexus/pagy/commits?author=davidwessman)[](https://github.com/ddnexus/pagy/commits?author=david-a-wheeler)[](https://github.com/ddnexus/pagy/commits?author=daniel-rikowski)[](https://github.com/ddnexus/pagy/commits?author=connie-feng)[](https://github.com/ddnexus/pagy/commits?author=MrMoins)[](https://github.com/ddnexus/pagy/commits?author=excid3)[](https://github.com/ddnexus/pagy/commits?author=cellvinchung)[](https://github.com/ddnexus/pagy/commits?author=brunoocasali)[](https://github.com/ddnexus/pagy/commits?author=BrandonKlotz)[](https://github.com/ddnexus/pagy/commits?author=Atul9)[](https://github.com/ddnexus/pagy/commits?author=amenon)[](https://github.com/ddnexus/pagy/commits?author=artinboghosian)[](https://github.com/ddnexus/pagy/commits?author=antonzaharia)[](https://github.com/ddnexus/pagy/commits?author=PyrinAndrii)[](https://github.com/ddnexus/pagy/commits?author=andrew)[](https://github.com/ddnexus/pagy/commits?author=AliOsm)[](https://github.com/ddnexus/pagy/commits?author=AbelToy)[](https://github.com/ddnexus/pagy/commits?author=fluser)[](https://github.com/ddnexus/pagy/commits?author=maful)[](https://github.com/ddnexus/pagy/commits?author=loed-idzinga)[](https://github.com/ddnexus/pagy/commits?author=epeirce)[](https://github.com/ddnexus/pagy/commits?author=kobusjoubert)[](https://github.com/ddnexus/pagy/commits?author=KevinColemanInc)[](https://github.com/ddnexus/pagy/commits?author=neontuna)[](https://github.com/ddnexus/pagy/commits?author=xuanxu)[](https://github.com/ddnexus/pagy/commits?author=jpgarritano) - + +[](https://github.com/ddnexus/pagy/commits?author=ddnexus)[](https://github.com/ddnexus/pagy/commits?author=benkoshy)[](https://github.com/ddnexus/pagy/commits?author=grosser)[](https://github.com/ddnexus/pagy/commits?author=Earlopain)[](https://github.com/ddnexus/pagy/commits?author=workgena)[](https://github.com/ddnexus/pagy/commits?author=espen)[](https://github.com/ddnexus/pagy/commits?author=enzinia)[](https://github.com/ddnexus/pagy/commits?author=sunny)[](https://github.com/ddnexus/pagy/commits?author=molfar)[](https://github.com/ddnexus/pagy/commits?author=bquorning)[](https://github.com/ddnexus/pagy/commits?author=djpremier)[](https://github.com/ddnexus/pagy/commits?author=747)[](https://github.com/ddnexus/pagy/commits?author=tersor)[](https://github.com/ddnexus/pagy/commits?author=thomasklemm)[](https://github.com/ddnexus/pagy/commits?author=gamafranco)[](https://github.com/ddnexus/pagy/commits?author=tiagotex)[](https://github.com/ddnexus/pagy/commits?author=wimdavies)[](https://github.com/ddnexus/pagy/commits?author=renshuki)[](https://github.com/ddnexus/pagy/commits?author=berniechiu)[](https://github.com/ddnexus/pagy/commits?author=ashmaroli)[](https://github.com/ddnexus/pagy/commits?author=cseelus)[](https://github.com/ddnexus/pagy/commits?author=sabljak)[](https://github.com/ddnexus/pagy/commits?author=petergoldstein)[](https://github.com/ddnexus/pagy/commits?author=rainerborene)[](https://github.com/ddnexus/pagy/commits?author=rbngzlv)[](https://github.com/ddnexus/pagy/commits?author=simonneutert)[](https://github.com/ddnexus/pagy/commits?author=sliminas)[](https://github.com/ddnexus/pagy/commits?author=serghost)[](https://github.com/ddnexus/pagy/commits?author=Tolchi)[](https://github.com/ddnexus/pagy/commits?author=rogermarlow)[](https://github.com/ddnexus/pagy/commits?author=yenshirak)[](https://github.com/ddnexus/pagy/commits?author=rafaelmontas)[](https://github.com/ddnexus/pagy/commits?author=rafaeelaudibert)[](https://github.com/ddnexus/pagy/commits?author=pedrocarmona)[](https://github.com/ddnexus/pagy/commits?author=olleolleolle)[](https://github.com/ddnexus/pagy/commits?author=okuramasafumi)[](https://github.com/ddnexus/pagy/commits?author=WilliamHorel)[](https://github.com/ddnexus/pagy/commits?author=woller)[](https://github.com/ddnexus/pagy/commits?author=sk8higher)[](https://github.com/ddnexus/pagy/commits?author=muhammadnawzad)[](https://github.com/ddnexus/pagy/commits?author=ronald)[](https://github.com/ddnexus/pagy/commits?author=achmiral)[](https://github.com/ddnexus/pagy/commits?author=mauro-ni)[](https://github.com/ddnexus/pagy/commits?author=borama)[](https://github.com/ddnexus/pagy/commits?author=creativetags)[](https://github.com/ddnexus/pagy/commits?author=mcary)[](https://github.com/ddnexus/pagy/commits?author=marckohlbrugge)[](https://github.com/ddnexus/pagy/commits?author=tulak)[](https://github.com/ddnexus/pagy/commits?author=artplan1)[](https://github.com/ddnexus/pagy/commits?author=AngelGuerra)[](https://github.com/ddnexus/pagy/commits?author=tr4b4nt)[](https://github.com/ddnexus/pagy/commits?author=tiejianluo)[](https://github.com/ddnexus/pagy/commits?author=szTheory)[](https://github.com/ddnexus/pagy/commits?author=smoothdvd)[](https://github.com/ddnexus/pagy/commits?author=rhodes-david)[](https://github.com/ddnexus/pagy/commits?author=radinreth)[](https://github.com/ddnexus/pagy/commits?author=okliv)[](https://github.com/ddnexus/pagy/commits?author=nedimdz)[](https://github.com/ddnexus/pagy/commits?author=msdundar)[](https://github.com/ddnexus/pagy/commits?author=m-abdurrehman)[](https://github.com/ddnexus/pagy/commits?author=dwieringa)[](https://github.com/ddnexus/pagy/commits?author=jyuvaraj03)[](https://github.com/ddnexus/pagy/commits?author=YutoYasunaga)[](https://github.com/ddnexus/pagy/commits?author=iamyujinwon)[](https://github.com/ddnexus/pagy/commits?author=yhk1038)[](https://github.com/ddnexus/pagy/commits?author=ya-s-u)[](https://github.com/ddnexus/pagy/commits?author=yshmarov)[](https://github.com/ddnexus/pagy/commits?author=thattimc)[](https://github.com/ddnexus/pagy/commits?author=thomaschauffour)[](https://github.com/ddnexus/pagy/commits?author=snkashis)[](https://github.com/ddnexus/pagy/commits?author=Federico-G)[](https://github.com/ddnexus/pagy/commits?author=egimenos)[](https://github.com/ddnexus/pagy/commits?author=elliotlarson)[](https://github.com/ddnexus/pagy/commits?author=hungdiep97)[](https://github.com/ddnexus/pagy/commits?author=davidwessman)[](https://github.com/ddnexus/pagy/commits?author=david-a-wheeler)[](https://github.com/ddnexus/pagy/commits?author=daniel-rikowski)[](https://github.com/ddnexus/pagy/commits?author=connie-feng)[](https://github.com/ddnexus/pagy/commits?author=MrMoins)[](https://github.com/ddnexus/pagy/commits?author=excid3)[](https://github.com/ddnexus/pagy/commits?author=cellvinchung)[](https://github.com/ddnexus/pagy/commits?author=brunoocasali)[](https://github.com/ddnexus/pagy/commits?author=BrandonKlotz)[](https://github.com/ddnexus/pagy/commits?author=Atul9)[](https://github.com/ddnexus/pagy/commits?author=amenon)[](https://github.com/ddnexus/pagy/commits?author=artinboghosian)[](https://github.com/ddnexus/pagy/commits?author=antonzaharia)[](https://github.com/ddnexus/pagy/commits?author=PyrinAndrii)[](https://github.com/ddnexus/pagy/commits?author=andrew)[](https://github.com/ddnexus/pagy/commits?author=AliOsm)[](https://github.com/ddnexus/pagy/commits?author=AbelToy)[](https://github.com/ddnexus/pagy/commits?author=fluser)[](https://github.com/ddnexus/pagy/commits?author=maful)[](https://github.com/ddnexus/pagy/commits?author=loed-idzinga)[](https://github.com/ddnexus/pagy/commits?author=epeirce)[](https://github.com/ddnexus/pagy/commits?author=kobusjoubert)[](https://github.com/ddnexus/pagy/commits?author=KevinColemanInc)[](https://github.com/ddnexus/pagy/commits?author=neontuna)[](https://github.com/ddnexus/pagy/commits?author=xuanxu)[](https://github.com/ddnexus/pagy/commits?author=jpgarritano) +
diff --git a/scripts/bump b/scripts/bump deleted file mode 100755 index a9472e14b..000000000 --- a/scripts/bump +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/env bash - -set -e - -root="$(git rev-parse --show-toplevel)" - -# Abort if the working tree is dirty -[[ -z "$(git status --porcelain)" ]] || (>&2 echo "Working tree dirty!" && exit 1) - -# Prompt for the new version -old_vers=$(ruby -Igem/lib -rpagy -e 'puts Pagy::VERSION') -echo "Current Pagy::VERSION: $old_vers" -read -rp 'Enter the new version> ' new_vers - -# Abort if the version is invalid -[[ -n $new_vers ]] || ( >&2 echo 'Missing new version!' && exit 1) -num=$(echo "$new_vers" | grep -o '\.' | wc -l | xargs) -[[ $num == 2 ]] || (>&2 echo 'Incomplete semantic version!' && exit 1) - -# Abort if there is no gem change -[[ -n $(git diff --name-only --relative=gem "$old_vers"..HEAD) ]] || \ - (>&2 echo "No gem changes since version $old_vers!" && exit 1) - -# Bump the version in files -esc_old_vers=${old_vers//./\\.} -esc_new_vers=${new_vers//./\\.} -for path in \ - "retype.yml" \ - ".github/ISSUE_TEMPLATE/Code.yml" \ - ".github/latest_release_body.md" \ - "gem/apps/calendar.ru" \ - "gem/apps/demo.ru" \ - "gem/apps/rails.ru" \ - "gem/apps/repro.ru" \ - "gem/bin/pagy" \ - "gem/config/pagy.rb" \ - "gem/lib/pagy.rb" \ - "gem/pagy.gemspec" \ - "src/pagy.ts" -do - sed -i "0,/$esc_old_vers/{s/$esc_old_vers/$esc_new_vers/}" "$root/$path" -done - -# Bumps docs example -esc_old_minor_vers=${esc_old_vers%\\*} -esc_new_minor_vers=${esc_new_vers%\\*} -sed -i "0,/$esc_old_minor_vers/{s/$esc_old_minor_vers/$esc_new_minor_vers/}" "$root/quick-start.md" - -# Build javascript files -cd "$root/src" -./build -cd "$root" - -# Set tmplog to the commit messages that have changes in the "gem" root path -tmplog=$(mktemp) -# Iterate through the new commits -for commit in $(git rev-list "$old_vers"..HEAD) -do - if [[ -n $(git show --pretty="format:" --name-only --relative=gem $commit) ]] - then - subject=$(git show --no-patch --format="- %s" $commit) - if [[ $subject != *"[skip-log]"* ]] - then - body=$(git show --no-patch --format="%b" $commit) - if [[ -n "$body" ]] - then - body=$(echo "$body" | awk '{print " " $0}') - fi - echo -e "${subject}${body}" >> $tmplog - fi - fi -done - -function edit_doc() { - doc_name=$1 - doc_path=$2 - - echo -e "\n${doc_name}:" - cat "$doc_path" - echo - # Optional edit - read -rp "Do you want to edit the ${doc_name}? (y/n)> " input - if [[ $input = y ]] || [[ $input = Y ]]; then - nano "$doc_path" - fi -} - -edit_doc 'Commit log' "$tmplog" - -# Insert the whats_new (from README) and changes in the the release body file -# used by .github/workflows/create_release.yml which is triggered by the :rubygem_release task (push tag) -release_body_path="$root/.github/latest_release_body.md" -### What's New -lead='' -tail='' -whats_new=$(sed -n "/$lead/,/$tail/p" "$root/README.md") -#whats_new=$(sed -n "/$lead/,/$tail/{//b;p}" "$root/README.md") -gawk -i inplace -v st="$lead" -v et="$tail" -v repl="$whats_new" ' - $0 == st{del=1} $0 == et{$0 = repl; del=0} !del' "$release_body_path" - -### Changes -lead='^$' -tail='^$' -sed -i "/$lead/,/$tail/{ /$lead/{p; r $tmplog - }; /$tail/p; d }" "$release_body_path" - -edit_doc 'Release body' "$release_body_path" - -# Update CHANGELOG -changelog=$(cat <(echo -e "
\n\n## Version $new_vers\n") "$tmplog") -changelog_path="$root/CHANGELOG.md" -awk -v l="$changelog" '{sub(/
/, l); print}' "$changelog_path" > "$tmplog" -mv "$tmplog" "$changelog_path" - -# Run the test to check the consistency of versioning across files -bundle exec ruby -Itest test/pagy_test.rb --name "/pagy::Version match(#|::)/" - -# Optional update of top 100 -read -rp 'Do you want to update the "Top 100 contributors"? (y/n)> ' input -if [[ $input = y ]] || [[ $input = Y ]]; then - bundle exec "$root/scripts/update_top100.rb" -fi - -# Optional commit -read -rp 'Do you want to commit the changes? (y/n)> ' input -if [[ $input = y ]] || [[ $input = Y ]]; then - git add -A - git commit -m "Version $new_vers" -fi diff --git a/scripts/bump.rb b/scripts/bump.rb new file mode 100755 index 000000000..7a7e5b33e --- /dev/null +++ b/scripts/bump.rb @@ -0,0 +1,103 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require 'tempfile' +require_relative 'scripty' + +# Abort if the working tree is dirty +Scripty.die('Working tree dirty!') unless `git status --porcelain`.empty? + +# Prompt for the new version +require_relative '../gem/lib/pagy' +old_version = Pagy::VERSION +puts "Current Pagy::VERSION: #{old_version}" +print 'Enter the new version: ' +new_version = gets.chomp + +# Abort if the version is missing +Scripty.die('Missing new version!') if new_version.empty? + +# Abort if the version is invalid +new_fragments = new_version.split('.') +Scripty.die('Incomplete semantic version!') if new_fragments.size < 3 + +# Abort if there is no gem change +Scripty.die("No gem changes since version #{old_version}!") \ + if `git diff --name-only --relative=gem "#{old_version}"..HEAD`.empty? + +# Bump the version in files +%w[retype.yml + .github/ISSUE_TEMPLATE/Code.yml + .github/latest_release_body.md + gem/apps/calendar.ru + gem/apps/demo.ru + gem/apps/rails.ru + gem/apps/repro.ru + gem/bin/pagy + gem/config/pagy.rb + gem/lib/pagy.rb + gem/pagy.gemspec + src/pagy.ts].each do |path| + Scripty.file_sub(path, old_version, new_version) +end + +# Bumps docs example +Scripty.file_sub('quick-start.md', + old_version.split('.')[0, 2].join('.'), + new_version.split('.')[0, 2].join('.')) + +# Build javascript files +system(Scripty::ROOT.join('src/build').to_s) + +# Create a tempfile with the formatted changes from the gem-filtered gitlog +gitlog = Tempfile.new +commits = `git rev-list "#{old_version}"..HEAD`.split("\n") +commits.each do |commit| + next if `git show --pretty="format:" --name-only --relative=gem #{commit}`.empty? + + subject = `git show --no-patch --format="- %s" #{commit}`.chomp + next if subject.match?('\[skip-log\]') + + gitlog.puts subject + body = `git show --no-patch --format="%b" #{commit}`.chomp + next if body.empty? + + lines = body.split("\n") + body = lines.map { |line| " #{line}" }.join("\n") + gitlog.puts body +end +gitlog.close + +# Edit the gitlog? +Scripty.file_edit?('Gitlog', gitlog.path) + +# Prepare the .github/latest_release_body.md file +# Used by .github/workflows/create_release.yml which is triggered by the :rubygem_release task (push tag) +release_body_path = '.github/latest_release_body.md' +# Insert whats_new from the README into latest_release_body file +whats_new_content = Scripty.tagged_extract('README.md', 'whats_new') +Scripty.tagged_file_sub(release_body_path, 'whats_new', whats_new_content) + +# Insert the changes into latest_release_body file +changes = "\n#{File.read(gitlog.path)}" +Scripty.tagged_file_sub(release_body_path, 'changes', changes) + +# Edit the Rlease Body? +Scripty.file_edit?('Release Body', release_body_path) + +# Update the CHANGELOG +Scripty.file_sub('CHANGELOG.md', /
\n/, "
\n\n## Version #{new_version}\n#{changes}") + +# Run the test to check the consistency of versioning across files +system('bundle exec rake test_version') + +# Optional update of top 100 +Scripty.ask_and_do('Do you want to update the "Top 100 contributors"? (y/n)> ') do + require_relative 'update_top100' +end + +# Optional commit +Scripty.ask_and_do('Do you want to commit the changes? (y/n)> ') do + system('git add -A') + system("git commit -m 'Version #{new_version}'") +end diff --git a/scripts/scripty.rb b/scripts/scripty.rb new file mode 100644 index 000000000..63c2a7083 --- /dev/null +++ b/scripts/scripty.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require 'pathname' + +# A few functions useful in scripts +module Scripty + ROOT = Pathname.new(`git rev-parse --show-toplevel`.chomp) + + # Ask for confirmation and do + def ask_and_do(question) + print question + yield if gets.chomp.start_with?(/y/i) + end + module_function :ask_and_do + + # Warn and exit + def die(message) + warn message + exit 1 + end + module_function :die + + # Optional edit + def file_edit?(name, filepath) + filepath = ROOT.join(filepath).to_s + puts "\n#{name}:" + puts File.read(filepath) + print "Do you want to edit #{name.inspect}? (y/n)> " + system("nano #{filepath}") if gets.chomp.start_with?(/y/i) + end + module_function :file_edit? + + # Substitute a string in filepth + def file_sub(filepath, search, replace) + filepath = ROOT.join(filepath).to_s + content = File.read(filepath) + content.sub!(search, replace) + File.write(filepath, content) + end + module_function :file_sub + + # Substitute a tagged string in filepth + def tagged_file_sub(filepath, tag, new_content) + filepath = ROOT.join(filepath).to_s + content = File.read(filepath) + content.sub!(/.*/m, + "#{new_content}") + File.write(filepath, content) + end + module_function :tagged_file_sub + + def tagged_extract(filepath, tag) + filepath = ROOT.join(filepath).to_s + content = File.read(filepath) + content[/(.*)/m, 1] + end + module_function :tagged_extract +end diff --git a/scripts/update_top100.rb b/scripts/update_top100.rb index 160f614f7..661089ffc 100755 --- a/scripts/update_top100.rb +++ b/scripts/update_top100.rb @@ -3,15 +3,14 @@ require 'json' require 'net/http' +require_relative 'scripty' USERS_URL_FMT = 'https://api.github.com/repos/ddnexus/pagy/contributors?page=%s' COMMITS_URL_FMT = 'https://github.com/ddnexus/pagy/commits?author=%s' IMG_WIDTH = '40' MAX_COUNT = 100 -START_TAG = '' -END_TAG = '' -top100 = "#{START_TAG}\n" +top100 = +"\n" count = 0 page = 1 until count >= MAX_COUNT || (users = JSON.parse(Net::HTTP.get(URI(format(USERS_URL_FMT, page))))).empty? @@ -26,11 +25,8 @@ end page += 1 end -top100 << "\n#{END_TAG}" +top100 << "\n" -readme_path = File.expand_path('../README.md', __dir__) -content = File.read(readme_path) -content.sub!(/#{START_TAG}.*#{END_TAG}/mo, top100) -File.write(readme_path, content) +Scripty.tagged_file_sub('README.md', 'top100', top100) puts %("Top 100 Contributors" README section updated! (#{count}/#{MAX_COUNT})) diff --git a/test/pagy/version_test.rb b/test/pagy/version_test.rb new file mode 100644 index 000000000..a35f6b417 --- /dev/null +++ b/test/pagy/version_test.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require_relative '../test_helper' + +describe 'Version match' do + it 'has version' do + _(Pagy::VERSION).wont_be_nil + end + it 'defines the same version in retype.yml' do + _(File.read('./retype.yml')).must_match "label: #{Pagy::VERSION}" + end + it 'defines the same version in .github/ISSUE_TEMPLATE/Code.yml' do + _(File.read('./.github/ISSUE_TEMPLATE/Code.yml')).must_match "I upgraded to pagy version #{Pagy::VERSION}" + end + it 'defines the same version in config/pagy.rb' do + _(Pagy.root.join('config', 'pagy.rb').read).must_match "# Pagy initializer file (#{Pagy::VERSION})" + end + it 'defines the same version in bin/pagy' do + _(Pagy.root.join('bin', 'pagy').read).must_match "VERSION = '#{Pagy::VERSION}'" + end + it 'defines the same version in apps/*.ru' do + %w[calendar demo rails repro].each do |app| + _(Pagy.root.join('apps', "#{app}.ru").read).must_match "VERSION = '#{Pagy::VERSION}'" + end + end + it 'defines the same version in javascripts/pagy.min.js' do + _(Pagy.root.join('javascripts', 'pagy.min.js').read).must_match "version:\"#{Pagy::VERSION}\"," + end + it 'defines the same version in src/pagy.min.js.map' do + _(Pagy.root.join('javascripts', 'pagy.min.js.map').read).must_match "version: \\\"#{Pagy::VERSION}\\\"," + end + it 'defines the same version in src/pagy.mjs' do + _(Pagy.root.join('javascripts', 'pagy.mjs').read).must_match "version: \"#{Pagy::VERSION}\"," + end + it 'defines the same version in CHANGELOG.md' do + _(Pagy.root.parent.join('CHANGELOG.md').read).must_match "## Version #{Pagy::VERSION}" + end + it 'defines the same minor version in ./quick-start.md' do + _(File.read('./quick-start.md')).must_match "gem 'pagy', '~> #{Pagy::VERSION.sub(/\.\d+$/, '')}" + end +end diff --git a/test/pagy_test.rb b/test/pagy_test.rb index e6b2afab2..63108fce6 100644 --- a/test/pagy_test.rb +++ b/test/pagy_test.rb @@ -5,44 +5,6 @@ describe 'pagy' do let(:pagy) { Pagy.new(count: 100, page: 4) } - describe 'Version match' do - it 'has version' do - _(Pagy::VERSION).wont_be_nil - end - it 'defines the same version in retype.yml' do - _(File.read('./retype.yml')).must_match "label: #{Pagy::VERSION}" - end - it 'defines the same version in .github/ISSUE_TEMPLATE/Code.yml' do - _(File.read('./.github/ISSUE_TEMPLATE/Code.yml')).must_match "I upgraded to pagy version #{Pagy::VERSION}" - end - it 'defines the same version in config/pagy.rb' do - _(Pagy.root.join('config', 'pagy.rb').read).must_match "# Pagy initializer file (#{Pagy::VERSION})" - end - it 'defines the same version in bin/pagy' do - _(Pagy.root.join('bin', 'pagy').read).must_match "VERSION = '#{Pagy::VERSION}'" - end - it 'defines the same version in apps/*.ru' do - %w[calendar demo rails repro].each do |app| - _(Pagy.root.join('apps', "#{app}.ru").read).must_match "VERSION = '#{Pagy::VERSION}'" - end - end - it 'defines the same version in javascripts/pagy.min.js' do - _(Pagy.root.join('javascripts', 'pagy.min.js').read).must_match "version:\"#{Pagy::VERSION}\"," - end - it 'defines the same version in src/pagy.min.js.map' do - _(Pagy.root.join('javascripts', 'pagy.min.js.map').read).must_match "version: \\\"#{Pagy::VERSION}\\\"," - end - it 'defines the same version in src/pagy.mjs' do - _(Pagy.root.join('javascripts', 'pagy.mjs').read).must_match "version: \"#{Pagy::VERSION}\"," - end - it 'defines the same version in CHANGELOG.md' do - _(Pagy.root.parent.join('CHANGELOG.md').read).must_match "## Version #{Pagy::VERSION}" - end - it 'defines the same minor version in ./quick-start.md' do - _(File.read('./quick-start.md')).must_match "gem 'pagy', '~> #{Pagy::VERSION.sub(/\.\d+$/, '')}" - end - end - describe '#initialize' do before do @vars = { count: 103, limit: 10 } From bebd1a166b0aa3c19f29b16200ddf7f94fb6be48 Mon Sep 17 00:00:00 2001 From: Domizio Demichelis Date: Sun, 28 Jul 2024 09:24:34 +0700 Subject: [PATCH 7/8] Remove legacy and unused javascript files --- Gemfile.lock | 4 +- gem/javascripts/pagy-module.js | 100 --------------------------------- gem/javascripts/pagy.js | 4 -- 3 files changed, 2 insertions(+), 106 deletions(-) delete mode 100644 gem/javascripts/pagy-module.js delete mode 100644 gem/javascripts/pagy.js diff --git a/Gemfile.lock b/Gemfile.lock index 42248f4ae..a47c46301 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -157,9 +157,9 @@ GEM net-smtp (0.5.0) net-protocol nio4r (2.7.3) - nokogiri (1.16.6-x86_64-darwin) + nokogiri (1.16.7-x86_64-darwin) racc (~> 1.4) - nokogiri (1.16.6-x86_64-linux) + nokogiri (1.16.7-x86_64-linux) racc (~> 1.4) oj (3.16.4) bigdecimal (>= 3.0) diff --git a/gem/javascripts/pagy-module.js b/gem/javascripts/pagy-module.js deleted file mode 100644 index 14e600216..000000000 --- a/gem/javascripts/pagy-module.js +++ /dev/null @@ -1,100 +0,0 @@ -const Pagy = (() => { - const rjsObserver = new ResizeObserver((entries) => entries.forEach((e) => e.target.querySelectorAll(".pagy-rjs").forEach((el) => el.pagyRender()))); - const initNav = (el, [tokens, sequels, labelSequels, trimParam]) => { - const container = el.parentElement ?? el; - const widths = Object.keys(sequels).map((w) => parseInt(w)).sort((a, b) => b - a); - let lastWidth = -1; - const fillIn = (a, page, label) => a.replace(/__pagy_page__/g, page).replace(/__pagy_label__/g, label); - (el.pagyRender = function() { - const width = widths.find((w) => w < container.clientWidth) || 0; - if (width === lastWidth) { - return; - } - let html = tokens.before; - const series = sequels[width.toString()]; - const labels = labelSequels?.[width.toString()] ?? series.map((l) => l.toString()); - series.forEach((item, i) => { - const label = labels[i]; - let filled; - if (typeof item === "number") { - filled = fillIn(tokens.a, item.toString(), label); - } else if (item === "gap") { - filled = tokens.gap; - } else { - filled = fillIn(tokens.current, item, label); - } - html += typeof trimParam === "string" && item == 1 ? trim(filled, trimParam) : filled; - }); - html += tokens.after; - el.innerHTML = ""; - el.insertAdjacentHTML("afterbegin", html); - lastWidth = width; - })(); - if (el.classList.contains("pagy-rjs")) { - rjsObserver.observe(container); - } - }; - const initCombo = (el, [url_token, trimParam]) => initInput(el, (inputValue) => [inputValue, url_token.replace(/__pagy_page__/, inputValue)], trimParam); - const initSelector = (el, [from, url_token, trimParam]) => { - initInput(el, (inputValue) => { - const page = Math.max(Math.ceil(from / parseInt(inputValue)), 1).toString(); - const url = url_token.replace(/__pagy_page__/, page).replace(/__pagy_items__/, inputValue); - return [page, url]; - }, trimParam); - }; - const initInput = (el, getVars, trimParam) => { - const input = el.querySelector("input"); - const link = el.querySelector("a"); - const initial = input.value; - const action = function() { - if (input.value === initial) { - return; - } - const [min, val, max] = [input.min, input.value, input.max].map((n) => parseInt(n) || 0); - if (val < min || val > max) { - input.value = initial; - input.select(); - return; - } - let [page, url] = getVars(input.value); - if (typeof trimParam === "string" && page === "1") { - url = trim(url, trimParam); - } - link.href = url; - link.click(); - }; - ["change", "focus"].forEach((e) => input.addEventListener(e, () => input.select())); - input.addEventListener("focusout", action); - input.addEventListener("keypress", (e) => { - if (e.key === "Enter") { - action(); - } - }); - }; - const trim = (a, param) => a.replace(new RegExp(`[?&]${param}=1\\b(?!&)|\\b${param}=1&`), ""); - return { - version: "8.6.3", - init(arg) { - const target = arg instanceof Element ? arg : document; - const elements = target.querySelectorAll("[data-pagy]"); - for (const el of elements) { - try { - const uint8array = Uint8Array.from(atob(el.getAttribute("data-pagy")), (c) => c.charCodeAt(0)); - const [keyword, ...args] = JSON.parse(new TextDecoder().decode(uint8array)); - if (keyword === "nav") { - initNav(el, args); - } else if (keyword === "combo") { - initCombo(el, args); - } else if (keyword === "selector") { - initSelector(el, args); - } else { - console.warn("Skipped Pagy.init() for: %o\nUnknown keyword '%s'", el, keyword); - } - } catch (err) { - console.warn("Skipped Pagy.init() for: %o\n%s", el, err); - } - } - } - }; -})(); -export default Pagy; diff --git a/gem/javascripts/pagy.js b/gem/javascripts/pagy.js deleted file mode 100644 index 5601aed60..000000000 --- a/gem/javascripts/pagy.js +++ /dev/null @@ -1,4 +0,0 @@ -window.Pagy=(()=>{const j=new ResizeObserver((B)=>B.forEach((D)=>D.target.querySelectorAll(".pagy-rjs").forEach((E)=>E.pagyRender()))),x=(B,[D,E,z,G])=>{const F=B.parentElement??B,K=Object.keys(E).map((H)=>parseInt(H)).sort((H,M)=>M-H);let L=-1;const T=(H,M,R)=>H.replace(/__pagy_page__/g,M).replace(/__pagy_label__/g,R);if((B.pagyRender=function(){const H=K.find((Q)=>QQ.toString());R.forEach((Q,J)=>{const $=X[J];let U;if(typeof Q==="number")U=T(D.a,Q.toString(),$);else if(Q==="gap")U=D.gap;else U=T(D.current,Q,$);M+=typeof G==="string"&&Q==1?Z(U,G):U}),M+=D.after,B.innerHTML="",B.insertAdjacentHTML("afterbegin",M),L=H})(),B.classList.contains("pagy-rjs"))j.observe(F)},A=(B,[D,E])=>Y(B,(z)=>[z,D.replace(/__pagy_page__/,z)],E),C=(B,[D,E,z])=>{Y(B,(G)=>{const F=Math.max(Math.ceil(D/parseInt(G)),1).toString(),K=E.replace(/__pagy_page__/,F).replace(/__pagy_items__/,G);return[F,K]},z)},Y=(B,D,E)=>{const z=B.querySelector("input"),G=B.querySelector("a"),F=z.value,K=function(){if(z.value===F)return;const[L,T,H]=[z.min,z.value,z.max].map((X)=>parseInt(X)||0);if(TH){z.value=F,z.select();return}let[M,R]=D(z.value);if(typeof E==="string"&&M==="1")R=Z(R,E);G.href=R,G.click()};["change","focus"].forEach((L)=>z.addEventListener(L,()=>z.select())),z.addEventListener("focusout",K),z.addEventListener("keypress",(L)=>{if(L.key==="Enter")K()})},Z=(B,D)=>B.replace(new RegExp(`[?&]${D}=1\\b(?!&)|\\b${D}=1&`),"");return{version:"8.6.3",init(B){const E=(B instanceof Element?B:document).querySelectorAll("[data-pagy]");for(let z of E)try{const G=Uint8Array.from(atob(z.getAttribute("data-pagy")),(L)=>L.charCodeAt(0)),[F,...K]=JSON.parse((new TextDecoder()).decode(G));if(F==="nav")x(z,K);else if(F==="combo")A(z,K);else if(F==="selector")C(z,K);else console.warn("Skipped Pagy.init() for: %o\nUnknown keyword '%s'",z,F)}catch(G){console.warn("Skipped Pagy.init() for: %o\n%s",z,G)}}}})(); - -//# debugId=B9DC02765C7A5B6764756E2164756E21 -//# sourceMappingURL=pagy.min.js.map From ae1d90659b8103dd7dfa1825a424e6faa1d05385 Mon Sep 17 00:00:00 2001 From: Domizio Demichelis Date: Sun, 28 Jul 2024 16:01:38 +0700 Subject: [PATCH 8/8] Version 9.0.3 --- .github/ISSUE_TEMPLATE/Code.yml | 2 +- .github/latest_release_body.md | 12 +++++++----- CHANGELOG.md | 9 +++++++++ Gemfile.lock | 2 +- gem/apps/calendar.ru | 2 +- gem/apps/demo.ru | 2 +- gem/apps/rails.ru | 2 +- gem/apps/repro.ru | 2 +- gem/bin/pagy | 2 +- gem/config/pagy.rb | 2 +- gem/javascripts/pagy.min.js | 4 ++-- gem/javascripts/pagy.min.js.map | 4 ++-- gem/javascripts/pagy.mjs | 2 +- gem/lib/pagy.rb | 2 +- gem/pagy.gemspec | 2 +- retype.yml | 2 +- src/pagy.ts | 2 +- 17 files changed, 33 insertions(+), 22 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/Code.yml b/.github/ISSUE_TEMPLATE/Code.yml index 6001e3980..0ec4ee788 100644 --- a/.github/ISSUE_TEMPLATE/Code.yml +++ b/.github/ISSUE_TEMPLATE/Code.yml @@ -19,7 +19,7 @@ body: attributes: label: 👀 Before submitting... options: - - label: I upgraded to pagy version 9.0.2 + - label: I upgraded to pagy version 9.0.3 required: true - label: I searched through the [Documentation](https://ddnexus.github.io/pagy/) required: true diff --git a/.github/latest_release_body.md b/.github/latest_release_body.md index d92dd775a..95f558e4a 100644 --- a/.github/latest_release_body.md +++ b/.github/latest_release_body.md @@ -6,13 +6,15 @@ - See the [Changelog](https://ddnexus.github.io/pagy/changelog) for possible breaking changes -### Changes in 9.0.2 +### Changes in 9.0.3 -- Rename and document the link header to pagy_link_header -- Add first and next url helpers to the keyset extra; add the keyset section to config/pagy.rb -- Fix nil page in keyset URL not overriding the params page -- Extracted shared method +- Remove legacy and unused javascript files +- Improve pagy_get_page with force_integer option +- Fix jsonapi with keyset +- Complete the internal refactoring of version 9: + - Remove the pagy*_get_vars methods now useless + - Use to_i on the page variable for the search extras [CHANGELOG](https://ddnexus.github.io/pagy/changelog) diff --git a/CHANGELOG.md b/CHANGELOG.md index cec84f691..c74b755b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,15 @@ If you upgrade from version `< 9.0.0` see the following: - None
+## Version 9.0.3 + +- Remove legacy and unused javascript files +- Improve pagy_get_page with force_integer option +- Fix jsonapi with keyset +- Complete the internal refactoring of version 9: + - Remove the pagy*_get_vars methods now useless + - Use to_i on the page variable for the search extras + ## Version 9.0.2 - Rename and document the link header to pagy_link_header diff --git a/Gemfile.lock b/Gemfile.lock index a47c46301..e3a04ae63 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: gem specs: - pagy (9.0.2) + pagy (9.0.3) GEM remote: https://rubygems.org/ diff --git a/gem/apps/calendar.ru b/gem/apps/calendar.ru index 9c8dd303e..4f58af543 100644 --- a/gem/apps/calendar.ru +++ b/gem/apps/calendar.ru @@ -15,7 +15,7 @@ # DOC # https://ddnexus.github.io/pagy/playground/#5-calendar-app -VERSION = '9.0.2' +VERSION = '9.0.3' # Gemfile require 'bundler/inline' diff --git a/gem/apps/demo.ru b/gem/apps/demo.ru index 779429a50..70fa479d6 100644 --- a/gem/apps/demo.ru +++ b/gem/apps/demo.ru @@ -18,7 +18,7 @@ # DOC # https://ddnexus.github.io/pagy/playground/#3-demo-app -VERSION = '9.0.2' +VERSION = '9.0.3' require 'bundler/inline' require 'bundler' diff --git a/gem/apps/rails.ru b/gem/apps/rails.ru index 7800a6c5c..bbc3c837d 100644 --- a/gem/apps/rails.ru +++ b/gem/apps/rails.ru @@ -15,7 +15,7 @@ # DOC # https://ddnexus.github.io/pagy/playground/#2-rails-app -VERSION = '9.0.2' +VERSION = '9.0.3' # Gemfile require 'bundler/inline' diff --git a/gem/apps/repro.ru b/gem/apps/repro.ru index 9c59549a0..af3734423 100644 --- a/gem/apps/repro.ru +++ b/gem/apps/repro.ru @@ -15,7 +15,7 @@ # DOC # https://ddnexus.github.io/pagy/playground/#1-repro-app -VERSION = '9.0.2' +VERSION = '9.0.3' require 'bundler/inline' require 'bundler' diff --git a/gem/bin/pagy b/gem/bin/pagy index 494a2c671..40ff58875 100755 --- a/gem/bin/pagy +++ b/gem/bin/pagy @@ -1,7 +1,7 @@ #!/usr/bin/env ruby # frozen_string_literal: true -VERSION = '9.0.2' +VERSION = '9.0.3' APPS = %w[repro rails demo calendar keyset_ar keyset_s].freeze LINUX = RbConfig::CONFIG['host_os'].include?('linux') HOST = '0.0.0.0' diff --git a/gem/config/pagy.rb b/gem/config/pagy.rb index b308a9425..1cead63e9 100644 --- a/gem/config/pagy.rb +++ b/gem/config/pagy.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# Pagy initializer file (9.0.2) +# Pagy initializer file (9.0.3) # Customize only what you really need and notice that the core Pagy works also without any of the following lines. # Should you just cherry pick part of this file, please maintain the require-order of the extras diff --git a/gem/javascripts/pagy.min.js b/gem/javascripts/pagy.min.js index a8a9b83b7..4dc4423e2 100644 --- a/gem/javascripts/pagy.min.js +++ b/gem/javascripts/pagy.min.js @@ -1,4 +1,4 @@ -window.Pagy=(()=>{const j=new ResizeObserver((B)=>B.forEach((D)=>D.target.querySelectorAll(".pagy-rjs").forEach((E)=>E.pagyRender()))),x=(B,[D,E,z,G])=>{const F=B.parentElement??B,K=Object.keys(E).map((H)=>parseInt(H)).sort((H,M)=>M-H);let L=-1;const T=(H,M,R)=>H.replace(/__pagy_page__/g,M).replace(/__pagy_label__/g,R);if((B.pagyRender=function(){const H=K.find((Q)=>QQ.toString());R.forEach((Q,J)=>{const $=X[J];let U;if(typeof Q==="number")U=T(D.a,Q.toString(),$);else if(Q==="gap")U=D.gap;else U=T(D.current,Q,$);M+=typeof G==="string"&&Q==1?Z(U,G):U}),M+=D.after,B.innerHTML="",B.insertAdjacentHTML("afterbegin",M),L=H})(),B.classList.contains("pagy-rjs"))j.observe(F)},A=(B,[D,E])=>Y(B,(z)=>[z,D.replace(/__pagy_page__/,z)],E),C=(B,[D,E,z])=>{Y(B,(G)=>{const F=Math.max(Math.ceil(D/parseInt(G)),1).toString(),K=E.replace(/__pagy_page__/,F).replace(/__pagy_limit__/,G);return[F,K]},z)},Y=(B,D,E)=>{const z=B.querySelector("input"),G=B.querySelector("a"),F=z.value,K=function(){if(z.value===F)return;const[L,T,H]=[z.min,z.value,z.max].map((X)=>parseInt(X)||0);if(TH){z.value=F,z.select();return}let[M,R]=D(z.value);if(typeof E==="string"&&M==="1")R=Z(R,E);G.href=R,G.click()};["change","focus"].forEach((L)=>z.addEventListener(L,()=>z.select())),z.addEventListener("focusout",K),z.addEventListener("keypress",(L)=>{if(L.key==="Enter")K()})},Z=(B,D)=>B.replace(new RegExp(`[?&]${D}=1\\b(?!&)|\\b${D}=1&`),"");return{version:"9.0.2",init(B){const E=(B instanceof Element?B:document).querySelectorAll("[data-pagy]");for(let z of E)try{const G=Uint8Array.from(atob(z.getAttribute("data-pagy")),(L)=>L.charCodeAt(0)),[F,...K]=JSON.parse((new TextDecoder()).decode(G));if(F==="nav")x(z,K);else if(F==="combo")A(z,K);else if(F==="selector")C(z,K);else console.warn("Skipped Pagy.init() for: %o\nUnknown keyword '%s'",z,F)}catch(G){console.warn("Skipped Pagy.init() for: %o\n%s",z,G)}}}})(); +window.Pagy=(()=>{const j=new ResizeObserver((B)=>B.forEach((D)=>D.target.querySelectorAll(".pagy-rjs").forEach((E)=>E.pagyRender()))),x=(B,[D,E,z,G])=>{const F=B.parentElement??B,K=Object.keys(E).map((H)=>parseInt(H)).sort((H,M)=>M-H);let L=-1;const T=(H,M,R)=>H.replace(/__pagy_page__/g,M).replace(/__pagy_label__/g,R);if((B.pagyRender=function(){const H=K.find((Q)=>QQ.toString());R.forEach((Q,J)=>{const $=X[J];let U;if(typeof Q==="number")U=T(D.a,Q.toString(),$);else if(Q==="gap")U=D.gap;else U=T(D.current,Q,$);M+=typeof G==="string"&&Q==1?Z(U,G):U}),M+=D.after,B.innerHTML="",B.insertAdjacentHTML("afterbegin",M),L=H})(),B.classList.contains("pagy-rjs"))j.observe(F)},A=(B,[D,E])=>Y(B,(z)=>[z,D.replace(/__pagy_page__/,z)],E),C=(B,[D,E,z])=>{Y(B,(G)=>{const F=Math.max(Math.ceil(D/parseInt(G)),1).toString(),K=E.replace(/__pagy_page__/,F).replace(/__pagy_limit__/,G);return[F,K]},z)},Y=(B,D,E)=>{const z=B.querySelector("input"),G=B.querySelector("a"),F=z.value,K=function(){if(z.value===F)return;const[L,T,H]=[z.min,z.value,z.max].map((X)=>parseInt(X)||0);if(TH){z.value=F,z.select();return}let[M,R]=D(z.value);if(typeof E==="string"&&M==="1")R=Z(R,E);G.href=R,G.click()};["change","focus"].forEach((L)=>z.addEventListener(L,()=>z.select())),z.addEventListener("focusout",K),z.addEventListener("keypress",(L)=>{if(L.key==="Enter")K()})},Z=(B,D)=>B.replace(new RegExp(`[?&]${D}=1\\b(?!&)|\\b${D}=1&`),"");return{version:"9.0.3",init(B){const E=(B instanceof Element?B:document).querySelectorAll("[data-pagy]");for(let z of E)try{const G=Uint8Array.from(atob(z.getAttribute("data-pagy")),(L)=>L.charCodeAt(0)),[F,...K]=JSON.parse((new TextDecoder()).decode(G));if(F==="nav")x(z,K);else if(F==="combo")A(z,K);else if(F==="selector")C(z,K);else console.warn("Skipped Pagy.init() for: %o\nUnknown keyword '%s'",z,F)}catch(G){console.warn("Skipped Pagy.init() for: %o\n%s",z,G)}}}})(); -//# debugId=F551263AEB70D01764756E2164756E21 +//# debugId=F902131AD289418764756E2164756E21 //# sourceMappingURL=pagy.min.js.map diff --git a/gem/javascripts/pagy.min.js.map b/gem/javascripts/pagy.min.js.map index 924913c93..902311dea 100644 --- a/gem/javascripts/pagy.min.js.map +++ b/gem/javascripts/pagy.min.js.map @@ -2,9 +2,9 @@ "version": 3, "sources": ["../../src/pagy.ts"], "sourcesContent": [ - "type NavArgs = readonly [Tokens, Sequels, null | LabelSequels, string?]\ntype ComboArgs = readonly [string, string?]\ntype SelectorArgs = readonly [number, string, string?]\ntype JsonArgs = ['nav', NavArgs] | ['combo', ComboArgs] | ['selector', SelectorArgs]\n\ninterface Tokens {\n readonly before:string\n readonly a:string\n readonly current:string\n readonly gap:string\n readonly after:string\n}\ninterface Sequels {readonly [width:string]:(string | number)[]}\ninterface LabelSequels {readonly [width:string]:string[]}\ninterface NavElement extends Element {pagyRender():void}\n\nconst Pagy = (() => {\n // The observer instance for responsive navs\n const rjsObserver = new ResizeObserver(\n entries => entries.forEach(e => e.target.querySelectorAll(\".pagy-rjs\")\n .forEach(el => el.pagyRender())));\n // Init the *_nav_js helpers\n const initNav = (el:NavElement, [tokens, sequels, labelSequels, trimParam]:NavArgs) => {\n const container = el.parentElement ?? el;\n const widths = Object.keys(sequels).map(w => parseInt(w)).sort((a, b) => b - a);\n let lastWidth = -1;\n const fillIn = (a:string, page:string, label:string):string =>\n a.replace(/__pagy_page__/g, page).replace(/__pagy_label__/g, label);\n (el.pagyRender = function () {\n const width = widths.find(w => w < container.clientWidth) || 0;\n if (width === lastWidth) { return } // no change: abort\n let html = tokens.before; // already trimmed in html\n const series = sequels[width.toString()];\n const labels = labelSequels?.[width.toString()] ?? series.map(l => l.toString());\n series.forEach((item, i) => {\n const label = labels[i];\n let filled;\n if (typeof item === \"number\") {\n filled = fillIn(tokens.a, item.toString(), label);\n } else if (item === \"gap\") {\n filled = tokens.gap;\n } else { // active page\n filled = fillIn(tokens.current, item, label);\n }\n html += (typeof trimParam === \"string\" && item == 1) ? trim(filled, trimParam) : filled;\n });\n html += tokens.after;\n el.innerHTML = \"\";\n el.insertAdjacentHTML(\"afterbegin\", html);\n lastWidth = width;\n })();\n if (el.classList.contains(\"pagy-rjs\")) { rjsObserver.observe(container) }\n };\n\n // Init the *_combo_nav_js helpers\n const initCombo = (el:Element, [url_token, trimParam]:ComboArgs) =>\n initInput(el, inputValue => [inputValue, url_token.replace(/__pagy_page__/, inputValue)], trimParam);\n\n // Init the limit_selector_js helper\n const initSelector = (el:Element, [from, url_token, trimParam]:SelectorArgs) => {\n initInput(el, inputValue => {\n const page = Math.max(Math.ceil(from / parseInt(inputValue)), 1).toString();\n const url = url_token.replace(/__pagy_page__/, page).replace(/__pagy_limit__/, inputValue);\n return [page, url];\n }, trimParam);\n };\n\n // Init the input element\n const initInput = (el:Element, getVars:(v:string) => [string, string], trimParam?:string) => {\n const input = el.querySelector(\"input\") as HTMLInputElement;\n const link = el.querySelector(\"a\") as HTMLAnchorElement;\n const initial = input.value;\n const action = function () {\n if (input.value === initial) { return } // not changed\n const [min, val, max] = [input.min, input.value, input.max].map(n => parseInt(n) || 0);\n if (val < min || val > max) { // reset invalid/out-of-range\n input.value = initial;\n input.select();\n return;\n }\n let [page, url] = getVars(input.value); // eslint-disable-line prefer-const\n if (typeof trimParam === \"string\" && page === \"1\") { url = trim(url, trimParam) }\n link.href = url;\n link.click();\n };\n [\"change\", \"focus\"].forEach(e => input.addEventListener(e, () => input.select())); // auto-select\n input.addEventListener(\"focusout\", action); // trigger action\n input.addEventListener(\"keypress\", e => { if (e.key === \"Enter\") { action() } }); // trigger action\n };\n\n // Trim the ${page-param}=1 params in links\n const trim = (a:string, param:string) =>\n a.replace(new RegExp(`[?&]${param}=1\\\\b(?!&)|\\\\b${param}=1&`), \"\");\n\n // Public interface\n return {\n version: \"9.0.2\",\n\n // Scan for elements with a \"data-pagy\" attribute and call their init functions with the decoded args\n init(arg?:Element) {\n const target = arg instanceof Element ? arg : document;\n const elements = target.querySelectorAll(\"[data-pagy]\");\n for (const el of elements) {\n try {\n const uint8array = Uint8Array.from(atob(el.getAttribute(\"data-pagy\") as string), c => c.charCodeAt(0));\n const [keyword, ...args] = JSON.parse((new TextDecoder()).decode(uint8array)) as JsonArgs; // base64-utf8 -> JSON -> Array\n if (keyword === \"nav\") {\n initNav(el as NavElement, args as unknown as NavArgs);\n } else if (keyword === \"combo\") {\n initCombo(el, args as unknown as ComboArgs);\n } else if (keyword === \"selector\") {\n initSelector(el, args as unknown as SelectorArgs);\n } else {\n console.warn(\"Skipped Pagy.init() for: %o\\nUnknown keyword '%s'\", el, keyword);\n }\n } catch (err) { console.warn(\"Skipped Pagy.init() for: %o\\n%s\", el, err) }\n }\n }\n };\n})();\n\nexport default Pagy;\n" + "type NavArgs = readonly [Tokens, Sequels, null | LabelSequels, string?]\ntype ComboArgs = readonly [string, string?]\ntype SelectorArgs = readonly [number, string, string?]\ntype JsonArgs = ['nav', NavArgs] | ['combo', ComboArgs] | ['selector', SelectorArgs]\n\ninterface Tokens {\n readonly before:string\n readonly a:string\n readonly current:string\n readonly gap:string\n readonly after:string\n}\ninterface Sequels {readonly [width:string]:(string | number)[]}\ninterface LabelSequels {readonly [width:string]:string[]}\ninterface NavElement extends Element {pagyRender():void}\n\nconst Pagy = (() => {\n // The observer instance for responsive navs\n const rjsObserver = new ResizeObserver(\n entries => entries.forEach(e => e.target.querySelectorAll(\".pagy-rjs\")\n .forEach(el => el.pagyRender())));\n // Init the *_nav_js helpers\n const initNav = (el:NavElement, [tokens, sequels, labelSequels, trimParam]:NavArgs) => {\n const container = el.parentElement ?? el;\n const widths = Object.keys(sequels).map(w => parseInt(w)).sort((a, b) => b - a);\n let lastWidth = -1;\n const fillIn = (a:string, page:string, label:string):string =>\n a.replace(/__pagy_page__/g, page).replace(/__pagy_label__/g, label);\n (el.pagyRender = function () {\n const width = widths.find(w => w < container.clientWidth) || 0;\n if (width === lastWidth) { return } // no change: abort\n let html = tokens.before; // already trimmed in html\n const series = sequels[width.toString()];\n const labels = labelSequels?.[width.toString()] ?? series.map(l => l.toString());\n series.forEach((item, i) => {\n const label = labels[i];\n let filled;\n if (typeof item === \"number\") {\n filled = fillIn(tokens.a, item.toString(), label);\n } else if (item === \"gap\") {\n filled = tokens.gap;\n } else { // active page\n filled = fillIn(tokens.current, item, label);\n }\n html += (typeof trimParam === \"string\" && item == 1) ? trim(filled, trimParam) : filled;\n });\n html += tokens.after;\n el.innerHTML = \"\";\n el.insertAdjacentHTML(\"afterbegin\", html);\n lastWidth = width;\n })();\n if (el.classList.contains(\"pagy-rjs\")) { rjsObserver.observe(container) }\n };\n\n // Init the *_combo_nav_js helpers\n const initCombo = (el:Element, [url_token, trimParam]:ComboArgs) =>\n initInput(el, inputValue => [inputValue, url_token.replace(/__pagy_page__/, inputValue)], trimParam);\n\n // Init the limit_selector_js helper\n const initSelector = (el:Element, [from, url_token, trimParam]:SelectorArgs) => {\n initInput(el, inputValue => {\n const page = Math.max(Math.ceil(from / parseInt(inputValue)), 1).toString();\n const url = url_token.replace(/__pagy_page__/, page).replace(/__pagy_limit__/, inputValue);\n return [page, url];\n }, trimParam);\n };\n\n // Init the input element\n const initInput = (el:Element, getVars:(v:string) => [string, string], trimParam?:string) => {\n const input = el.querySelector(\"input\") as HTMLInputElement;\n const link = el.querySelector(\"a\") as HTMLAnchorElement;\n const initial = input.value;\n const action = function () {\n if (input.value === initial) { return } // not changed\n const [min, val, max] = [input.min, input.value, input.max].map(n => parseInt(n) || 0);\n if (val < min || val > max) { // reset invalid/out-of-range\n input.value = initial;\n input.select();\n return;\n }\n let [page, url] = getVars(input.value); // eslint-disable-line prefer-const\n if (typeof trimParam === \"string\" && page === \"1\") { url = trim(url, trimParam) }\n link.href = url;\n link.click();\n };\n [\"change\", \"focus\"].forEach(e => input.addEventListener(e, () => input.select())); // auto-select\n input.addEventListener(\"focusout\", action); // trigger action\n input.addEventListener(\"keypress\", e => { if (e.key === \"Enter\") { action() } }); // trigger action\n };\n\n // Trim the ${page-param}=1 params in links\n const trim = (a:string, param:string) =>\n a.replace(new RegExp(`[?&]${param}=1\\\\b(?!&)|\\\\b${param}=1&`), \"\");\n\n // Public interface\n return {\n version: \"9.0.3\",\n\n // Scan for elements with a \"data-pagy\" attribute and call their init functions with the decoded args\n init(arg?:Element) {\n const target = arg instanceof Element ? arg : document;\n const elements = target.querySelectorAll(\"[data-pagy]\");\n for (const el of elements) {\n try {\n const uint8array = Uint8Array.from(atob(el.getAttribute(\"data-pagy\") as string), c => c.charCodeAt(0));\n const [keyword, ...args] = JSON.parse((new TextDecoder()).decode(uint8array)) as JsonArgs; // base64-utf8 -> JSON -> Array\n if (keyword === \"nav\") {\n initNav(el as NavElement, args as unknown as NavArgs);\n } else if (keyword === \"combo\") {\n initCombo(el, args as unknown as ComboArgs);\n } else if (keyword === \"selector\") {\n initSelector(el, args as unknown as SelectorArgs);\n } else {\n console.warn(\"Skipped Pagy.init() for: %o\\nUnknown keyword '%s'\", el, keyword);\n }\n } catch (err) { console.warn(\"Skipped Pagy.init() for: %o\\n%s\", el, err) }\n }\n }\n };\n})();\n\nexport default Pagy;\n" ], "mappings": "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", - "debugId": "F551263AEB70D01764756E2164756E21", + "debugId": "F902131AD289418764756E2164756E21", "names": [] } \ No newline at end of file diff --git a/gem/javascripts/pagy.mjs b/gem/javascripts/pagy.mjs index a3fb74f1c..263080b1c 100644 --- a/gem/javascripts/pagy.mjs +++ b/gem/javascripts/pagy.mjs @@ -73,7 +73,7 @@ const Pagy = (() => { }; const trim = (a, param) => a.replace(new RegExp(`[?&]${param}=1\\b(?!&)|\\b${param}=1&`), ""); return { - version: "9.0.2", + version: "9.0.3", init(arg) { const target = arg instanceof Element ? arg : document; const elements = target.querySelectorAll("[data-pagy]"); diff --git a/gem/lib/pagy.rb b/gem/lib/pagy.rb index 0d0454b88..c4d06dcd9 100644 --- a/gem/lib/pagy.rb +++ b/gem/lib/pagy.rb @@ -6,7 +6,7 @@ # Top superclass: it should define only what's common to all the subclasses class Pagy - VERSION = '9.0.2' + VERSION = '9.0.3' # Core default: constant for easy access, but mutable for customizable defaults DEFAULT = { count_args: [:all], # rubocop:disable Style/MutableConstant diff --git a/gem/pagy.gemspec b/gem/pagy.gemspec index b5e108e71..0cb0c5e01 100644 --- a/gem/pagy.gemspec +++ b/gem/pagy.gemspec @@ -2,7 +2,7 @@ Gem::Specification.new do |s| s.name = 'pagy' - s.version = '9.0.2' + s.version = '9.0.3' s.authors = ['Domizio Demichelis'] s.email = ['dd.nexus@gmail.com'] s.summary = 'The best pagination ruby gem' diff --git a/retype.yml b/retype.yml index f0fbafac3..73959f71a 100644 --- a/retype.yml +++ b/retype.yml @@ -8,7 +8,7 @@ url: https://ddnexus.github.io/pagy branding: title: Pagy - label: 9.0.2 + label: 9.0.3 colors: label: text: "#FFFFFF" diff --git a/src/pagy.ts b/src/pagy.ts index c99a4cf0b..2834a230c 100644 --- a/src/pagy.ts +++ b/src/pagy.ts @@ -94,7 +94,7 @@ const Pagy = (() => { // Public interface return { - version: "9.0.2", + version: "9.0.3", // Scan for elements with a "data-pagy" attribute and call their init functions with the decoded args init(arg?:Element) {