pagy 43.2.1 → 43.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/pagy/cli.rb ADDED
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'optparse'
4
+ require 'fileutils'
5
+ require 'rbconfig'
6
+ require 'pagy'
7
+ require_relative '../../apps/index'
8
+
9
+ class Pagy
10
+ class CLI
11
+ HOST = 'localhost'
12
+ PORT = '8000'
13
+
14
+ def start(args = ARGV)
15
+ options = parse_options(args)
16
+ run_command(args, options)
17
+ end
18
+
19
+ private
20
+
21
+ def parse_options(args)
22
+ options = { env: 'development', host: HOST, port: PORT, quiet: false }
23
+
24
+ parser = OptionParser.new do |opts|
25
+ opts.banner = <<~BANNER
26
+ Pagy #{VERSION} (https://ddnexus.github.io/pagy/playground)
27
+ Playground to showcase, clone and develop Pagy APPs
28
+
29
+ Usage:
30
+ pagy APP [opts] Showcase APP from the installed gem
31
+ pagy clone APP Clone APP to the current dir
32
+ pagy FILE [opts] Develop app FILE from local path
33
+ BANNER
34
+
35
+ opts.summary_indent = ' '
36
+ opts.summary_width = 18
37
+
38
+ opts.separator "\nAPPs"
39
+ PagyApps::INDEX.each do |name, path|
40
+ desc = File.readlines(path)[3].sub('# ', '').strip
41
+ opts.separator " #{name.ljust(18)}#{desc}"
42
+ end
43
+
44
+ opts.separator "\nRackup options"
45
+ opts.on('-e', '--env ENV', 'Environment') { |v| options[:env] = v }
46
+ opts.on('-o', '--host HOST', 'Host') { |v| options[:host] = v }
47
+ opts.on('-p', '--port PORT', 'Port') { |v| options[:port] = v }
48
+
49
+ opts.separator "\nOther options"
50
+ opts.on('-q', '--quiet', 'Quiet mode for development') { options[:quiet] = true }
51
+ opts.on('-v', '--version', 'Show version') do
52
+ puts VERSION
53
+ exit
54
+ end
55
+ opts.on('-h', '--help', 'Show this help') do
56
+ puts opts
57
+ exit
58
+ end
59
+
60
+ opts.separator "\nExamples"
61
+ opts.separator " pagy demo Showcase demo at http://#{HOST}:#{PORT}"
62
+ opts.separator ' pagy clone repro Clone repro to ./repro.ru (rename it)'
63
+ opts.separator " pagy ~/myapp.ru Develop ~/myapp.ru at #{HOST}:#{PORT}"
64
+ end
65
+
66
+ begin
67
+ parser.parse!(args)
68
+ rescue OptionParser::InvalidOption => e
69
+ abort e.message
70
+ end
71
+
72
+ if args.empty?
73
+ puts parser
74
+ exit
75
+ end
76
+
77
+ options
78
+ end
79
+
80
+ def run_command(args, options)
81
+ run_from_repo = Pagy::ROOT.join('pagy.gemspec').exist?
82
+ setup_gems(run_from_repo)
83
+
84
+ arg = args.shift
85
+
86
+ if arg.eql?('clone')
87
+ clone_app(args.shift)
88
+ else
89
+ serve_app(arg, options)
90
+ end
91
+ end
92
+
93
+ def clone_app(name)
94
+ abort "Expected APP to be in [#{PagyApps::INDEX.keys.join(', ')}]; got #{name.inspect}" unless PagyApps::INDEX.key?(name)
95
+
96
+ if File.exist?(name)
97
+ print "Do you want to overwrite the #{name.inspect} file? (y/n)> "
98
+ answer = gets.chomp
99
+ abort "#{name.inspect} file already present" unless answer.start_with?(/y/i)
100
+ end
101
+ FileUtils.cp(PagyApps::INDEX[name], '.', verbose: true)
102
+ end
103
+
104
+ def serve_app(arg, options)
105
+ if PagyApps::INDEX.key?(arg)
106
+ options[:env] = 'showcase'
107
+ options[:quiet] = true
108
+ # Avoid the creation of './tmp/local_secret.txt' for showcase env
109
+ ENV['SECRET_KEY_BASE'] = 'absolute secret!' if arg.eql?('rails')
110
+ file = PagyApps::INDEX[arg]
111
+ else
112
+ file = arg
113
+ end
114
+ abort "#{file.inspect} app not found" unless File.exist?(file)
115
+
116
+ gem_dir = File.expand_path('../..', __dir__)
117
+ rackup = "rackup -I #{gem_dir}/lib -r pagy -o #{options[:host]} -p #{options[:port]} -E #{options[:env]} #{file}"
118
+ rackup << ' -q' if options[:quiet]
119
+
120
+ exec(rackup)
121
+ end
122
+
123
+ # Kept as a separate method because mocking 'gemfile' (dsl) is complex otherwise
124
+ def setup_gems(run_from_repo)
125
+ require 'bundler/inline'
126
+ gemfile(!run_from_repo) do
127
+ source 'https://rubygems.org'
128
+ gem 'logger'
129
+ gem 'rackup'
130
+ end
131
+ end
132
+ end
133
+ end
data/lib/pagy.rb CHANGED
@@ -8,7 +8,7 @@ require_relative 'pagy/toolbox/helpers/loader'
8
8
 
9
9
  # Top superclass: it defines only what's common to all the subclasses
10
10
  class Pagy
11
- VERSION = '43.2.1'
11
+ VERSION = '43.2.3'
12
12
  ROOT = Pathname.new(__dir__).parent.freeze
13
13
  DEFAULT = { limit: 20, limit_key: 'limit', page_key: 'page' }.freeze
14
14
  PAGE_TOKEN = EscapedValue.new('P ')
@@ -25,7 +25,7 @@
25
25
  --background-input: hsl(var(--H) var(--S) calc(var(--L) + (45 * var(--B))));
26
26
  --opacity: 1;
27
27
 
28
- @apply flex space-x-[var(--spacing)] font-[var(--font-weight)]
28
+ @apply flex gap-x-[var(--spacing)] font-[var(--font-weight)]
29
29
  text-[length:var(--font-size)] text-[var(--text)]
30
30
  leading-[var(--line-height)];
31
31
 
data/stylesheets/pagy.css CHANGED
@@ -28,12 +28,7 @@
28
28
  }
29
29
 
30
30
  .pagy > :not([hidden]) ~ :not([hidden]) {
31
- margin-left: calc(var(--spacing) * (1 - var(--space-reverse, 0)));
32
- margin-right: calc(var(--spacing) * var(--space-reverse, 0));
33
- }
34
-
35
- .rtl .pagy > :not([hidden]) ~ :not([hidden]) {
36
- --space-reverse: 1;
31
+ margin-inline-start: var(--spacing);
37
32
  }
38
33
 
39
34
  .pagy a:not([role="separator"]) { /* all but gaps */
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pagy
3
3
  version: !ruby/object:Gem::Version
4
- version: 43.2.1
4
+ version: 43.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Domizio Demichelis
@@ -48,13 +48,13 @@ files:
48
48
  - LICENSE.txt
49
49
  - apps/calendar.ru
50
50
  - apps/demo.ru
51
+ - apps/enable_rails_page_segment.rb
51
52
  - apps/index.rb
52
53
  - apps/keynav+root_key.ru
53
54
  - apps/keynav.ru
54
55
  - apps/keyset.ru
55
56
  - apps/keyset_sequel.ru
56
57
  - apps/rails.ru
57
- - apps/rails_page_segment.rb
58
58
  - apps/repro.ru
59
59
  - bin/pagy
60
60
  - config/pagy.rb
@@ -65,7 +65,6 @@ files:
65
65
  - javascripts/pagy.min.js
66
66
  - javascripts/pagy.mjs
67
67
  - javascripts/wand.js
68
- - lib/optimist.rb
69
68
  - lib/pagy.rb
70
69
  - lib/pagy/classes/calendar/calendar.rb
71
70
  - lib/pagy/classes/calendar/day.rb
@@ -84,6 +83,7 @@ files:
84
83
  - lib/pagy/classes/offset/offset.rb
85
84
  - lib/pagy/classes/offset/search.rb
86
85
  - lib/pagy/classes/request.rb
86
+ - lib/pagy/cli.rb
87
87
  - lib/pagy/console.rb
88
88
  - lib/pagy/modules/abilities/configurable.rb
89
89
  - lib/pagy/modules/abilities/countable.rb
@@ -202,7 +202,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
202
202
  - !ruby/object:Gem::Version
203
203
  version: '0'
204
204
  requirements: []
205
- rubygems_version: 3.6.9
205
+ rubygems_version: 4.0.3
206
206
  specification_version: 4
207
207
  summary: "Pagy \U0001F438 The Leaping Gem!"
208
208
  test_files: []
@@ -1,71 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # ################# IMPORTANT WARNING #################
4
- # Use this override ONLY if you strictly need to support the page param as a dynamic segment.
5
- # (e.g. get '/comments(/:page)', to: 'comments#index').
6
- #
7
- # This setup forces Pagy to use the Rails `url_for` method, which is significantly
8
- # slower (~20x) than Pagy's native URL generation.
9
- # #####################################################
10
-
11
- # 1. CONSTANT REDEFINITION
12
- # We must replace Pagy's internal tokens.
13
- # Why: Pagy marks its default tokens as "Escaped" to allow spaces into the URL template for safe interpolation.
14
- # Since we are handing control back to Rails' standard QueryUtils, we need simple, URL-safe placeholders
15
- # that Rails won't need to escape, to avoid mismatches between non-escaped and escaped tokens.
16
- Pagy.send(:remove_const, :PAGE_TOKEN)
17
- Pagy.send(:remove_const, :LIMIT_TOKEN)
18
-
19
- Pagy::PAGE_TOKEN = '___PAGY_PAGE___'
20
- Pagy::LIMIT_TOKEN = '___PAGY_LIMIT___'
21
-
22
- require 'pagy/toolbox/paginators/method'
23
- require 'pagy/modules/abilities/linkable'
24
-
25
- class Pagy
26
- # 2. REQUEST PARAMETERS
27
- # Why: Pagy defaults to Rack::Request to be framework agnostic.
28
- # To support dynamic segments (which are routing concepts, not query params),
29
- # we must switch to the Rails `request.params` method which includes path parameters.
30
- module RequestOverride
31
- def get_params(request)
32
- request.params
33
- end
34
- end
35
- Request.prepend RequestOverride
36
-
37
- # 3. CONTEXT INJECTION
38
- # Why: The Pagy object needs access to the Controller instance to call `url_for`.
39
- # We intercept the `pagy` method in the controller to inject `self` (the controller)
40
- # into the Pagy instance as `@context`.
41
- module MethodOverride
42
- def pagy(...)
43
- super.tap do |result|
44
- # result is [pagy_object, records]
45
- # We inject the controller (self) directly into the pagy object
46
- result[0].instance_variable_set(:@context, self)
47
- end
48
- end
49
- end
50
- Method.prepend MethodOverride
51
-
52
- # 4. URL GENERATION
53
- # Why: We override Pagy's optimized string interpolation with Rails' `url_for`.
54
- # We combine the current Rails parameters with Pagy's options and generate the URL.
55
- module LinkableOverride
56
- def compose_url(absolute, _path, params, fragment)
57
- params[:anchor] = fragment if fragment
58
- params[:only_path] = !absolute
59
-
60
- # Call the Rails url_for method from the controller context
61
- @context.url_for(params)
62
- end
63
- end
64
- Linkable.prepend LinkableOverride
65
- end
66
-
67
- # USAGE with rails.ru
68
-
69
- # Search and uncomment the following lines in the rails.ru app:
70
- # require_relative 'rails_page_segment' # Uncomment to test the rails_page_segment.rb override
71
- # get '/comments(/:page)', to: 'comments#index' # Uncomment to test the rails_page_segment.rb override