respondo 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f627c02a80d4eb8ab106714e2739d38b17545a93d1772e052497850c8a56f437
4
- data.tar.gz: 8f078c4540d8182fc59ccdc8c539b29835ccb9f7cf5d781b2ae389e0a9c04461
3
+ metadata.gz: fb5118a5648863ec54d68805d897485f40da5b81b9b628b9b9a08d6ee2f735d7
4
+ data.tar.gz: 4282b491b0bd587ba668e7accaf19f6dfb879cc61261d64d744de69c803ae8a0
5
5
  SHA512:
6
- metadata.gz: 4677d2d32eaa9441032829a6414cd81d24d831b61ce45e0fd3586c4d804745d9307a1bc375b280b0801d53812b6accb656ae28ac1c36dc858befa51c3098b2aa
7
- data.tar.gz: 937d964de71ac65cd5d13df236cf74012b390cee914c13b8078a653db7d7a2273037593fad1981df41a59280e3cba677f5ede00ea6992b07058b90a5456645f6
6
+ metadata.gz: 4ae4daae47ef9c2c66388fc6d8f3a915b66439208fafa25b7046234813229704de0e53863921f2b4e2100817218b2a315ef40a564c5f672a9848194e55814906
7
+ data.tar.gz: 86a9ecb6864c1bba75dc4d47941bd0f80c837f4dbc72ed424526e1dad3f05ead92b738a417a239f3fb160e7043fc465418fe6670948be147399ea90ee3ce85d8
data/CHANGELOG.md CHANGED
@@ -1,5 +1,74 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.1.0] — Interactive Install Generator
4
+
5
+ ### Added
6
+
7
+ #### `rails generate respondo:install` — interactive setup wizard
8
+ A new generator that walks developers through configuration interactively at
9
+ install time, writing a fully commented `config/initializers/respondo.rb` so
10
+ they never have to read the README to get started.
11
+
12
+ **Usage:**
13
+ ```bash
14
+ rails generate respondo:install
15
+ ```
16
+
17
+ **What the wizard collects:**
18
+
19
+ | Prompt | Config written |
20
+ |--------|---------------|
21
+ | Project / app name | Comment header in initializer |
22
+ | API version | Auto-added to `config.default_meta` |
23
+ | Default success message | `config.default_success_message` |
24
+ | Default error message | `config.default_error_message` |
25
+ | Include request ID? | `config.include_request_id` |
26
+ | Camelize keys? | `config.camelize_keys` |
27
+ | Extra global meta fields | `config.default_meta` (merged with api_version) |
28
+ | Custom serializer stub? | Commented example added to initializer |
29
+
30
+ **Example output — `config/initializers/respondo.rb`:**
31
+ ```ruby
32
+ # frozen_string_literal: true
33
+
34
+ # Respondo initializer — MyApp
35
+ # Generated by: rails generate respondo:install
36
+ # Respondo version: 2.1.0
37
+
38
+ Respondo.configure do |config|
39
+
40
+ # ── Messages ─────────────────────────────────────────────────────────
41
+ config.default_success_message = "Success"
42
+ config.default_error_message = "Something went wrong"
43
+
44
+ # ── Request ID ───────────────────────────────────────────────────────
45
+ config.include_request_id = true
46
+
47
+ # ── Key Format ───────────────────────────────────────────────────────
48
+ config.camelize_keys = true
49
+
50
+ # ── Global Meta ──────────────────────────────────────────────────────
51
+ config.default_meta = {
52
+ api_version: "v1",
53
+ platform: "mobile"
54
+ }
55
+
56
+ # ── Custom Serializer ────────────────────────────────────────────────
57
+ # config.serializer = ->(obj) { MySerializer.new(obj).as_json }
58
+
59
+ end
60
+ ```
61
+
62
+ **Generator file location:**
63
+ ```
64
+ lib/generators/respondo/install/install_generator.rb
65
+ ```
66
+
67
+ Rails auto-discovers this path — no manual require needed. Re-running the
68
+ generator overwrites the existing initializer with fresh answers.
69
+
70
+ ---
71
+
3
72
  ## [2.0.0] — Full HTTP Coverage
4
73
 
5
74
  ### Breaking Changes
data/README.md CHANGED
@@ -42,6 +42,78 @@ gem "respondo"
42
42
 
43
43
  ## Setup
44
44
 
45
+ ### ✅ Recommended — use the install generator
46
+
47
+ After adding the gem, run:
48
+
49
+ ```bash
50
+ rails generate respondo:install
51
+ ```
52
+
53
+ The interactive wizard walks you through every option and writes a fully commented `config/initializers/respondo.rb` tailored to your project. No need to read the full README or copy-paste config by hand.
54
+
55
+ ```
56
+ ┌─ Project Info ─────────────────────────────────────────────────────┐
57
+
58
+ Project / app name
59
+ (Used as a comment header in the initializer)
60
+ › [MyApp]:
61
+
62
+ API version (e.g. v1 — added to every response meta block)
63
+ › [v1]:
64
+
65
+ ┌─ Response Messages ────────────────────────────────────────────────┐
66
+
67
+ Default success message
68
+ › [Success]:
69
+
70
+ Default error message
71
+ › [An error occurred]:
72
+
73
+ ...
74
+ ```
75
+
76
+ The generator produces a file like this:
77
+
78
+ ```ruby
79
+ # frozen_string_literal: true
80
+
81
+ # Respondo initializer — MyApp
82
+ # Generated by: rails generate respondo:install
83
+ # Respondo version: 2.1.0
84
+
85
+ Respondo.configure do |config|
86
+
87
+ # ── Messages ─────────────────────────────────────────────────────────
88
+ config.default_success_message = "Success"
89
+ config.default_error_message = "Something went wrong"
90
+
91
+ # ── Request ID ───────────────────────────────────────────────────────
92
+ config.include_request_id = true
93
+
94
+ # ── Key Format ───────────────────────────────────────────────────────
95
+ config.camelize_keys = true
96
+
97
+ # ── Global Meta ──────────────────────────────────────────────────────
98
+ config.default_meta = {
99
+ api_version: "v1",
100
+ platform: "mobile"
101
+ }
102
+
103
+ # ── Custom Serializer ────────────────────────────────────────────────
104
+ # config.serializer = ->(obj) { MySerializer.new(obj).as_json }
105
+
106
+ end
107
+ ```
108
+
109
+ Re-run the generator any time to regenerate with different answers — it overwrites the existing initializer.
110
+
111
+ ---
112
+
113
+ ### Manual setup (alternative)
114
+
115
+ If you prefer to write the initializer yourself, create `config/initializers/respondo.rb`:
116
+
45
117
  ```ruby
46
118
  # config/initializers/respondo.rb
47
119
  Respondo.configure do |config|
@@ -770,13 +842,17 @@ class ApiResponse<T> {
770
842
  ```
771
843
  lib/
772
844
  ├── respondo.rb # Entry point, configure, Railtie hook
773
- └── respondo/
774
- ├── version.rb # VERSION
775
- ├── configuration.rb # Config with defaults
776
- ├── serializer.rb # Auto-detects and serializes any object
777
- ├── response_builder.rb # Assembles the final Hash
778
- ├── controller_helpers.rb # All render_* helpers (1xx–5xx)
779
- └── railtie.rb # Auto-includes into Rails controllers
845
+ ├── respondo/
846
+ ├── version.rb # VERSION
847
+ ├── configuration.rb # Config with defaults
848
+ ├── serializer.rb # Auto-detects and serializes any object
849
+ ├── response_builder.rb # Assembles the final Hash
850
+ ├── controller_helpers.rb # All render_* helpers (1xx–5xx)
851
+ └── railtie.rb # Auto-includes into Rails controllers
852
+ └── generators/
853
+ └── respondo/
854
+ └── install/
855
+ └── install_generator.rb # rails generate respondo:install
780
856
  ```
781
857
 
782
858
  ---
@@ -0,0 +1,350 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+
5
+ module Respondo
6
+ module Generators
7
+ class InstallGenerator < Rails::Generators::Base
8
+ desc "Interactive setup — creates config/initializers/respondo.rb with your preferences."
9
+
10
+ # We bypass Thor's `say` entirely for all display output and use
11
+ # $stdout.puts / print directly. This prevents Thor from re-echoing
12
+ # buffered output and causing duplicate lines in the terminal.
13
+
14
+ def run_interactive_setup
15
+ # out LOGO
16
+ out logo_with_version
17
+ out divider
18
+ out line(" This wizard will generate config/initializers/respondo.rb")
19
+ out line(" tailored to your project — no need to read the full README.")
20
+ out blank
21
+ out line(yellow(" All settings can be changed later by editing the initializer."))
22
+ out divider
23
+ out blank
24
+
25
+ unless confirm(" Ready to configure Respondo? (y/n) ")
26
+ out blank
27
+ out line(yellow(" Skipped. Run this again any time:"))
28
+ out line(" rails generate respondo:install")
29
+ out blank
30
+ return
31
+ end
32
+
33
+ @cfg = {}
34
+
35
+ step_project_info
36
+ step_messages
37
+ step_request_id
38
+ step_camelize
39
+ step_default_meta
40
+ step_serializer
41
+
42
+ print_summary
43
+ write_initializer
44
+ print_done
45
+ end
46
+
47
+ private
48
+
49
+ # =========================================================================
50
+ # Steps
51
+ # =========================================================================
52
+
53
+ def step_project_info
54
+ out section("Project Info")
55
+ out line(" Project / app name")
56
+ out line(yellow(" (Used as a comment header in the initializer)"))
57
+ @cfg[:project_name] = prompt_default(Rails.application.class.module_parent_name)
58
+
59
+ out blank
60
+ out line(" API version")
61
+ out line(yellow(" (e.g. v1 — added to every response meta block)"))
62
+ @cfg[:api_version] = prompt_default("v1")
63
+ end
64
+
65
+ def step_messages
66
+ out section("Response Messages")
67
+ out line(" Fallback messages used when you don't pass message: explicitly.")
68
+ out blank
69
+
70
+ out line(" Default success message")
71
+ @cfg[:default_success_message] = prompt_default("Success")
72
+
73
+ out blank
74
+ out line(" Default error message")
75
+ @cfg[:default_error_message] = prompt_default("An error occurred")
76
+ end
77
+
78
+ def step_request_id
79
+ out section("Request ID")
80
+ out line(" When enabled, Rails request.request_id is included in every")
81
+ out line(" response meta block — useful for log correlation and debugging.")
82
+ out blank
83
+ @cfg[:include_request_id] = confirm(" Include request_id in every response? (y/n) ")
84
+ end
85
+
86
+ def step_camelize
87
+ out section("Key Format")
88
+ out line(" When enabled, all JSON keys are camelCased:")
89
+ out line(yellow(' { "createdAt": "...", "userId": 1 }'))
90
+ out line(" Recommended for Flutter, React, and JavaScript clients.")
91
+ out blank
92
+ @cfg[:camelize_keys] = confirm(" Camelize all response keys? (y/n) ")
93
+ end
94
+
95
+ def step_default_meta
96
+ out section("Global Meta Fields")
97
+ out line(" Static key=value pairs merged into the meta block of EVERY response.")
98
+ out line(" Example: platform=mobile environment=production")
99
+ out blank
100
+ out line(yellow(" Note: api_version from above is already included automatically."))
101
+ out blank
102
+
103
+ @cfg[:default_meta] = {}
104
+ return unless confirm(" Add extra global meta fields? (y/n) ")
105
+
106
+ out blank
107
+ out line(" Enter key=value one at a time. Blank line to finish.")
108
+ out blank
109
+
110
+ loop do
111
+ $stdout.print cyan(" key=value › ")
112
+ raw = $stdin.gets.to_s.strip
113
+ break if raw.empty?
114
+
115
+ unless raw.include?("=")
116
+ out line(yellow(" Use key=value format (e.g. platform=mobile). Skipping."))
117
+ next
118
+ end
119
+
120
+ key, value = raw.split("=", 2)
121
+
122
+ next out line(yellow(" Use key=value format.")) if key.nil? || key.strip.empty?
123
+
124
+ k = key.strip
125
+ v = (value || "").strip
126
+ @cfg[:default_meta][k] = v
127
+ out line(green(" ✓ #{k}: #{v.inspect}"))
128
+ end
129
+ end
130
+
131
+ def step_serializer
132
+ out section("Custom Serializer")
133
+ out line(" By default Respondo serializes ActiveRecord models, collections,")
134
+ out line(" hashes, and arrays automatically.")
135
+ out blank
136
+ out line(" You can override with any callable: ->(obj) { MySerializer.new(obj).as_json }")
137
+ out blank
138
+ @cfg[:custom_serializer] = confirm(" Add a custom serializer stub? (y/n) ")
139
+ end
140
+
141
+ # =========================================================================
142
+ # Summary
143
+ # =========================================================================
144
+
145
+ def print_summary
146
+ out blank
147
+ out divider
148
+ out line(cyan(" Configuration Summary"))
149
+ out divider
150
+ out blank
151
+ summary_row "Project", @cfg[:project_name]
152
+ summary_row "API version", @cfg[:api_version]
153
+ summary_row "Success message", @cfg[:default_success_message]
154
+ summary_row "Error message", @cfg[:default_error_message]
155
+ summary_row "Include request_id", @cfg[:include_request_id]
156
+ summary_row "Camelize keys", @cfg[:camelize_keys]
157
+ summary_row "Custom serializer", @cfg[:custom_serializer]
158
+
159
+ unless @cfg[:default_meta].empty?
160
+ out blank
161
+ out line(" Global meta:")
162
+ @cfg[:default_meta].each { |k, v| out line(" #{k}: #{v.inspect}") }
163
+ end
164
+
165
+ out blank
166
+ out divider
167
+ out blank
168
+ end
169
+
170
+ def summary_row(label, value)
171
+ bool_true = value == true
172
+ val_str = bool_true ? green(value.inspect) : yellow(value.inspect)
173
+ out " #{("#{label}:").ljust(24)}#{val_str}\n"
174
+ end
175
+
176
+ # =========================================================================
177
+ # Write file
178
+ # =========================================================================
179
+
180
+ def write_initializer
181
+ dir = File.join(destination_root, "config", "initializers")
182
+ path = File.join(dir, "respondo.rb")
183
+ FileUtils.mkdir_p(dir)
184
+ File.write(path, build_content)
185
+ out line(green(" ✅ Created config/initializers/respondo.rb"))
186
+ out blank
187
+ end
188
+
189
+ def build_content
190
+ meta = { "api_version" => @cfg[:api_version] }.merge(@cfg[:default_meta])
191
+ b = Lines.new
192
+
193
+ b << "# frozen_string_literal: true"
194
+ b << ""
195
+ b << "# Respondo initializer — #{@cfg[:project_name]}"
196
+ b << "# Generated by: rails generate respondo:install"
197
+ b << "# Respondo version: #{Respondo::VERSION}"
198
+ b << "# Docs: https://github.com/your-org/respondo"
199
+ b << ""
200
+ b << "Respondo.configure do |config|"
201
+ b << ""
202
+ b << " # ── Messages ─────────────────────────────────────────────────────────"
203
+ b << " # Fallback when render_success / render_error is called without message:"
204
+ b << " config.default_success_message = #{@cfg[:default_success_message].inspect}"
205
+ b << " config.default_error_message = #{@cfg[:default_error_message].inspect}"
206
+ b << ""
207
+ b << " # ── Request ID ───────────────────────────────────────────────────────"
208
+ b << " # Includes Rails request.request_id in every response meta block."
209
+ b << " config.include_request_id = #{@cfg[:include_request_id]}"
210
+ b << ""
211
+ b << " # ── Key Format ───────────────────────────────────────────────────────"
212
+ b << " # CamelCase all JSON keys — recommended for Flutter / JS clients."
213
+ b << " config.camelize_keys = #{@cfg[:camelize_keys]}"
214
+ b << ""
215
+ b << " # ── Global Meta ──────────────────────────────────────────────────────"
216
+ b << " # Static fields merged into the meta block of every response."
217
+
218
+ if meta.empty?
219
+ b << " config.default_meta = {}"
220
+ else
221
+ b << " config.default_meta = {"
222
+ meta.each_with_index do |(k, v), i|
223
+ comma = i < meta.size - 1 ? "," : ""
224
+ b << " #{k}: #{v.inspect}#{comma}"
225
+ end
226
+ b << " }"
227
+ end
228
+
229
+ if @cfg[:custom_serializer]
230
+ b << ""
231
+ b << " # ── Custom Serializer ────────────────────────────────────────────────"
232
+ b << " # Replace the lambda body with your own serialization logic."
233
+ b << " # Examples:"
234
+ b << " # ActiveModelSerializers: ->(obj) { SomeSerializer.new(obj).as_json }"
235
+ b << " # Blueprinter: ->(obj) { UserBlueprint.render_as_hash(obj) }"
236
+ b << " #"
237
+ b << " # config.serializer = ->(obj) { MySerializer.new(obj).as_json }"
238
+ end
239
+
240
+ b << ""
241
+ b << "end"
242
+ b << ""
243
+ b.to_s
244
+ end
245
+
246
+ # =========================================================================
247
+ # Done
248
+ # =========================================================================
249
+
250
+ def print_done
251
+ out divider
252
+ out blank
253
+ out line(cyan(" 🎉 Respondo is ready!"))
254
+ out blank
255
+ out line(" Next steps:")
256
+ out line(" 1. Review config/initializers/respondo.rb")
257
+ out line(" 2. Use render_success / render_error in your controllers")
258
+ out line(" 3. Re-run rails generate respondo:install to regenerate")
259
+ out blank
260
+ out divider
261
+ out blank
262
+ end
263
+
264
+ # =========================================================================
265
+ # Output primitives — all output goes through $stdout, never through Thor
266
+ # =========================================================================
267
+
268
+ def out(str)
269
+ $stdout.print str
270
+ $stdout.flush
271
+ end
272
+
273
+ def line(str) = "#{str}\n"
274
+ def blank = "\n"
275
+
276
+ def divider
277
+ " #{cyan("─" * 68)}\n"
278
+ end
279
+
280
+ def section(title)
281
+ dashes = "─" * [0, 54 - title.length].max
282
+ "\n #{cyan("┌─ #{title} #{dashes}┐")}\n\n"
283
+ end
284
+
285
+ def prompt_default(default)
286
+ $stdout.print " #{cyan("›")} #{yellow("[#{default}]")}: "
287
+ $stdout.flush
288
+ result = $stdin.gets.to_s.strip
289
+ result.empty? ? default.to_s : result
290
+ end
291
+
292
+ def confirm(question)
293
+ $stdout.print question
294
+ $stdout.flush
295
+ $stdin.gets.to_s.strip.downcase.start_with?("y")
296
+ end
297
+
298
+ # =========================================================================
299
+ # ANSI colors
300
+ # =========================================================================
301
+
302
+ def cyan(t) = "\e[36m#{t}\e[0m"
303
+ def green(t) = "\e[32m#{t}\e[0m"
304
+ def yellow(t) = "\e[33m#{t}\e[0m"
305
+
306
+ # =========================================================================
307
+ # ASCII logo
308
+ # =========================================================================
309
+
310
+ LOGOS = <<~'LOGO'
311
+
312
+ ██████╗ ███████╗███████╗██████╗ ██████╗ ███╗ ██╗██████╗ ██████╗
313
+ ██╔══██╗██╔════╝██╔════╝██╔══██╗██╔═══██╗████╗ ██║██╔══██╗██╔═══██╗
314
+ ██████╔╝█████╗ ███████╗██████╔╝██║ ██║██╔██╗ ██║██║ ██║██║ ██║
315
+ ██╔══██╗██╔══╝ ╚════██║██╔═══╝ ██║ ██║██║╚██╗██║██║ ██║██║ ██║
316
+ ██║ ██║███████╗███████║██║ ╚██████╔╝██║ ╚████║██████╔╝╚██████╔╝
317
+ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚═════╝ ╚═════╝
318
+
319
+ Smart JSON API Response Formatter for Rails
320
+ ─── v#{Respondo::VERSION} ───
321
+
322
+ LOGO
323
+
324
+ def logo_with_version
325
+ green(<<~LOGO)
326
+
327
+ ██████╗ ███████╗███████╗██████╗ ██████╗ ███╗ ██╗██████╗ ██████╗
328
+ ██╔══██╗██╔════╝██╔════╝██╔══██╗██╔═══██╗████╗ ██║██╔══██╗██╔═══██╗
329
+ ██████╔╝█████╗ ███████╗██████╔╝██║ ██║██╔██╗ ██║██║ ██║██║ ██║
330
+ ██╔══██╗██╔══╝ ╚════██║██╔═══╝ ██║ ██║██║╚██╗██║██║ ██║██║ ██║
331
+ ██║ ██║███████╗███████║██║ ╚██████╔╝██║ ╚████║██████╔╝╚██████╔╝
332
+ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚═════╝ ╚═════╝
333
+
334
+ Smart JSON API Response Formatter for Rails
335
+ ─── v#{Respondo::VERSION} ───
336
+
337
+ LOGO
338
+ end
339
+ # =========================================================================
340
+ # Simple line buffer for building file content
341
+ # =========================================================================
342
+
343
+ class Lines
344
+ def initialize = (@buf = [])
345
+ def <<(str) = @buf << str
346
+ def to_s = @buf.join("\n") + "\n"
347
+ end
348
+ end
349
+ end
350
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Respondo
4
- VERSION = "2.0.0"
4
+ VERSION = "2.1.0"
5
5
  end
data/respondo.gemspec CHANGED
@@ -19,11 +19,20 @@ Gem::Specification.new do |spec|
19
19
  spec.license = "MIT"
20
20
  spec.required_ruby_version = ">= 2.7.0"
21
21
 
22
+ spec.metadata = {
23
+ "homepage_uri" => spec.homepage,
24
+ "source_code_uri" => spec.homepage,
25
+ "changelog_uri" => "#{spec.homepage}/blob/main/CHANGELOG.md",
26
+ "bug_tracker_uri" => "#{spec.homepage}/auditron/issues",
27
+ "rubygems_mfa_required" => "true"
28
+ }
29
+
22
30
  spec.files = Dir["lib/**/*.rb", "README.md", "LICENSE.txt", "CHANGELOG.md", "respondo.gemspec"]
23
31
  spec.require_paths = ["lib"]
24
32
 
25
- spec.add_development_dependency "rspec", "~> 3.12"
26
- spec.add_development_dependency "rake", "~> 13.0"
27
- spec.add_development_dependency "activesupport","~> 7.0"
28
- spec.add_development_dependency 'simplecov', '~> 0.22'
33
+ spec.add_development_dependency "railties", "~> 8.1.3"
34
+ spec.add_development_dependency "rspec", "~> 3.12"
35
+ spec.add_development_dependency "rake", "~> 13.0"
36
+ spec.add_development_dependency "activesupport", "~> 8.1.3"
37
+ spec.add_development_dependency 'simplecov', "~> 0.22"
29
38
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: respondo
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - shailendra Kumar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-04-08 00:00:00.000000000 Z
11
+ date: 2026-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: railties
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 8.1.3
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 8.1.3
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: rspec
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,14 +58,14 @@ dependencies:
44
58
  requirements:
45
59
  - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: '7.0'
61
+ version: 8.1.3
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: '7.0'
68
+ version: 8.1.3
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: simplecov
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -80,10 +94,10 @@ files:
80
94
  - CHANGELOG.md
81
95
  - LICENSE.txt
82
96
  - README.md
97
+ - lib/generators/respondo/install/install_generator.rb
83
98
  - lib/respondo.rb
84
99
  - lib/respondo/configuration.rb
85
100
  - lib/respondo/controller_helpers.rb
86
- - lib/respondo/pagination.rb
87
101
  - lib/respondo/railtie.rb
88
102
  - lib/respondo/response_builder.rb
89
103
  - lib/respondo/serializer.rb
@@ -92,7 +106,12 @@ files:
92
106
  homepage: https://github.com/spatelpatidar/respondo
93
107
  licenses:
94
108
  - MIT
95
- metadata: {}
109
+ metadata:
110
+ homepage_uri: https://github.com/spatelpatidar/respondo
111
+ source_code_uri: https://github.com/spatelpatidar/respondo
112
+ changelog_uri: https://github.com/spatelpatidar/respondo/blob/main/CHANGELOG.md
113
+ bug_tracker_uri: https://github.com/spatelpatidar/respondo/auditron/issues
114
+ rubygems_mfa_required: 'true'
96
115
  post_install_message:
97
116
  rdoc_options: []
98
117
  require_paths:
@@ -1,152 +0,0 @@
1
- # # frozen_string_literal: true
2
-
3
- # module Respondo
4
- # # Extracts pagination metadata from Kaminari, Pagy, or WillPaginate collections.
5
- # #
6
- # # --- How pagination works in Respondo ---
7
- # #
8
- # # Respondo does NOT paginate data for you. Pagination is always performed by
9
- # # your chosen library (Kaminari, Pagy, or WillPaginate) in your controller
10
- # # BEFORE you call render_success / render_ok.
11
- # #
12
- # # Respondo's role is purely to DETECT that the collection is paginated and
13
- # # EXTRACT the metadata so it appears in the `meta.pagination` block.
14
- # #
15
- # # --- Usage patterns by library ---
16
- # #
17
- # # Kaminari (pagination lives on the collection itself):
18
- # # @users = User.page(params[:page]).per(params[:per_page] || 10)
19
- # # render_ok(data: @users) # ← just pass the collection; Respondo detects Kaminari
20
- # #
21
- # # WillPaginate (same — pagination lives on the collection):
22
- # # @users = User.paginate(page: params[:page], per_page: 10)
23
- # # render_ok(data: @users) # ← same pattern
24
- # #
25
- # # Pagy (metadata lives on a SEPARATE Pagy object, not the collection):
26
- # # @pagy, @users = pagy(User.all, items: 10)
27
- # # render_ok(data: @users, pagy: @pagy) # ← pass the Pagy object explicitly
28
- # #
29
- # # Alternatively, if you decorate your collection with pagy_metadata:
30
- # # render_ok(data: @pagy) # ← pass the Pagy object as data (unusual)
31
- # #
32
- # # --- Returned hash shape (same regardless of library) ---
33
- # # {
34
- # # current_page: Integer,
35
- # # per_page: Integer,
36
- # # total_pages: Integer,
37
- # # total_count: Integer,
38
- # # next_page: Integer | nil,
39
- # # prev_page: Integer | nil
40
- # # }
41
- # #
42
- # # --- Disabling pagination meta ---
43
- # # Pass pagination: false to any render_* helper to suppress the block entirely:
44
- # # render_ok(data: @users, pagination: false)
45
- # #
46
- # module Pagination
47
- # module_function
48
-
49
- # # @param collection [Object] any object — returns nil if not a paginated collection
50
- # # @return [Hash, nil]
51
- # def extract(collection)
52
- # return nil if collection.nil?
53
-
54
- # if pagy?(collection)
55
- # from_pagy(collection)
56
- # elsif kaminari?(collection)
57
- # from_kaminari(collection)
58
- # elsif will_paginate?(collection)
59
- # from_will_paginate(collection)
60
- # else
61
- # nil
62
- # end
63
- # end
64
-
65
- # private
66
-
67
- # module_function
68
-
69
- # # -------------------------------------------------------------------------
70
- # # Pagy
71
- # # -------------------------------------------------------------------------
72
- # # Pagy stores metadata on a SEPARATE Pagy object, not the collection.
73
- # # You must pass it explicitly via the `pagy:` keyword in render_success/render_ok.
74
- # #
75
- # # Example in controller:
76
- # # @pagy, @records = pagy(User.all, items: 10)
77
- # # render_ok(data: @records, pagy: @pagy)
78
- # #
79
- # def pagy?(object)
80
- # defined?(Pagy) && object.is_a?(Pagy)
81
- # end
82
-
83
- # def from_pagy(pagy)
84
- # {
85
- # current_page: pagy.page,
86
- # per_page: pagy.items,
87
- # total_pages: pagy.pages,
88
- # total_count: pagy.count,
89
- # next_page: pagy.next,
90
- # prev_page: pagy.prev
91
- # }
92
- # end
93
-
94
- # # -------------------------------------------------------------------------
95
- # # Kaminari
96
- # # -------------------------------------------------------------------------
97
- # # Kaminari attaches pagination directly to the ActiveRecord relation.
98
- # # No extra argument needed — just pass the collection.
99
- # #
100
- # # Example in controller:
101
- # # @records = User.page(params[:page]).per(10)
102
- # # render_ok(data: @records)
103
- # #
104
- # def kaminari?(object)
105
- # object.respond_to?(:current_page) &&
106
- # object.respond_to?(:total_pages) &&
107
- # object.respond_to?(:limit_value)
108
- # end
109
-
110
- # def from_kaminari(collection)
111
- # {
112
- # current_page: collection.current_page,
113
- # per_page: collection.limit_value,
114
- # total_pages: collection.total_pages,
115
- # total_count: collection.total_count,
116
- # next_page: collection.next_page,
117
- # prev_page: collection.prev_page
118
- # }
119
- # end
120
-
121
- # # -------------------------------------------------------------------------
122
- # # WillPaginate
123
- # # -------------------------------------------------------------------------
124
- # # WillPaginate also attaches pagination to the collection.
125
- # # No extra argument needed — just pass the collection.
126
- # #
127
- # # Example in controller:
128
- # # @records = User.paginate(page: params[:page], per_page: 10)
129
- # # render_ok(data: @records)
130
- # #
131
- # # We distinguish WillPaginate from Kaminari by the absence of #limit_value.
132
- # #
133
- # def will_paginate?(object)
134
- # object.respond_to?(:current_page) &&
135
- # object.respond_to?(:total_pages) &&
136
- # object.respond_to?(:per_page) &&
137
- # !object.respond_to?(:limit_value)
138
- # end
139
-
140
- # def from_will_paginate(collection)
141
- # {
142
- # current_page: collection.current_page,
143
- # per_page: collection.per_page,
144
- # total_pages: collection.total_pages,
145
- # total_count: collection.total_entries,
146
- # next_page: collection.next_page,
147
- # prev_page: collection.previous_page
148
- # }
149
- # end
150
- # end
151
- # end
152
-