gotenberg-ruby 1.0.15 → 1.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: 2990c93d26eeaaf90147f2d3ac3125147df47ca773b9e5aac0b6ce08b62f4ca0
4
- data.tar.gz: 7aa0bba1a0bc1b45cff46d59eda3ec4a6dfcc2a8dc63cc8b0a3fd28bebc21f13
3
+ metadata.gz: 1a57ecef802d6a5a8b9eb26a2da94ed3787b4538f852eb2d3f07938f08cf5e49
4
+ data.tar.gz: fcc88742ae86a6c99faf125dffd690ab269e34a05e29bba3308d085d3a3acaff
5
5
  SHA512:
6
- metadata.gz: ab8ef6e6d103c231cea637c3946b7bae1b3f12207f8b9a5940c1d73fc71819c3b5ef53b93b8f43f6a619884a6bf33f56d17d5b29c6158857c9e2e83ff7855a68
7
- data.tar.gz: 0624427f0f223f52676a5c92f4e9c52449a075fd15f748f6b6e85901698404f24974582f5bbe4b6dd2cc94e8326dab3b2c7c8fc44ecde567877a689126dbef80
6
+ metadata.gz: b65c215fc11b60cfb9460c80c40e5702b27ce0fc2332c35d4f76550a5e858775c6e790bcc1dbdf9e4afaa005e9eac94089b976b2a43b1597cb7f04341362cdd2
7
+ data.tar.gz: ea637568964b0193dd4a7735dfd1f4c0af8af9193dc3283b3515e7b3a275b6b3f8fc2933d3934313f51de6a8189808fc983f3832840afb55261fe1f07a71fd98
data/CHANGELOG.md ADDED
@@ -0,0 +1,25 @@
1
+ # Changelog
2
+
3
+ ## 1.1.0 - 2026-07-12
4
+
5
+ ### Added
6
+
7
+ - ViteRuby helpers.
8
+ - A development/test Vite manifest.
9
+ - Network idle controls.
10
+ - Native Gotenberg PDF metadata support.
11
+
12
+ ### Changed
13
+
14
+ - PDF metadata is sent through Gotenberg's `metadata` field.
15
+ - The minimum supported Gotenberg version is now 8.3.0.
16
+
17
+ See [Gotenberg 8.3.0](https://github.com/gotenberg/gotenberg/releases/tag/v8.3.0) and the
18
+ [metadata documentation](https://gotenberg.dev/docs/convert-with-chromium/convert-html-to-pdf#metadata-pdf-engines).
19
+
20
+ ### Removed
21
+
22
+ - The `mini_exiftool` dependency.
23
+ - `Gotenberg::Exiftools`.
24
+ - The client-side HTML title extractor.
25
+ - `Gotenberg::ModifyMetadataError`.
data/README.md CHANGED
@@ -4,13 +4,19 @@ PDF files, and more!
4
4
 
5
5
  ## Requirement
6
6
 
7
+ ⚠️ Gotenberg Ruby requires Gotenberg 8.3.0 or newer.
8
+
9
+ Native PDF metadata support was added in [Gotenberg 8.3.0](https://github.com/gotenberg/gotenberg/releases/tag/v8.3.0).
10
+ See the official [Chromium metadata documentation](https://gotenberg.dev/docs/convert-with-chromium/convert-html-to-pdf#metadata-pdf-engines)
11
+ for details.
12
+
7
13
  This packages requires [Gotenberg](https://gotenberg.dev), a Docker-powered stateless API for PDF files:
8
14
 
9
- * 🔥 [Live Demo](https://gotenberg.dev/docs/get-started/live-demo)
10
- * [Docker](https://gotenberg.dev/docs/get-started/docker)
11
- * [Docker Compose](https://gotenberg.dev/docs/get-started/docker-compose)
12
- * [Kubernetes](https://gotenberg.dev/docs/get-started/kubernetes)
13
- * [Cloud Run](https://gotenberg.dev/docs/get-started/cloud-run)
15
+ * 🔥 [Live Demo](https://gotenberg.dev/docs/getting-started/installation#live-demo)
16
+ * [Docker](https://gotenberg.dev/docs/getting-started/installation#docker)
17
+ * [Docker Compose](https://gotenberg.dev/docs/getting-started/installation#docker-compose)
18
+ * [Kubernetes](https://gotenberg.dev/docs/getting-started/installation#kubernetes)
19
+ * [Cloud Run](https://gotenberg.dev/docs/getting-started/installation#cloud-run)
14
20
 
15
21
  ## Installation
16
22
 
@@ -22,10 +28,9 @@ gem "gotenberg-ruby"
22
28
 
23
29
  * [Send a request to the API](#send-a-request-to-the-api)
24
30
  * [Chromium](#chromium)
25
- * [LibreOffice](#libreOffice)
31
+ * [LibreOffice](#libreoffice)
26
32
  * [PDF Engines](#pdf-engines)
27
33
  * [Webhook](#webhook)
28
- * [Exiftools](#exiftools)
29
34
 
30
35
  ### Run Gotenberg
31
36
 
@@ -37,11 +42,18 @@ version: "3"
37
42
  services:
38
43
  gotenberg:
39
44
  image: gotenberg/gotenberg:8
45
+ command:
46
+ - gotenberg
47
+ - --chromium-allow-file-access-from-files=true
40
48
  restart: always
41
49
  ports:
42
50
  - 3000:3000
43
51
  ```
44
52
 
53
+ The `--chromium-allow-file-access-from-files=true` flag is required when converting HTML documents that use Vite
54
+ CSS, ES modules, module preload imports, fonts, or images uploaded as multipart assets. Gotenberg opens these local
55
+ assets through `file://` URLs, so Chromium must be allowed to load files from other local files.
56
+
45
57
  ### Send a request to the API
46
58
 
47
59
  After having created the HTTP request (see below), you have two options:
@@ -53,11 +65,11 @@ After having created the HTTP request (see below), you have two options:
53
65
 
54
66
  ### Chromium
55
67
 
56
- The [Chromium module](https://gotenberg.dev/docs/routes#convert-with-chromium) interacts with the Chromium browser to convert HTML documents to PDF.
68
+ The [Chromium module](https://gotenberg.dev/docs/convert-with-chromium/convert-html-to-pdf) interacts with the Chromium browser to convert HTML documents to PDF.
57
69
 
58
70
  #### Convert a target URL to PDF
59
71
 
60
- See https://gotenberg.dev/docs/routes#url-into-pdf-route.
72
+ See https://gotenberg.dev/docs/convert-with-chromium/convert-url-to-pdf.
61
73
 
62
74
  Converting a target URL to PDF is as simple as:
63
75
 
@@ -99,9 +111,6 @@ Available exceptions:
99
111
  # raise while PDF transform failed
100
112
  Gotenberg::TransformError
101
113
 
102
- # raise while change PDF metadata failed
103
- Gotenberg::ModifyMetadataError
104
-
105
114
  # raise while loading asset source failed
106
115
  Gotenberg::RemoteSourceError
107
116
  ```
@@ -144,9 +153,77 @@ gotenberg_stylesheet_tag 'application.css', inline: true
144
153
  gotenberg_stylesheet_tag 'application.css', inline: true, skip_analyze: true
145
154
  ```
146
155
 
156
+ Applications using `vite_rails` can load assets from the Vite manifest with dedicated helpers:
157
+
158
+ ```erb
159
+ <%= gotenberg_vite_image_tag 'images/logo.svg' %>
160
+ <%= gotenberg_vite_stylesheet_tag 'entrypoints/pdf.scss' %>
161
+ <%= gotenberg_vite_javascript_tag 'entrypoints/pdf.js' %>
162
+ ```
163
+
164
+ Each source must be present in the Vite manifest. These helpers only support local manifest assets and do not accept
165
+ options such as `inline`, `absolute_path`, or `base_path`. Continue to use the regular Gotenberg helpers for external
166
+ URLs and other options.
167
+
168
+ ##### Development Vite PDF build
169
+
170
+ In development and test environments, Gotenberg needs production-style files instead of URLs from the Vite dev
171
+ server. Add a dedicated watch command to `package.json`:
172
+
173
+ ```json
174
+ {
175
+ "scripts": {
176
+ "vite:pdf:dev": "vite build --config vite.pdf.config.ts --mode development --watch"
177
+ }
178
+ }
179
+ ```
180
+
181
+ Run it alongside the Rails application:
182
+
183
+ ```bash
184
+ npm run vite:pdf:dev
185
+ ```
186
+
187
+ A minimal `vite.pdf.config.ts` for JavaScript and stylesheet PDF entrypoints looks like this:
188
+
189
+ ```ts
190
+ import { defineConfig } from 'vite'
191
+ import { resolve } from 'node:path'
192
+
193
+ const root = resolve(__dirname, 'app/javascript')
194
+ const entrypoint = (path: string) => resolve(root, path)
195
+
196
+ export default defineConfig(({ mode }) => {
197
+ if (mode !== 'development') {
198
+ throw new Error(
199
+ 'vite.pdf.config.ts is development-only. Use the main Vite build for production PDF assets.'
200
+ )
201
+ }
202
+
203
+ return {
204
+ root,
205
+ build: {
206
+ outDir: resolve(__dirname, 'tmp/vite-pdf'),
207
+ emptyOutDir: true,
208
+ manifest: true,
209
+ cssCodeSplit: true,
210
+ rollupOptions: {
211
+ input: {
212
+ 'pdf.js': entrypoint('entrypoints/pdf.js'),
213
+ 'pdf.css': entrypoint('entrypoints/pdf.scss'),
214
+ },
215
+ },
216
+ },
217
+ }
218
+ })
219
+ ```
220
+
221
+ This is a Vite build running in watch mode, not the Vite development server. The output directory must match
222
+ `config.vite_output_dir`.
223
+
147
224
  #### Convert an HTML document to PDF
148
225
 
149
- See See https://gotenberg.dev/docs/routes#url-into-pdf-route.
226
+ See https://gotenberg.dev/docs/convert-with-chromium/convert-html-to-pdf.
150
227
 
151
228
  Prepare HTML content with build-in Rails methods:
152
229
 
@@ -176,25 +253,27 @@ document = Gotenberg::Chromium.call(ENV['GOTENBERG_URL']) do |doc|
176
253
  end
177
254
  ```
178
255
 
179
- #### Change PDF meta with exiftools
180
-
181
- If you want to use this feature, you need to install additional package to host system:
182
-
183
- ```
184
- sudo apt install exiftool
185
- ```
186
-
187
- and now you can change PDF metatags using exiftools:
256
+ #### PDF metadata
188
257
 
189
258
  ```ruby
190
259
  document = Gotenberg::Chromium.call(ENV['GOTENBERG_URL']) do |doc|
191
260
  doc.html index_html
192
- doc.meta title: 'Custom PDF title'
261
+ doc.meta(
262
+ 'Title' => 'Quarterly Report',
263
+ 'Author' => 'Jane Doe',
264
+ 'Subject' => 'Quarterly business results',
265
+ 'Keywords' => ['quarterly', 'business', 'report']
266
+ )
193
267
  end
194
268
  ```
195
269
 
196
- Note: for Rails based apps, you can setup <title>Custom PDF title</title> header in index.html and
197
- it will be automatically added to output PDF.
270
+ Metadata keys correspond to ExifTool tag names. Canonical capitalization is recommended, although lowercase and
271
+ symbol keys are also supported. Do not provide the same tag more than once with different casing. Not every ExifTool
272
+ tag is writable; see the full [ExifTool XMP Tags](https://exiftool.org/TagNames/XMP.html) reference and the
273
+ [Gotenberg metadata documentation](https://gotenberg.dev/docs/manipulate-pdfs/write-metadata) for more examples.
274
+
275
+ Writing metadata usually breaks PDF/A compliance. Without an explicit `Title`, Chromium uses the HTML `<title>`;
276
+ pass an empty `Title` to clear it.
198
277
 
199
278
  #### Configuration file (optionally)
200
279
 
@@ -205,12 +284,21 @@ Gotenberg.configure do |config|
205
284
 
206
285
  # default temporary directory for output
207
286
  config.backtrace_dir = Rails.root.join('tmp', 'gotenberg')
287
+
288
+ # development/test Vite PDF build output
289
+ config.vite_output_dir = 'tmp/vite-pdf'
290
+
291
+ # directory containing Vite source entrypoints
292
+ config.vite_source_code_dir = 'app/javascript'
208
293
  end
209
294
  ```
210
295
 
296
+ The Vite options configure the dedicated PDF build used in development and test. Production uses the standard
297
+ ViteRuby manifest and compiled assets from the configured public Vite output directory (by default, `public/vite`).
298
+
211
299
  #### Convert one or more markdown files to PDF
212
300
 
213
- See https://gotenberg.dev/docs/routes#markdown-files-into-pdf-route.
301
+ See https://gotenberg.dev/docs/convert-with-chromium/convert-markdown-to-pdf.
214
302
 
215
303
  You may convert markdown files with:
216
304
 
@@ -421,6 +509,31 @@ document = Gotenberg::Chromium.call(ENV['GOTENBERG_URL']) do |doc|
421
509
  end
422
510
  ```
423
511
 
512
+ #### Wait for network idle
513
+
514
+ By default, Gotenberg does not wait for network activity to settle before converting a document. You may wait until no
515
+ network connections remain active for 500ms:
516
+
517
+ ```ruby
518
+ document = Gotenberg::Chromium.call(ENV['GOTENBERG_URL']) do |doc|
519
+ doc.html index_html
520
+ doc.wait_for_network_idle
521
+ end
522
+ ```
523
+
524
+ Strict network idle may never occur on pages using long polling, WebSockets, analytics, or heartbeat requests. For these
525
+ pages, wait until at most two network connections remain active for 500ms instead:
526
+
527
+ ```ruby
528
+ document = Gotenberg::Chromium.call(ENV['GOTENBERG_URL']) do |doc|
529
+ doc.html index_html
530
+ doc.wait_for_network_almost_idle
531
+ end
532
+ ```
533
+
534
+ Do not combine both methods unless strict network idle is required: when both are enabled, Gotenberg waits for both
535
+ events. See the [Gotenberg network errors documentation](https://gotenberg.dev/docs/convert-with-chromium/convert-html-to-pdf#network-errors).
536
+
424
537
  #### User agent
425
538
 
426
539
  You may override the default `User-Agent` header used by Gotenberg:
@@ -479,7 +592,7 @@ end
479
592
 
480
593
  #### PDF Format
481
594
 
482
- See https://gotenberg.dev/docs/routes#pdfa-chromium.
595
+ See https://gotenberg.dev/docs/convert-with-chromium/convert-url-to-pdf#pdfa--pdfua.
483
596
 
484
597
  You may set the PDF format of the resulting PDF with:
485
598
 
@@ -492,12 +605,12 @@ end
492
605
 
493
606
  ### LibreOffice
494
607
 
495
- The [LibreOffice module](https://gotenberg.dev/docs/routes#convert-with-libreoffice) interacts with [LibreOffice](https://www.libreoffice.org/)
608
+ The [LibreOffice module](https://gotenberg.dev/docs/convert-with-libreoffice/convert-to-pdf) interacts with [LibreOffice](https://www.libreoffice.org/)
496
609
  to convert documents to PDF, thanks to [unoconv](https://github.com/unoconv/unoconv).
497
610
 
498
611
  #### Convert documents to PDF
499
612
 
500
- See https://gotenberg.dev/docs/routes#office-documents-into-pdfs-route.
613
+ See https://gotenberg.dev/docs/convert-with-libreoffice/convert-to-pdf.
501
614
 
502
615
  Converting a document to PDF is as simple as:
503
616
 
@@ -557,7 +670,7 @@ end
557
670
 
558
671
  #### PDF format
559
672
 
560
- See https://gotenberg.dev/docs/routes#pdfa-libreoffice.
673
+ See https://gotenberg.dev/docs/convert-with-libreoffice/convert-to-pdf#pdfa--pdfua.
561
674
 
562
675
  You may set the PDF format of the resulting PDF(s) with:
563
676
 
@@ -586,7 +699,7 @@ The [PDF Engines module](https://gotenberg.dev/docs/configuration#pdf-engines) g
586
699
 
587
700
  #### Merge PDFs
588
701
 
589
- See https://gotenberg.dev/docs/routes#merge-pdfs-route.
702
+ See https://gotenberg.dev/docs/manipulate-pdfs/merge-pdfs.
590
703
 
591
704
  Merging PDFs is as simple as:
592
705
 
@@ -609,7 +722,7 @@ end
609
722
 
610
723
  #### Convert to a specific PDF format
611
724
 
612
- See https://gotenberg.dev/docs/routes#convert-into-pdfa--pdfua-route.
725
+ See https://gotenberg.dev/docs/manipulate-pdfs/pdfa-pdfua.
613
726
 
614
727
  You may convert a PDF to a specific PDF format with:
615
728
 
@@ -634,7 +747,7 @@ end
634
747
 
635
748
  ### Webhook
636
749
 
637
- The [Webhook module](https://gotenberg.dev/docs/webhook) is a Gotenberg middleware that sends the API
750
+ The [Webhook module](https://gotenberg.dev/docs/webhook-download#webhooks) is a Gotenberg middleware that sends the API
638
751
  responses to callbacks.
639
752
 
640
753
  ⚠️ You cannot use the `document.to_binary` method if you're using the webhook feature.
@@ -668,19 +781,3 @@ document = Gotenberg::Chromium.call(ENV['GOTENBERG_URL']) do |doc|
668
781
  doc.webhook 'https://my.webhook.url', 'https://my.webhook.error.url'
669
782
  end
670
783
  ```
671
-
672
- ### Exiftools
673
-
674
- Gem also proxify (expert mode) access to mini_exiftools througth *Gotenberg::Exiftools* class.
675
- You can change PDF metadata manually:
676
-
677
- ```ruby
678
- binary = Gotenberg::Exiftools.modify(pdf_binary, { title: 'Document 1' })
679
-
680
- # save PDF file
681
- File.open('filename.pdf', 'wb') do |file|
682
- file << binary
683
- end
684
- ```
685
-
686
- ⚠️ Class is just wrapper around *MiniExiftool* class, so you need handle exceptions manually/carefully in begin/rescue block.
@@ -0,0 +1,15 @@
1
+ require 'gotenberg/analyzers/base'
2
+
3
+ module Gotenberg
4
+ module Analyzers
5
+ class ModuleJs < Base
6
+ def tag
7
+ '<script type="module" src="%s"></script>' % filename
8
+ end
9
+
10
+ def assets
11
+ @assets ||= [[binary, filename]]
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'gotenberg/analyzers/base'
2
+
3
+ module Gotenberg
4
+ module Analyzers
5
+ class ModulePreload < Base
6
+ def tag
7
+ '<link rel="modulepreload" href="%s" />' % filename
8
+ end
9
+
10
+ def assets
11
+ @assets ||= [[binary, filename]]
12
+ end
13
+ end
14
+ end
15
+ end
@@ -87,7 +87,25 @@ module Gotenberg
87
87
 
88
88
  self
89
89
  end
90
-
90
+
91
+ # Waits until no network connections remain active for 500ms.
92
+ # Avoid this for long polling or WebSockets, which may prevent network idle.
93
+ # See https://gotenberg.dev/docs/convert-with-chromium/convert-html-to-pdf#network-errors.
94
+ def wait_for_network_idle
95
+ properties['skipNetworkIdleEvent'] = false
96
+
97
+ self
98
+ end
99
+
100
+ # Waits until at most two network connections remain active for 500ms.
101
+ # Prefer this for long polling, WebSockets, analytics, or heartbeat requests.
102
+ # See https://gotenberg.dev/docs/convert-with-chromium/convert-html-to-pdf#network-errors.
103
+ def wait_for_network_almost_idle
104
+ properties['skipNetworkAlmostIdleEvent'] = false
105
+
106
+ self
107
+ end
108
+
91
109
  # DEPRECATED in Gotenberg 8. Overrides the default "User-Agent" header.
92
110
  def user_agent user_agent
93
111
  properties['userAgent'] = user_agent
@@ -108,7 +126,7 @@ module Gotenberg
108
126
 
109
127
  self
110
128
  end
111
-
129
+
112
130
  # Forces Chromium to emulate the media type "print" or "screen".
113
131
  def emulate_media_type type
114
132
  properties['emulatedMediaType'] = type
@@ -140,10 +158,10 @@ module Gotenberg
140
158
  end
141
159
 
142
160
  private
143
-
161
+
144
162
  def properties
145
163
  @properties ||= {}
146
164
  end
147
165
  end
148
166
  end
149
- end
167
+ end
@@ -29,8 +29,6 @@ module Gotenberg
29
29
  def html index
30
30
  compiler = Compiler.new(index)
31
31
 
32
- meta(extract_metadata_from_body(compiler.body))
33
-
34
32
  files << multipart_file(compiler.body, 'index.html', 'text/html')
35
33
 
36
34
  assets *compiler.assets
@@ -61,4 +59,4 @@ module Gotenberg
61
59
  end
62
60
  end
63
61
  end
64
- end
62
+ end
@@ -4,14 +4,12 @@ require 'gotenberg/headers'
4
4
  require 'gotenberg/metadata'
5
5
  require 'gotenberg/files'
6
6
  require 'gotenberg/client'
7
- require 'gotenberg/exiftools'
8
- require 'gotenberg/extractors'
9
7
  require 'gotenberg/exceptions'
10
8
  require 'gotenberg/backtrace'
11
9
 
12
10
  module Gotenberg
13
11
  class Chromium
14
- include Properties, Files, Headers, Metadata, Tools, Extractors
12
+ include Properties, Files, Headers, Metadata, Tools
15
13
 
16
14
  attr_accessor :base_path, :client_headers
17
15
  attr_reader :endpoint, :response, :exception
@@ -31,7 +29,6 @@ module Gotenberg
31
29
  def call
32
30
  backtrace if html_debug?
33
31
  transform
34
- modify_metadata if modify_metadata?
35
32
 
36
33
  self
37
34
  end
@@ -46,12 +43,6 @@ module Gotenberg
46
43
 
47
44
  private
48
45
 
49
- def modify_metadata?
50
- return false if webhook_request?
51
-
52
- success? && metadata_available?
53
- end
54
-
55
46
  def html_debug?
56
47
  Gotenberg.configuration.html_debug == true
57
48
  end
@@ -66,14 +57,8 @@ module Gotenberg
66
57
  @exception = Gotenberg::TransformError.new(e)
67
58
  end
68
59
 
69
- def modify_metadata
70
- @response = Exiftools.modify(response, metadata)
71
- rescue StandardError => e
72
- @exception = Gotenberg::ModifyMetadataError.new(e)
73
- end
74
-
75
60
  def client
76
61
  Client.new(base_path, headers: client_headers)
77
62
  end
78
63
  end
79
- end
64
+ end
@@ -2,6 +2,8 @@ require 'json'
2
2
  require 'gotenberg/analyzers/image'
3
3
  require 'gotenberg/analyzers/js'
4
4
  require 'gotenberg/analyzers/css'
5
+ require 'gotenberg/analyzers/module_js'
6
+ require 'gotenberg/analyzers/module_preload'
5
7
 
6
8
  module Gotenberg
7
9
  class Compiler
@@ -35,6 +37,10 @@ module Gotenberg
35
37
  Analyzers::Js.new(resource).call
36
38
  when 'css'
37
39
  Analyzers::Css.new(resource).call
40
+ when 'modulejs'
41
+ Analyzers::ModuleJs.new(resource).call
42
+ when 'modulepreload'
43
+ Analyzers::ModulePreload.new(resource).call
38
44
  end
39
45
 
40
46
  assets.push(*analyzer.assets)
@@ -43,4 +49,4 @@ module Gotenberg
43
49
  end
44
50
  end
45
51
  end
46
- end
52
+ end
@@ -1,6 +1,6 @@
1
1
  module Gotenberg
2
2
  class Configuration
3
- attr_accessor :backtrace_dir, :html_debug
3
+ attr_accessor :backtrace_dir, :html_debug, :vite_output_dir, :vite_source_code_dir
4
4
 
5
5
  def initialize
6
6
  @backtrace_dir =
@@ -10,6 +10,9 @@ module Gotenberg
10
10
  Dir.mktmpdir
11
11
  end
12
12
 
13
+ @vite_output_dir = 'tmp/vite-pdf'
14
+ @vite_source_code_dir = 'app/javascript'
15
+
13
16
  @html_debug = false
14
17
  end
15
18
  end
@@ -1,5 +1,4 @@
1
1
  module Gotenberg
2
2
  class TransformError < StandardError; end
3
- class ModifyMetadataError < StandardError; end
4
3
  class RemoteSourceError < StandardError; end
5
- end
4
+ end
@@ -45,7 +45,7 @@ module Gotenberg
45
45
  EOF
46
46
  end
47
47
 
48
- Rails.env.development? ? :proxy : :static
48
+ (Rails.env.development? || Rails.env.test?) ? :proxy : :static
49
49
  end
50
50
 
51
51
  def gotenberg_source_location source, options = {}
@@ -75,4 +75,4 @@ module Gotenberg
75
75
  end
76
76
  end
77
77
  end
78
- end
78
+ end
@@ -0,0 +1,108 @@
1
+ module Gotenberg
2
+ module Helpers
3
+ module ViteHelpers
4
+ def gotenberg_vite_image_tag source
5
+ ensure_vite_ruby!
6
+
7
+ path = gotenberg_vite_manifest.path_for(source)
8
+
9
+ gotenberg_context_tag(
10
+ tag: 'image',
11
+ src: gotenberg_vite_source_location(path)
12
+ )
13
+ end
14
+
15
+ def gotenberg_vite_stylesheet_tag source
16
+ ensure_vite_ruby!
17
+
18
+ path = gotenberg_vite_manifest.path_for(source, type: :stylesheet)
19
+
20
+ gotenberg_context_tag(
21
+ tag: 'css',
22
+ src: gotenberg_vite_source_location(path),
23
+ base_path: gotenberg_vite_stylesheet_base_path,
24
+ skip_analyze: false
25
+ )
26
+ end
27
+
28
+ def gotenberg_vite_javascript_tag source
29
+ ensure_vite_ruby!
30
+
31
+ entries = gotenberg_vite_manifest.resolve_entries(
32
+ source,
33
+ type: :javascript
34
+ )
35
+
36
+ tags = entries[:imports].map do |path|
37
+ gotenberg_modulepreload_tag(path)
38
+ end
39
+
40
+ tags.concat(
41
+ entries[:scripts].map do |path|
42
+ gotenberg_modulejs_tag(path)
43
+ end
44
+ )
45
+
46
+ safe_join(tags)
47
+ end
48
+
49
+ private
50
+
51
+ def ensure_vite_ruby!
52
+ return if Object.const_defined?(:ViteRuby)
53
+
54
+ raise LoadError,
55
+ 'ViteRuby is required to use Gotenberg Vite helpers. Add vite_rails to your Gemfile.'
56
+ end
57
+
58
+ def gotenberg_modulejs_tag source
59
+ gotenberg_context_tag(
60
+ tag: 'modulejs',
61
+ src: gotenberg_vite_source_location(source)
62
+ )
63
+ end
64
+
65
+ def gotenberg_modulepreload_tag source
66
+ gotenberg_context_tag(
67
+ tag: 'modulepreload',
68
+ src: gotenberg_vite_source_location(source)
69
+ )
70
+ end
71
+
72
+ def gotenberg_vite_source_location source
73
+ if Rails.env.development? || Rails.env.test?
74
+ File.join(Rails.root, source)
75
+ else
76
+ File.join(Rails.public_path, source)
77
+ end
78
+ end
79
+
80
+ def gotenberg_vite_stylesheet_base_path
81
+ if Rails.env.development? || Rails.env.test?
82
+ Rails.root.join(Gotenberg.configuration.vite_output_dir)
83
+ else
84
+ Rails.public_path
85
+ end
86
+ end
87
+
88
+ def gotenberg_vite_manifest
89
+ if Rails.env.development? || Rails.env.test?
90
+ @gotenberg_vite_manifest ||= vite_internal_manifest.tap(&:refresh)
91
+ else
92
+ vite_manifest
93
+ end
94
+ end
95
+
96
+ def vite_internal_manifest
97
+ @vite_internal_manifest ||= ViteRuby.new(
98
+ root: Rails.root.to_s,
99
+ mode: 'production',
100
+ public_dir: '.',
101
+ public_output_dir: Gotenberg.configuration.vite_output_dir,
102
+ source_code_dir: Gotenberg.configuration.vite_source_code_dir,
103
+ auto_build: false
104
+ ).manifest
105
+ end
106
+ end
107
+ end
108
+ end
@@ -4,7 +4,6 @@ require 'gotenberg/headers'
4
4
  require 'gotenberg/metadata'
5
5
  require 'gotenberg/files'
6
6
  require 'gotenberg/client'
7
- require 'gotenberg/exiftools'
8
7
  require 'gotenberg/exceptions'
9
8
 
10
9
  module Gotenberg
@@ -28,7 +27,6 @@ module Gotenberg
28
27
 
29
28
  def call
30
29
  transform
31
- modify_metadata if modify_metadata?
32
30
 
33
31
  self
34
32
  end
@@ -43,27 +41,14 @@ module Gotenberg
43
41
 
44
42
  private
45
43
 
46
- def modify_metadata?
47
- return false if webhook_request?
48
- return false if zip_mode?
49
-
50
- success? && metadata_available?
51
- end
52
-
53
44
  def transform
54
45
  @response = client.adapter.post(endpoint, properties.merge(files: files), headers).body
55
46
  rescue StandardError => e
56
47
  @exception = Gotenberg::TransformError.new(e)
57
48
  end
58
49
 
59
- def modify_metadata
60
- @response = Exiftools.modify(response, metadata)
61
- rescue StandardError => e
62
- @exception = Gotenberg::ModifyMetadataError.new(e)
63
- end
64
-
65
50
  def client
66
51
  Client.new(base_path, headers: client_headers)
67
52
  end
68
53
  end
69
- end
54
+ end
@@ -1,20 +1,18 @@
1
+ require 'json'
2
+
1
3
  module Gotenberg
2
4
  module Metadata
3
- # set meta headers for PDF file with exiftools (title, creator, etc...)
4
5
  def meta elements
5
6
  metadata.merge!(elements)
7
+ properties['metadata'] = metadata.to_json unless metadata.empty?
6
8
 
7
9
  self
8
10
  end
9
11
 
10
12
  private
11
13
 
12
- def metadata_available?
13
- !metadata.empty?
14
- end
15
-
16
14
  def metadata
17
15
  @metadata ||= {}
18
16
  end
19
17
  end
20
- end
18
+ end
@@ -4,7 +4,6 @@ require 'gotenberg/headers'
4
4
  require 'gotenberg/metadata'
5
5
  require 'gotenberg/files'
6
6
  require 'gotenberg/client'
7
- require 'gotenberg/exiftools'
8
7
  require 'gotenberg/exceptions'
9
8
 
10
9
  module Gotenberg
@@ -28,7 +27,6 @@ module Gotenberg
28
27
 
29
28
  def call
30
29
  transform
31
- modify_metadata if modify_metadata?
32
30
 
33
31
  self
34
32
  end
@@ -43,26 +41,14 @@ module Gotenberg
43
41
 
44
42
  private
45
43
 
46
- def modify_metadata?
47
- return false if webhook_request?
48
-
49
- success? && metadata_available?
50
- end
51
-
52
44
  def transform
53
45
  @response = client.adapter.post(endpoint, properties.merge(files: files), headers).body
54
46
  rescue StandardError => e
55
47
  @exception = Gotenberg::TransformError.new(e)
56
48
  end
57
49
 
58
- def modify_metadata
59
- @response = Exiftools.modify(response, metadata)
60
- rescue StandardError => e
61
- @exception = Gotenberg::ModifyMetadataError.new(e)
62
- end
63
-
64
50
  def client
65
51
  Client.new(base_path, headers: client_headers)
66
52
  end
67
53
  end
68
- end
54
+ end
@@ -1,11 +1,13 @@
1
1
  require 'gotenberg/helpers/action_view'
2
+ require 'gotenberg/helpers/vite_helpers'
2
3
 
3
4
  module WillPaginate
4
5
  class Railtie < Rails::Railtie
5
6
  initializer "gotenberg.register" do |app|
6
7
  ActiveSupport.on_load :action_view do
7
8
  include Gotenberg::Helpers::ActionView
9
+ include Gotenberg::Helpers::ViteHelpers
8
10
  end
9
11
  end
10
12
  end
11
- end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module Gotenberg
2
- VERSION = '1.0.15'
3
- end
2
+ VERSION = '1.1.0'
3
+ end
@@ -5,7 +5,6 @@ module Gotenberg
5
5
  autoload :Chromium, 'gotenberg/chromium'
6
6
  autoload :Libreoffice, 'gotenberg/libreoffice'
7
7
  autoload :PdfEngines, 'gotenberg/pdf_engines'
8
- autoload :Exiftools, 'gotenberg/exiftools'
9
8
  autoload :Configuration, 'gotenberg/configuration'
10
9
 
11
10
  def self.configuration
@@ -15,4 +14,4 @@ module Gotenberg
15
14
  def self.configure
16
15
  yield(configuration)
17
16
  end
18
- end
17
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gotenberg-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.15
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - sanzstez
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-06-18 00:00:00.000000000 Z
11
+ date: 2026-07-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: 1.0.4
41
- - !ruby/object:Gem::Dependency
42
- name: mini_exiftool
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: 1.0.0
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: 1.0.0
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: launchy
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -74,6 +60,7 @@ executables: []
74
60
  extensions: []
75
61
  extra_rdoc_files: []
76
62
  files:
63
+ - CHANGELOG.md
77
64
  - LICENSE.md
78
65
  - README.md
79
66
  - lib/gotenberg-ruby.rb
@@ -81,6 +68,8 @@ files:
81
68
  - lib/gotenberg/analyzers/css.rb
82
69
  - lib/gotenberg/analyzers/image.rb
83
70
  - lib/gotenberg/analyzers/js.rb
71
+ - lib/gotenberg/analyzers/module_js.rb
72
+ - lib/gotenberg/analyzers/module_preload.rb
84
73
  - lib/gotenberg/analyzers/resource.rb
85
74
  - lib/gotenberg/backtrace.rb
86
75
  - lib/gotenberg/chromium.rb
@@ -90,11 +79,10 @@ files:
90
79
  - lib/gotenberg/compiler.rb
91
80
  - lib/gotenberg/configuration.rb
92
81
  - lib/gotenberg/exceptions.rb
93
- - lib/gotenberg/exiftools.rb
94
- - lib/gotenberg/extractors.rb
95
82
  - lib/gotenberg/files.rb
96
83
  - lib/gotenberg/headers.rb
97
84
  - lib/gotenberg/helpers/action_view.rb
85
+ - lib/gotenberg/helpers/vite_helpers.rb
98
86
  - lib/gotenberg/libreoffice.rb
99
87
  - lib/gotenberg/libreoffice/properties.rb
100
88
  - lib/gotenberg/libreoffice/tools.rb
@@ -110,7 +98,7 @@ homepage: https://github.com/sanzstez/gotenberg-ruby
110
98
  licenses:
111
99
  - MIT
112
100
  metadata: {}
113
- post_install_message:
101
+ post_install_message:
114
102
  rdoc_options: []
115
103
  require_paths:
116
104
  - lib
@@ -125,8 +113,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
113
  - !ruby/object:Gem::Version
126
114
  version: '0'
127
115
  requirements: []
128
- rubygems_version: 3.4.10
129
- signing_key:
116
+ rubygems_version: 3.0.3.1
117
+ signing_key:
130
118
  specification_version: 4
131
119
  summary: A gem that provides a client interface for the Gotenberg PDF generate service
132
120
  test_files: []
@@ -1,61 +0,0 @@
1
- require 'mini_exiftool'
2
- require 'tempfile'
3
-
4
- module Gotenberg
5
- class Exiftools
6
- attr_reader :io, :metadata
7
-
8
- def self.modify io, metadata
9
- new(io, metadata).call
10
- end
11
-
12
- def initialize io, metadata
13
- @io = io
14
- @metadata = metadata
15
- end
16
-
17
- def call
18
- set_attributes
19
- write
20
-
21
- @body
22
- end
23
-
24
- def exiftools
25
- @exiftools ||= MiniExiftool.new(tempfile.path)
26
- end
27
-
28
- private
29
-
30
- def set_attributes
31
- metadata.each do |property, v|
32
- exiftools.public_send(('%s=' % property), v)
33
- end
34
- end
35
-
36
- def write
37
- exiftools.save!
38
-
39
- @body = tempfile.read
40
- rescue StandardError => e
41
- raise e
42
- ensure
43
- tempfile.close
44
- tempfile.unlink
45
- end
46
-
47
- def tempfile
48
- @tempfile ||= tempfile_builder do |file|
49
- file << io
50
- end
51
- end
52
-
53
- def tempfile_builder
54
- Tempfile.new(['gootenberg', '.pdf']).tap do |tempfile|
55
- tempfile.binmode
56
- yield tempfile if block_given?
57
- tempfile.rewind
58
- end
59
- end
60
- end
61
- end
@@ -1,14 +0,0 @@
1
- module Gotenberg
2
- module Extractors
3
-
4
- private
5
-
6
- def extract_metadata_from_body body, variables = {}
7
- body.match('<title.*?>(.*?)<\/title>') do
8
- variables.merge!(title: $1)
9
- end
10
-
11
- variables
12
- end
13
- end
14
- end