weasy_pdf 0.1.1 → 0.1.2

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: 12b1d3cf6d3b8596b9ab9e5873d05dbc29ebff24966de276e0cc5d234247273d
4
- data.tar.gz: 1df1d355f3a8b52074edaf604370025df78d8e93bb30a7ec88fd4ad1fa870827
3
+ metadata.gz: 17cafa52131b7f83d4d632ba1524eeac59d85ad0f35c80dc565337647a4302cb
4
+ data.tar.gz: af9fdcd91dc415a129c57b362ab02afdc8ac504f42e9288ce7d889d80daefa39
5
5
  SHA512:
6
- metadata.gz: f25f4b0d192f1fbe9b0e96aa140488eaad532ea552691c24565e1753810d40a6a3d3423235bf57228542635616b5066bf952c13dec6aa3b93851402485c3dc58
7
- data.tar.gz: 3dd91e7e0bab4f2bebe6817c0cc192b1aaff5347b565287a2b126d491c2d74d96f6ce09eab0f5129b074c67f00a643a5f42d04c14375060316221ebe46d17714
6
+ metadata.gz: d605d7d6e9ddc71362f25a001f7c47922bb459d2b03e85619cd4dd157fc04d7e9bb5e071392515648e80b7a3688df1c0f84520cdac8986aff37b8433ceb06746
7
+ data.tar.gz: eef904f8e6a5b5d212b44c94716e87d0289ad5e55bddc5adaf1422c7ea5ee8d183911cf6e745f08d90c2958af240b510098403fe0432bb737d2c86ef76e706c0
data/CHANGELOG.md CHANGED
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.1.2] - 2026-04-30
11
+
12
+ ### Fixed
13
+
14
+ - Vite development stylesheets are now linked directly with `?direct` instead of being fetched and inlined, allowing WeasyPrint to resolve nested `url(...)` assets against the real stylesheet URL
15
+ - Vite development asset paths are normalized to absolute URLs using `origin` or `host`/`port`/`https`, fixing relative manifest paths such as `/vite-dev/...`
16
+ - `weasy_pdf_asset_path` no longer base64-encodes Vite dev assets implicitly; it returns the absolute dev server URL instead
17
+ - `weasy_pdf` now raises `WeasyPDF::ViteDevServerConfigError` when the Vite dev server is running but no absolute asset URL can be derived from the Vite configuration
18
+
10
19
  ## [0.1.1] - 2026-04-18
11
20
 
12
21
  ### Added
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WeasyPDF
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.2"
5
5
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "base64"
3
+ require "uri"
4
4
 
5
5
  module WeasyPDF
6
6
  module ViewHelpers
@@ -19,11 +19,10 @@ module WeasyPDF
19
19
 
20
20
  url = vite_asset_url(asset)
21
21
 
22
- if cdn_url?(url)
22
+ if vite_dev_server_running?
23
+ absolute_vite_url(url)
24
+ elsif cdn_url?(url)
23
25
  url
24
- elsif vite_dev_server_running?
25
- content = fetch_bytes(url)
26
- "data:#{mime_for(asset)};base64,#{Base64.strict_encode64(content)}"
27
26
  else
28
27
  disk = disk_path_from_url(url)
29
28
  (disk && File.exist?(disk.to_s)) ? "file://#{disk}" : url
@@ -32,12 +31,14 @@ module WeasyPDF
32
31
 
33
32
  private
34
33
 
35
- # Strategy progression: CDN URL → dev server (HTTP) → compiled file on disk → fallback link.
34
+ # Strategy progression: dev server URL → CDN URL → compiled file on disk → fallback link.
36
35
  # Each branch returns the same shape (a tag string), so the caller can treat them uniformly.
37
36
  def resolve_vite_stylesheet(source)
38
37
  url = vite_asset_url(source)
38
+ # Keep the stylesheet external in dev so WeasyPrint resolves nested url(...)
39
+ # references against the Vite asset URL instead of against a temp HTML file.
40
+ return stylesheet_link(vite_dev_direct_url(url)) if vite_dev_server_running?
39
41
  return stylesheet_link(url) if cdn_url?(url)
40
- return inlined_stylesheet(source, fetch_text(url)) if vite_dev_server_running?
41
42
 
42
43
  disk = disk_path_from_url(url)
43
44
  if disk && File.exist?(disk.to_s)
@@ -80,30 +81,61 @@ module WeasyPDF
80
81
  end
81
82
 
82
83
  def disk_path_from_url(url)
83
- return nil unless url.to_s.start_with?("/")
84
+ path = asset_url_path(url)
85
+ return nil unless path&.start_with?("/")
84
86
 
85
- Rails.root.join("public", url.sub(%r{\A/}, ""))
87
+ Rails.root.join("public", path.sub(%r{\A/}, ""))
86
88
  end
87
89
 
88
- def fetch_text(url)
89
- fetch_bytes(url).encode("utf-8", "binary", invalid: :replace, undef: :replace)
90
+ def vite_dev_direct_url(url)
91
+ absolute = absolute_vite_url(url)
92
+ absolute.include?("?") ? "#{absolute}&direct" : "#{absolute}?direct"
90
93
  end
91
94
 
92
- def fetch_bytes(url)
93
- require "net/http"
94
- uri = URI.parse(url)
95
- response = Net::HTTP.get_response(uri)
96
- raise WeasyPDF::MissingRemoteAsset.new(url, response) \
97
- unless response.is_a?(Net::HTTPSuccess)
95
+ def absolute_vite_url(url)
96
+ string = url.to_s
97
+ return string if string.start_with?("http://", "https://", "//", "data:")
98
98
 
99
- response.body.b
100
- rescue WeasyPDF::MissingRemoteAsset
101
- raise
102
- rescue => e
103
- # Network errors during asset resolution shouldn't abort PDF generation;
104
- # the caller logs and degrades to a <link> tag or omits the asset.
105
- Rails.logger.warn("[WeasyPDF] Error fetching #{url}: #{e.message}")
106
- "".b
99
+ origin = vite_origin
100
+ raise_missing_vite_dev_origin!(string) unless origin
101
+
102
+ path = string.start_with?("/") ? string : "/#{string}"
103
+ "#{origin}#{path}"
104
+ end
105
+
106
+ def vite_origin
107
+ config = vite_config
108
+ origin = config.origin if config&.respond_to?(:origin)
109
+ return origin.to_s.sub(%r{/\z}, "") unless origin.to_s.empty?
110
+
111
+ host = config.host if config&.respond_to?(:host)
112
+ port = config.port if config&.respond_to?(:port)
113
+ https = config.https if config&.respond_to?(:https)
114
+
115
+ return nil if host.to_s.empty? || port.to_s.empty?
116
+
117
+ normalized_host = %w[0.0.0.0 :: [::]].include?(host.to_s) ? "localhost" : host.to_s
118
+ scheme = https ? "https" : "http"
119
+ "#{scheme}://#{normalized_host}:#{port}"
120
+ end
121
+
122
+ def vite_config
123
+ return ViteRuby.config if ViteRuby.respond_to?(:config)
124
+ return ViteRuby.instance.config if ViteRuby.instance.respond_to?(:config)
125
+
126
+ nil
127
+ end
128
+
129
+ def asset_url_path(url)
130
+ URI.parse(url.to_s).path
131
+ rescue URI::InvalidURIError
132
+ nil
133
+ end
134
+
135
+ def raise_missing_vite_dev_origin!(url)
136
+ raise WeasyPDF::ViteDevServerConfigError,
137
+ "Vite dev server is running, but weasy_pdf could not derive an absolute asset URL " \
138
+ "for '#{url}'. Configure Vite with an explicit origin, or ensure host/port/https are available."
107
139
  end
108
140
  end
109
141
  end
data/lib/weasy_pdf.rb CHANGED
@@ -17,6 +17,7 @@ module WeasyPDF
17
17
  class GenerationError < Error; end
18
18
  class TimeoutError < Error; end
19
19
  class MissingAsset < Error; end
20
+ class ViteDevServerConfigError < Error; end
20
21
 
21
22
  class MissingLocalAsset < MissingAsset
22
23
  attr_reader :path
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: weasy_pdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Diego Enjamio