bidi2pdf-rails 0.0.1.pre.alpha → 0.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 +4 -4
- data/.idea/bidi2pdf-rails.iml +55 -9
- data/.rubocop.yml +14 -0
- data/CHANGELOG.md +33 -0
- data/README.md +117 -27
- data/Rakefile +2 -0
- data/cliff.toml +126 -0
- data/lib/bidi2pdf_rails/browser_console_log_subscriber.rb +24 -0
- data/lib/bidi2pdf_rails/chromedriver_manager_singleton.rb +11 -11
- data/lib/bidi2pdf_rails/config.rb +133 -0
- data/lib/bidi2pdf_rails/configurable.rb +106 -0
- data/lib/bidi2pdf_rails/main_log_subscriber.rb +33 -0
- data/lib/bidi2pdf_rails/network_log_subscriber.rb +20 -0
- data/lib/bidi2pdf_rails/railtie.rb +12 -45
- data/lib/bidi2pdf_rails/services/html_renderer.rb +33 -0
- data/lib/bidi2pdf_rails/services/html_to_pdf_converter.rb +28 -0
- data/lib/bidi2pdf_rails/services/pdf_browser_session.rb +39 -0
- data/lib/bidi2pdf_rails/services/pdf_renderer.rb +82 -0
- data/lib/bidi2pdf_rails/services/url_to_pdf_converter.rb +82 -0
- data/lib/bidi2pdf_rails/version.rb +1 -1
- data/lib/bidi2pdf_rails.rb +41 -58
- data/lib/generators/bidi2pdf_rails/USAGE +12 -4
- data/lib/generators/bidi2pdf_rails/initializer_generator.rb +136 -30
- data/lib/generators/bidi2pdf_rails/templates/bidi2pdf_rails.rb.tt +25 -79
- data/spec/acceptance/user_can_download_report_pdf_spec.rb +133 -0
- data/spec/acceptance/user_can_generate_pdf_from_protected_remote_url_spec.rb +173 -0
- data/spec/dummy/app/controllers/reports_controller.rb +37 -0
- data/spec/dummy/app/controllers/secure_controller.rb +52 -0
- data/spec/dummy/app/views/layouts/simple.html.erb +17 -0
- data/spec/dummy/app/views/secure/show.html.erb +10 -0
- data/spec/dummy/config/environments/production.rb +1 -1
- data/spec/dummy/config/initializers/bidi2pdf_rails.rb +68 -54
- data/spec/dummy/config/initializers/cors.rb +1 -1
- data/spec/dummy/config/routes.rb +10 -0
- data/spec/dummy/log/development.log +16567 -156
- data/spec/dummy/log/test.log +53046 -0
- data/spec/dummy/tmp/pids/server.pid +1 -1
- data/spec/integration/generators/bidi2pdf_rails/initializer_generator_spec.rb +64 -0
- data/spec/rails_helper.rb +8 -1
- data/spec/spec_helper.rb +47 -5
- data/spec/support/default_dirs_helper.rb +32 -0
- data/spec/support/pdf_helper.rb +12 -0
- data/spec/support/render_setting_helpers.rb +28 -0
- data/spec/support/request_server_bootstrap.rb +44 -0
- data/spec/{bidi2pdf_rails → unit/bidi2pdf_rails}/bidi2pdf_rails_spec.rb +1 -1
- data/spec/unit/bidi2pdf_rails/configurable/base_nested_config_spec.rb +133 -0
- data/tasks/changelog.rake +29 -0
- data/tasks/coverage.rake +23 -0
- metadata +95 -25
- data/lib/bidi2pdf_rails/log_subscriber.rb +0 -13
- data/spec/dummy/spec/helpers/reports_helper_spec.rb +0 -15
- data/spec/dummy/spec/requests/reports_spec.rb +0 -10
- data/spec/dummy/spec/views/reports/show.html.erb_spec.rb +0 -5
- data/spec/generator/bidie2pdf_rails_initializer_generator_spec.rb +0 -5
- data/spec/generator/initializer_generator_spec.rb +0 -5
- data/spec/requests/reports_spec.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d0aa5d0b7d83ed5324b0a8669672f08d7a3e7b22dc7f9d51994f59e4d503df5
|
4
|
+
data.tar.gz: 928af8b8e8646b13c027cf2fb88ca216f53d37abc808c325733e18ee1011e1b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 01abea76bf14ed10a93abe22394621df080e864024ad828de8a7edcf36eed62b12f008e02db06cf6e0b2449408132467df90415918473eabb55bbeb1ca6c91f8
|
7
|
+
data.tar.gz: 0b99cbcb01e48f2577e0da652b5a20f6720bbd11feb6e0dc06bea684e4d5c40e8d94b4c72c83862e498ade59050c1ef72bb28902f1f334c0f250821854391fd3
|
data/.idea/bidi2pdf-rails.iml
CHANGED
@@ -102,6 +102,7 @@
|
|
102
102
|
</excluded>
|
103
103
|
</library>
|
104
104
|
</orderEntry>
|
105
|
+
<orderEntry type="library" scope="PROVIDED" name="Ascii85 (v2.0.1, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
105
106
|
<orderEntry type="library" scope="PROVIDED" name="actioncable (v7.2.2.1, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
106
107
|
<orderEntry type="library" scope="PROVIDED" name="actionmailbox (v7.2.2.1, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
107
108
|
<orderEntry type="library" scope="PROVIDED" name="actionmailer (v7.2.2.1, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
@@ -113,6 +114,8 @@
|
|
113
114
|
<orderEntry type="library" scope="PROVIDED" name="activerecord (v7.2.2.1, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
114
115
|
<orderEntry type="library" scope="PROVIDED" name="activestorage (v7.2.2.1, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
115
116
|
<orderEntry type="library" scope="PROVIDED" name="activesupport (v7.2.2.1, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
117
|
+
<orderEntry type="library" scope="PROVIDED" name="afm (v0.2.2, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
118
|
+
<orderEntry type="library" scope="PROVIDED" name="ammeter (v1.1.7, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
116
119
|
<orderEntry type="library" scope="PROVIDED" name="ast (v2.4.3, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
117
120
|
<orderEntry type="library" scope="PROVIDED" name="benchmark (v0.4.0, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
118
121
|
<orderEntry type="library" scope="PROVIDED" name="bigdecimal (v3.1.9, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
@@ -128,8 +131,9 @@
|
|
128
131
|
<orderEntry type="library" scope="PROVIDED" name="drb (v2.2.1, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
129
132
|
<orderEntry type="library" scope="PROVIDED" name="erubi (v1.13.1, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
130
133
|
<orderEntry type="library" scope="PROVIDED" name="event_emitter (v0.2.6, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
131
|
-
<orderEntry type="library" scope="PROVIDED" name="ffi (v1.17.
|
134
|
+
<orderEntry type="library" scope="PROVIDED" name="ffi (v1.17.2, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
132
135
|
<orderEntry type="library" scope="PROVIDED" name="globalid (v1.2.1, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
136
|
+
<orderEntry type="library" scope="PROVIDED" name="hashery (v2.1.2, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
133
137
|
<orderEntry type="library" scope="PROVIDED" name="i18n (v1.14.7, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
134
138
|
<orderEntry type="library" scope="PROVIDED" name="io-console (v0.8.0, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
135
139
|
<orderEntry type="library" scope="PROVIDED" name="irb (v1.15.2, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
@@ -148,8 +152,9 @@
|
|
148
152
|
<orderEntry type="library" scope="PROVIDED" name="net-smtp (v0.5.1, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
149
153
|
<orderEntry type="library" scope="PROVIDED" name="nio4r (v2.7.4, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
150
154
|
<orderEntry type="library" scope="PROVIDED" name="nokogiri (v1.18.7, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
151
|
-
<orderEntry type="library" scope="PROVIDED" name="parallel (v1.
|
155
|
+
<orderEntry type="library" scope="PROVIDED" name="parallel (v1.27.0, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
152
156
|
<orderEntry type="library" scope="PROVIDED" name="parser (v3.3.8.0, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
157
|
+
<orderEntry type="library" scope="PROVIDED" name="pdf-reader (v2.14.1, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
153
158
|
<orderEntry type="library" scope="PROVIDED" name="pp (v0.6.2, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
154
159
|
<orderEntry type="library" scope="PROVIDED" name="prism (v1.4.0, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
155
160
|
<orderEntry type="library" scope="PROVIDED" name="propshaft (v1.1.0, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
@@ -181,8 +186,9 @@
|
|
181
186
|
<orderEntry type="library" scope="PROVIDED" name="rubocop-rails (v2.31.0, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
182
187
|
<orderEntry type="library" scope="PROVIDED" name="rubocop-rails-omakase (v1.1.0, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
183
188
|
<orderEntry type="library" scope="PROVIDED" name="rubocop-rake (v0.7.1, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
184
|
-
<orderEntry type="library" scope="PROVIDED" name="rubocop-rspec (v3.
|
189
|
+
<orderEntry type="library" scope="PROVIDED" name="rubocop-rspec (v3.6.0, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
185
190
|
<orderEntry type="library" scope="PROVIDED" name="ruby-progressbar (v1.13.0, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
191
|
+
<orderEntry type="library" scope="PROVIDED" name="ruby-rc4 (v0.1.5, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
186
192
|
<orderEntry type="library" scope="PROVIDED" name="rubyzip (v2.4.1, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
187
193
|
<orderEntry type="library" scope="PROVIDED" name="securerandom (v0.4.1, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
188
194
|
<orderEntry type="library" scope="PROVIDED" name="simplecov (v0.22.0, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
@@ -192,14 +198,17 @@
|
|
192
198
|
<orderEntry type="library" scope="PROVIDED" name="sys-proctable (v1.3.0, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
193
199
|
<orderEntry type="library" scope="PROVIDED" name="thor (v1.3.2, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
194
200
|
<orderEntry type="library" scope="PROVIDED" name="timeout (v0.4.3, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
201
|
+
<orderEntry type="library" scope="PROVIDED" name="ttfunk (v1.8.0, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
195
202
|
<orderEntry type="library" scope="PROVIDED" name="tzinfo (v2.0.6, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
196
203
|
<orderEntry type="library" scope="PROVIDED" name="unicode-display_width (v3.1.4, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
197
204
|
<orderEntry type="library" scope="PROVIDED" name="unicode-emoji (v4.0.4, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
205
|
+
<orderEntry type="library" scope="PROVIDED" name="unicode_utils (v1.4.0, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
198
206
|
<orderEntry type="library" scope="PROVIDED" name="useragent (v0.16.11, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
199
207
|
<orderEntry type="library" scope="PROVIDED" name="websocket (v1.2.11, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
200
208
|
<orderEntry type="library" scope="PROVIDED" name="websocket-client-simple (v0.9.0, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
201
209
|
<orderEntry type="library" scope="PROVIDED" name="websocket-driver (v0.7.7, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
202
210
|
<orderEntry type="library" scope="PROVIDED" name="websocket-extensions (v0.1.5, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
211
|
+
<orderEntry type="library" scope="PROVIDED" name="websocket-native (v1.0.0, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
203
212
|
<orderEntry type="library" scope="PROVIDED" name="zeitwerk (v2.7.2, RVM: ruby-3.3.4 [bidi2pdf-rails]) [gem]" level="application" />
|
204
213
|
</component>
|
205
214
|
<component name="RailsGeneratorsCache">
|
@@ -338,9 +347,6 @@
|
|
338
347
|
<entry key="config">
|
339
348
|
<value>file://$MODULE_DIR$/config</value>
|
340
349
|
</entry>
|
341
|
-
<entry key="config/cable">
|
342
|
-
<value>file://$MODULE_DIR$/config/cable.yml</value>
|
343
|
-
</entry>
|
344
350
|
<entry key="config/database">
|
345
351
|
<value>file://$MODULE_DIR$/config/database.yml</value>
|
346
352
|
</entry>
|
@@ -362,9 +368,6 @@
|
|
362
368
|
<entry key="config/routes.rb">
|
363
369
|
<value>file://$MODULE_DIR$/config/routes.rb</value>
|
364
370
|
</entry>
|
365
|
-
<entry key="config/secrets">
|
366
|
-
<value>file://$MODULE_DIR$/config</value>
|
367
|
-
</entry>
|
368
371
|
<entry key="db">
|
369
372
|
<value>file://$MODULE_DIR$/db</value>
|
370
373
|
</entry>
|
@@ -398,6 +401,9 @@
|
|
398
401
|
<entry key="public/stylesheets">
|
399
402
|
<value>file://$MODULE_DIR$/public/stylesheets</value>
|
400
403
|
</entry>
|
404
|
+
<entry key="test/mailers/previews">
|
405
|
+
<value>file://$MODULE_DIR$/test/mailers/previews</value>
|
406
|
+
</entry>
|
401
407
|
<entry key="tmp">
|
402
408
|
<value>file://$MODULE_DIR$/tmp</value>
|
403
409
|
</entry>
|
@@ -408,4 +414,44 @@
|
|
408
414
|
<value>file://$MODULE_DIR$/vendor/assets</value>
|
409
415
|
</entry>
|
410
416
|
</component>
|
417
|
+
<component name="RakeTasksCache-v2">
|
418
|
+
<option name="myRootTask">
|
419
|
+
<RakeTaskImpl id="rake">
|
420
|
+
<subtasks>
|
421
|
+
<RakeTaskImpl description="Build bidi2pdf-rails-0.0.1.alpha.1.gem into the pkg directory" fullCommand="build" id="build" />
|
422
|
+
<RakeTaskImpl id="build">
|
423
|
+
<subtasks>
|
424
|
+
<RakeTaskImpl description="Generate SHA512 checksum of bidi2pdf-rails-0.0.1.alpha.1.gem into the checksums directory" fullCommand="build:checksum" id="checksum" />
|
425
|
+
</subtasks>
|
426
|
+
</RakeTaskImpl>
|
427
|
+
<RakeTaskImpl description="Remove any temporary products" fullCommand="clean" id="clean" />
|
428
|
+
<RakeTaskImpl description="Remove any generated files" fullCommand="clobber" id="clobber" />
|
429
|
+
<RakeTaskImpl description="Build and install bidi2pdf-rails-0.0.1.alpha.1.gem into system gems" fullCommand="install" id="install" />
|
430
|
+
<RakeTaskImpl id="install">
|
431
|
+
<subtasks>
|
432
|
+
<RakeTaskImpl description="Build and install bidi2pdf-rails-0.0.1.alpha.1.gem into system gems without network access" fullCommand="install:local" id="local" />
|
433
|
+
</subtasks>
|
434
|
+
</RakeTaskImpl>
|
435
|
+
<RakeTaskImpl description="Create tag v0.0.1.alpha.1 and build and push bidi2pdf-rails-0.0.1.alpha.1.gem to https://rubygems.org" fullCommand="release[remote]" id="release[remote]" />
|
436
|
+
<RakeTaskImpl description="Run RuboCop" fullCommand="rubocop" id="rubocop" />
|
437
|
+
<RakeTaskImpl id="rubocop">
|
438
|
+
<subtasks>
|
439
|
+
<RakeTaskImpl description="Autocorrect RuboCop offenses (only when it's safe)" fullCommand="rubocop:autocorrect" id="autocorrect" />
|
440
|
+
<RakeTaskImpl description="Autocorrect RuboCop offenses (safe and unsafe)" fullCommand="rubocop:autocorrect_all" id="autocorrect_all" />
|
441
|
+
<RakeTaskImpl description="" fullCommand="rubocop:auto_correct" id="auto_correct" />
|
442
|
+
</subtasks>
|
443
|
+
</RakeTaskImpl>
|
444
|
+
<RakeTaskImpl description="Run RSpec code examples" fullCommand="spec" id="spec" />
|
445
|
+
<RakeTaskImpl description="" fullCommand="release" id="release" />
|
446
|
+
<RakeTaskImpl id="release">
|
447
|
+
<subtasks>
|
448
|
+
<RakeTaskImpl description="" fullCommand="release:guard_clean" id="guard_clean" />
|
449
|
+
<RakeTaskImpl description="" fullCommand="release:rubygem_push" id="rubygem_push" />
|
450
|
+
<RakeTaskImpl description="" fullCommand="release:source_control_push" id="source_control_push" />
|
451
|
+
</subtasks>
|
452
|
+
</RakeTaskImpl>
|
453
|
+
</subtasks>
|
454
|
+
</RakeTaskImpl>
|
455
|
+
</option>
|
456
|
+
</component>
|
411
457
|
</module>
|
data/.rubocop.yml
CHANGED
@@ -50,9 +50,18 @@ Layout/BeginEndAlignment:
|
|
50
50
|
Layout/ArrayAlignment:
|
51
51
|
Enabled: false
|
52
52
|
|
53
|
+
Layout/ElseAlignment:
|
54
|
+
Enabled: false
|
55
|
+
|
56
|
+
Layout/EndAlignment:
|
57
|
+
Enabled: false
|
58
|
+
|
53
59
|
Layout/LineLength:
|
54
60
|
Enabled: false
|
55
61
|
|
62
|
+
Layout/SpaceInsideArrayLiteralBrackets:
|
63
|
+
EnforcedStyle: no_space
|
64
|
+
|
56
65
|
RSpec/MultipleMemoizedHelpers:
|
57
66
|
Max: 10
|
58
67
|
|
@@ -85,6 +94,11 @@ RSpec/DescribeClass:
|
|
85
94
|
Exclude:
|
86
95
|
- 'spec/acceptance/**/*_spec.rb'
|
87
96
|
|
97
|
+
RSpec/MultipleExpectations:
|
98
|
+
Enabled: true
|
99
|
+
Exclude:
|
100
|
+
- 'spec/acceptance/**/*_spec.rb'
|
101
|
+
|
88
102
|
plugins:
|
89
103
|
- rubocop-rake
|
90
104
|
- rubocop-rspec
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
<!-- generated by git-cliff start -->
|
2
|
+
|
3
|
+
# Changelog
|
4
|
+
|
5
|
+
All notable changes to this project will be documented in this file.
|
6
|
+
|
7
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
8
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
9
|
+
|
10
|
+
<!-- generated by git-cliff end -->
|
11
|
+
|
12
|
+
## [0.1.0] - 2025-04-21
|
13
|
+
|
14
|
+
### 🐛 Fixed
|
15
|
+
|
16
|
+
- Add PDF rendering from protected remote URLs by @dieter-medium
|
17
|
+
- Add acceptance tests for PDF generation with bidi2pdf-rails by @dieter-medium
|
18
|
+
- Allow forcing chromedriver manager initialization by @dieter-medium
|
19
|
+
- Add unit tests for BaseNestedConfig behavior by @dieter-medium
|
20
|
+
|
21
|
+
### 📝 Docs
|
22
|
+
|
23
|
+
- Enhance README with usage and config examples by @dieter-medium
|
24
|
+
- Add CORS configuration details for asset access by @dieter-medium
|
25
|
+
|
26
|
+
### 🚀 Added
|
27
|
+
|
28
|
+
- Enhance configuration and logging for Bidi2pdfRails by @dieter-medium
|
29
|
+
- Ensure custom HTML can be used in PDF rendering by @dieter-medium
|
30
|
+
|
31
|
+
[unreleased](https://github.com/dieter-medium/bidi2pdf-rails/compare/v0.1.0..HEAD)
|
32
|
+
[0.1.0](https://github.com/dieter-medium/bidi2pdf-rails/compare/v0.0.1.alpha.1..v0.1.0)
|
33
|
+
|
data/README.md
CHANGED
@@ -1,75 +1,165 @@
|
|
1
1
|
[](https://github.com/dieter-medium/bidi2pdf-rails/blob/main/.github/workflows/ruby.yml)
|
2
2
|
[](https://codeclimate.com/github/dieter-medium/bidi2pdf-rails/maintainability)
|
3
|
-
[](https://badge.fury.io/rb/bidi2pdf-rails)
|
4
3
|
[](https://codeclimate.com/github/dieter-medium/bidi2pdf-rails/test_coverage)
|
4
|
+
[](https://badge.fury.io/rb/bidi2pdf-rails)
|
5
5
|
[](https://www.codetriage.com/dieter-medium/bidi2pdf-rails)
|
6
6
|
|
7
|
-
|
8
7
|
# 📄 Bidi2pdfRails
|
9
8
|
|
10
|
-
**Bidi2pdfRails** is the official Rails integration for [Bidi2pdf](https://github.com/dieter-medium/bidi2pdf)
|
11
|
-
|
9
|
+
**Bidi2pdfRails** is the official Rails integration for [Bidi2pdf](https://github.com/dieter-medium/bidi2pdf) — a
|
10
|
+
modern, headless-browser-based PDF rendering engine.
|
11
|
+
Generate high-fidelity PDFs directly from your Rails views or external URLs with minimal setup.
|
12
12
|
|
13
|
-
>
|
13
|
+
> ⚠️ **Project status:** _Under active development_. Not yet recommended for production use.
|
14
14
|
|
15
15
|
---
|
16
16
|
|
17
|
-
##
|
17
|
+
## ✨ Features
|
18
18
|
|
19
|
-
-
|
20
|
-
-
|
21
|
-
-
|
19
|
+
- 🔍 Accurate PDF rendering using a real browser engine
|
20
|
+
- 💾 Supports both HTML string rendering and remote URL conversion
|
21
|
+
- 🔐 Built-in support for authentication (Basic Auth, cookies, headers)
|
22
|
+
- 🧰 Full test suite with examples for Rails controller integration
|
23
|
+
- 🧠 Sensible defaults, yet fully configurable
|
22
24
|
|
23
25
|
---
|
24
26
|
|
25
27
|
## 🔧 Installation
|
26
28
|
|
27
|
-
Add
|
29
|
+
Add to your Gemfile:
|
28
30
|
|
29
31
|
```ruby
|
30
|
-
|
31
|
-
|
32
|
-
gem "bidi2pdf-rails", github: "dieter-medium/bidi2pdf", branch: "main"
|
32
|
+
# Until released, use the GitHub repo
|
33
|
+
gem "bidi2pdf-rails", github: "dieter-medium/bidi2pdf-rails", branch: "main"
|
33
34
|
gem "bidi2pdf", github: "dieter-medium/bidi2pdf", branch: "main"
|
35
|
+
|
36
|
+
# Optional for performance:
|
37
|
+
# gem "websocket-native"
|
34
38
|
```
|
35
39
|
|
36
|
-
|
40
|
+
Install it:
|
37
41
|
|
38
42
|
```bash
|
39
|
-
bundle
|
43
|
+
bundle install
|
40
44
|
```
|
41
45
|
|
42
|
-
Generate the initializer:
|
46
|
+
Generate the config initializer:
|
43
47
|
|
44
48
|
```bash
|
45
49
|
bin/rails generate bidi2pdf_rails:initializer
|
46
50
|
```
|
47
51
|
|
48
|
-
|
52
|
+
---
|
49
53
|
|
50
|
-
|
51
|
-
|
54
|
+
## 📦 Usage Examples
|
55
|
+
|
56
|
+
### 📄 Rendering a Rails View as PDF
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
# app/controllers/invoices_controller.rb
|
60
|
+
|
61
|
+
def show
|
62
|
+
render pdf: "invoice",
|
63
|
+
template: "invoices/show",
|
64
|
+
layout: "pdf",
|
65
|
+
locals: { invoice: @invoice },
|
66
|
+
print_options: { landscape: true },
|
67
|
+
wait_for_network_idle: true
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
### 🌐 Rendering a Remote URL to PDF
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
|
75
|
+
def convert
|
76
|
+
render pdf: "external-report",
|
77
|
+
url: "https://example.com/dashboard",
|
78
|
+
wait_for_page_loaded: false,
|
79
|
+
print_options: { page: { format: :A4 } }
|
80
|
+
end
|
52
81
|
```
|
53
82
|
|
54
83
|
---
|
55
84
|
|
56
|
-
##
|
85
|
+
## 🛡️ Authentication Support
|
86
|
+
|
87
|
+
Need to convert pages that require authentication? No problem. Use:
|
88
|
+
|
89
|
+
- `auth: { username:, password: }`
|
90
|
+
- `cookies: { session_key: value }`
|
91
|
+
- `headers: { "Authorization" => "Bearer ..." }`
|
92
|
+
|
93
|
+
Example:
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
render pdf: "secure",
|
97
|
+
url: secure_report_url,
|
98
|
+
auth: { username: "admin", password: "secret" }
|
99
|
+
```
|
100
|
+
|
101
|
+
Or use global config in `bidi2pdf_rails.rb` initializer:
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
config.render_remote_settings.basic_auth_user = ->(_) { "admin" }
|
105
|
+
config.render_remote_settings.basic_auth_pass = ->(_) { Rails.application.credentials.dig(:pdf, :auth_pass) }
|
106
|
+
```
|
107
|
+
|
108
|
+
---
|
109
|
+
|
110
|
+
## 📂 Asset Access via CORS
|
111
|
+
|
112
|
+
When rendering HTML with `render_to_string`, Chromium needs access to your assets (CSS, images, fonts).
|
113
|
+
Enable CORS for `/assets` using `rack-cors`:
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
# Gemfile
|
117
|
+
gem 'rack-cors'
|
118
|
+
|
119
|
+
# config/initializers/cors.rb
|
120
|
+
Rails.application.config.middleware.insert_before 0, Rack::Cors do
|
121
|
+
allow do
|
122
|
+
origins '*'
|
123
|
+
resource '/assets/*', headers: :any, methods: [:get, :options]
|
124
|
+
end
|
125
|
+
end
|
126
|
+
```
|
127
|
+
|
128
|
+
---
|
129
|
+
|
130
|
+
## 🧪 Acceptance Examples
|
131
|
+
|
132
|
+
This repo includes **real integration tests** that serve as usage documentation:
|
133
|
+
|
134
|
+
- [Download PDF with `.pdf` format](spec/acceptance/user_can_download_report_pdf_spec.rb)
|
135
|
+
- [Render protected remote URLs using Basic Auth, cookies, and headers](spec/acceptance/user_can_generate_pdf_from_protected_remote_url_spec.rb)
|
136
|
+
|
137
|
+
---
|
138
|
+
|
139
|
+
## 🧠 Configuration
|
140
|
+
|
141
|
+
Bidi2pdfRails is highly configurable.
|
142
|
+
|
143
|
+
See full config options in:
|
144
|
+
|
145
|
+
```bash
|
146
|
+
bin/rails generate bidi2pdf_rails:initializer
|
147
|
+
```
|
57
148
|
|
58
|
-
|
59
|
-
This demonstrates how to use `Bidi2pdfRails` in a realistic mini Rails application setup.
|
149
|
+
Or explore `Bidi2pdfRails::Configuration` in the source.
|
60
150
|
|
61
151
|
---
|
62
152
|
|
63
153
|
## 🙌 Contributing
|
64
154
|
|
65
|
-
|
66
|
-
|
155
|
+
Pull requests, issues, and ideas are all welcome 🙏
|
156
|
+
Want to contribute? Just fork, branch, and PR like a boss.
|
67
157
|
|
68
|
-
|
158
|
+
> Contribution guide coming soon!
|
69
159
|
|
70
160
|
---
|
71
161
|
|
72
162
|
## 📄 License
|
73
163
|
|
74
|
-
This gem is
|
75
|
-
|
164
|
+
This gem is released under the [MIT License](https://opensource.org/licenses/MIT).
|
165
|
+
Use freely — and responsibly.
|
data/Rakefile
CHANGED
data/cliff.toml
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
# git-cliff ~ configuration file
|
2
|
+
# https://git-cliff.org/docs/configuration
|
3
|
+
|
4
|
+
[changelog]
|
5
|
+
# template for the changelog header
|
6
|
+
header = """
|
7
|
+
<!-- generated by git-cliff start -->
|
8
|
+
# Changelog\n
|
9
|
+
All notable changes to this project will be documented in this file.
|
10
|
+
|
11
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
12
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n
|
13
|
+
"""
|
14
|
+
# template for the changelog body
|
15
|
+
# https://keats.github.io/tera/docs/#introduction
|
16
|
+
body = """
|
17
|
+
{%- macro remote_url() -%}
|
18
|
+
https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
|
19
|
+
{%- endmacro -%}
|
20
|
+
|
21
|
+
{% if version -%}
|
22
|
+
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
|
23
|
+
{% else -%}
|
24
|
+
## [Unreleased]
|
25
|
+
{% endif -%}
|
26
|
+
|
27
|
+
{% for group, commits in commits | group_by(attribute="group") %}
|
28
|
+
### {{ group | upper_first }}
|
29
|
+
{%- for commit in commits %}
|
30
|
+
- {{ commit.message | split(pat="\n") | first | upper_first | trim }}\
|
31
|
+
{% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif -%}
|
32
|
+
{% if commit.remote.pr_number %} in \
|
33
|
+
[#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }}) \
|
34
|
+
{%- endif -%}
|
35
|
+
{% endfor %}
|
36
|
+
{% endfor %}
|
37
|
+
|
38
|
+
{%- if github.contributors | filter(attribute="is_first_time", value=true) | length != 0 %}
|
39
|
+
## New Contributors
|
40
|
+
{%- endif -%}
|
41
|
+
|
42
|
+
{% for contributor in github.contributors | filter(attribute="is_first_time", value=true) %}
|
43
|
+
* @{{ contributor.username }} made their first contribution
|
44
|
+
{%- if contributor.pr_number %} in \
|
45
|
+
[#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }}) \
|
46
|
+
{%- endif %}
|
47
|
+
{%- endfor %}\n
|
48
|
+
"""
|
49
|
+
# template for the changelog footer
|
50
|
+
footer = """
|
51
|
+
{%- macro remote_url() -%}
|
52
|
+
https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
|
53
|
+
{%- endmacro -%}
|
54
|
+
|
55
|
+
{% for release in releases -%}
|
56
|
+
{% if release.version -%}
|
57
|
+
{% if release.previous.version -%}
|
58
|
+
[{{ release.version | trim_start_matches(pat="v") }}]: \
|
59
|
+
{{ self::remote_url() }}/compare/{{ release.previous.version }}..{{ release.version }}
|
60
|
+
{% endif -%}
|
61
|
+
{% else -%}
|
62
|
+
[unreleased]: {{ self::remote_url() }}/compare/{{ release.previous.version }}..HEAD
|
63
|
+
{% endif -%}
|
64
|
+
{% endfor %}
|
65
|
+
<!-- generated by git-cliff end -->
|
66
|
+
"""
|
67
|
+
# remove the leading and trailing whitespace from the templates
|
68
|
+
trim = true
|
69
|
+
|
70
|
+
[git]
|
71
|
+
# parse the commits based on https://www.conventionalcommits.org
|
72
|
+
conventional_commits = true
|
73
|
+
# filter out the commits that are not conventional
|
74
|
+
filter_unconventional = false
|
75
|
+
# regex for preprocessing the commit messages
|
76
|
+
commit_preprocessors = [
|
77
|
+
# remove issue numbers from commits
|
78
|
+
{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "" },
|
79
|
+
]
|
80
|
+
# regex for parsing and grouping commits
|
81
|
+
commit_parsers = [
|
82
|
+
# ✅ Features (additions)
|
83
|
+
{ message = "^feat(?:\\([^)]+\\))?!?:", group = "🚀 Added" },
|
84
|
+
{ message = "^[aA]dd", group = "🚀 Added" },
|
85
|
+
{ message = "^[sS]upport", group = "🚀 Added" },
|
86
|
+
# ❌ Removals
|
87
|
+
{ message = "^[rR]emove", group = "🗑️ Removed" },
|
88
|
+
{ message = "^[dD]elete", group = "🗑️ Removed" },
|
89
|
+
# 🐛 Fixes
|
90
|
+
{ message = "^fix(?:\\([^)]+\\))?!?:", group = "🐛 Fixed" },
|
91
|
+
{ message = "^[tT]est", group = "🐛 Fixed" },
|
92
|
+
{ message = "^[fF]ix", group = "🐛 Fixed" },
|
93
|
+
# 🎨 Refactors
|
94
|
+
{ message = "^refactor(?:\\([^)]+\\))?!?:", group = "🎨 Refactored" },
|
95
|
+
# ⚡️ Performance
|
96
|
+
{ message = "^perf(?:\\([^)]+\\))?!?:", group = "⚡️ Performance" },
|
97
|
+
# 📝 Docs
|
98
|
+
{ message = "^docs(?:\\([^)]+\\))?!?:", group = "📝 Docs" },
|
99
|
+
# 💄 Style (formatting, whitespace, etc.)
|
100
|
+
{ message = "^style(?:\\([^)]+\\))?!?:", group = "💄 Style" },
|
101
|
+
# 🧪 Tests
|
102
|
+
{ message = "^test(?:\\([^)]+\\))?!?:", group = "🧪 Tests" },
|
103
|
+
# 🔧 Build
|
104
|
+
{ message = "^build(?:\\([^)]+\\))?!?:", group = "🔧 Build" },
|
105
|
+
# 🛠️ CI
|
106
|
+
{ message = "^ci(?:\\([^)]+\\))?!?:", skip = true },
|
107
|
+
# 🧹 Chores (skip)
|
108
|
+
{ message = "^chore\\(release\\): prepare for", skip = true },
|
109
|
+
{ message = "^chore\\(deps.*\\)", skip = true },
|
110
|
+
{ message = "^chore\\(pr\\)", skip = true },
|
111
|
+
{ message = "^chore\\(pull\\)", skip = true },
|
112
|
+
{ message = "^chore(?:\\([^)]+\\))?!?:", skip = true },
|
113
|
+
{ message = "^\\s*chore", skip = true },
|
114
|
+
# ⏪ Reverts
|
115
|
+
{ message = "^revert(?:\\([^)]+\\))?!?:", group = "⏪ Reverted" },
|
116
|
+
# 🌀 Catch-all (only if nothing else matched)
|
117
|
+
{ message = "^.*", group = "🔄 Changed" }
|
118
|
+
]
|
119
|
+
|
120
|
+
|
121
|
+
# filter out the commits that are not matched by commit parsers
|
122
|
+
filter_commits = false
|
123
|
+
# sort the tags topologically
|
124
|
+
topo_order = false
|
125
|
+
# sort the commits inside sections by oldest/newest order
|
126
|
+
sort_commits = "newest"
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bidi2pdf/bidi/browser_console_logger"
|
4
|
+
|
5
|
+
module Bidi2pdfRails
|
6
|
+
class BrowserConsoleLogSubscriber < ActiveSupport::LogSubscriber
|
7
|
+
def browser_console_log_received(event)
|
8
|
+
payload = event.payload
|
9
|
+
timestamp = Bidi2pdf::Bidi::BrowserConsoleLogger.format_timestamp(payload[:timestamp])
|
10
|
+
|
11
|
+
logger.tagged("bidi2pdf_rails", "browser_console", timestamp) do |tagged_logger|
|
12
|
+
verbose_logger = Bidi2pdf::VerboseLogger.new(tagged_logger, Bidi2pdfRails.config.general_options.verbosity_value)
|
13
|
+
Bidi2pdf::Bidi::BrowserConsoleLogger.new(verbose_logger)
|
14
|
+
.builder
|
15
|
+
.with_level(payload[:level])
|
16
|
+
.with_prefix("")
|
17
|
+
.with_text(payload[:text])
|
18
|
+
.with_args(payload[:args])
|
19
|
+
.with_stack_trace(payload[:stack_trace])
|
20
|
+
.log_event
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -5,28 +5,28 @@ module Bidi2pdfRails
|
|
5
5
|
class << self
|
6
6
|
attr_reader :manager, :session
|
7
7
|
|
8
|
-
def initialize_manager
|
9
|
-
return unless running_as_server?
|
8
|
+
def initialize_manager(force: false)
|
9
|
+
return unless running_as_server? || force
|
10
10
|
|
11
11
|
@mutex ||= Mutex.new
|
12
12
|
@mutex.synchronize do
|
13
13
|
return if @manager && @session
|
14
14
|
|
15
|
-
msg = Bidi2pdfRails.
|
15
|
+
msg = Bidi2pdfRails.use_remote_browser? ? "Remote session" : "ChromeDriver manager"
|
16
16
|
|
17
17
|
Bidi2pdfRails.logger.info "Initializing Bidi2pdf #{msg}"
|
18
18
|
|
19
|
-
if Bidi2pdfRails.
|
19
|
+
if Bidi2pdfRails.use_remote_browser?
|
20
20
|
@session = Bidi::Session.new(
|
21
|
-
session_url: Bidi2pdfRails.
|
22
|
-
headless: Bidi2pdfRails.
|
23
|
-
chrome_args: Bidi2pdfRails.
|
21
|
+
session_url: Bidi2pdfRails.config.render_remote_settings.browser_url_value,
|
22
|
+
headless: Bidi2pdfRails.config.general_options.headless_value,
|
23
|
+
chrome_args: Bidi2pdfRails.config.general_options.chrome_session_args_value
|
24
24
|
)
|
25
25
|
else
|
26
26
|
@manager = Bidi2pdf::ChromedriverManager.new(
|
27
|
-
port: Bidi2pdfRails.
|
28
|
-
headless: Bidi2pdfRails.
|
29
|
-
chrome_args: Bidi2pdfRails.
|
27
|
+
port: Bidi2pdfRails.config.chromedriver_settings.port_value,
|
28
|
+
headless: Bidi2pdfRails.config.general_options.headless_value,
|
29
|
+
chrome_args: Bidi2pdfRails.config.general_options.chrome_session_args_value
|
30
30
|
)
|
31
31
|
@manager.start
|
32
32
|
@session = @manager.session
|
@@ -42,7 +42,7 @@ module Bidi2pdfRails
|
|
42
42
|
|
43
43
|
@mutex ||= Mutex.new
|
44
44
|
@mutex.synchronize do
|
45
|
-
msg = Bidi2pdfRails.
|
45
|
+
msg = Bidi2pdfRails.use_remote_browser? ? "Remote session" : "ChromeDriver manager"
|
46
46
|
Bidi2pdfRails.logger.info "Shutting down Bidi2pdf #{msg}"
|
47
47
|
@session&.close
|
48
48
|
@manager&.stop
|