Repository navigation
Releases
Releases · poli-page/rubyonrails
v0.13.1
Deprecated
config.poli_page.user_agent. It never had an effect: thepoli-pageSDK
sends its ownUser-Agentand takes no option for it, so the value was
never passed on. Setting it now emits a deprecation warning (through
PoliPage::Rails.deprecator, registered inRails.application.deprecators
on Rails 7.1+) and still does nothing. It will be removed in a later minor
release.
v0.13.0
First release on RubyGems. It requires the poli-page SDK 0.13
(~> 0.13.0) and passes the Poli Page API contract v0.13.0. The gem shares
its major.minor with the Poli Page API, so its first version is 0.13.0; a
0.11.0 was prepared and never published, and neither was the 0.1.0
development line. The Changed, Removed and Fixed entries below describe
changes made during those lines.
Added
- Rails engine + Railtie wrapping the official
poli-pageRuby SDK. PoliPage.client— lazy memoised class-level accessor (Monitor-guarded;
shared across threads per the SDK's thread-safety guarantee).
PoliPage.reset_client!clears the memo (test-only).Rails.application.config.poli_page—Configurationobject exposing every
SDK kwarg as anattr_accessorplus anotificationsopt-out switch.
to_client_kwargs.compactlets the SDK's own defaults apply fornilkeys.PoliPage::Rails::ConfigurationValidator— validatesapi_key(see
Changed),base_url(http/https),timeout
(1..600),max_retries(0..10),retry_delay(0..30),notifications
(boolean), andon_retry/on_error(callable). Runs lazily on first
PoliPage.clientcall — keepsassets:precompileanddb:createworking
in containers without secrets at boot.PoliPage::Rails::Renderable— controller concern providingrender_pdf,
render_preview,redirect_to_document. SetsCache-Control: private, no-store,X-Content-Type-Options: nosniff, and an RFC 5987 / RFC 6266
Content-Dispositionthat handles ASCII + non-ASCII filenames (résumé.pdf,
発票.pdf,🦀.pdf).PoliPage::Rails::FilenameEncoder— thin wrapper over
ActionDispatch::Http::ContentDisposition.format; single seam if Rails
changes the formatting API across versions.ActiveSupport::Notificationsbridge for the SDK's retry/error hooks
(poli_page.retry,poli_page.error). Default-on, opt-out via
c.notifications = false. Zero overhead with no subscribers.rails generate poli_page:install— writes
config/initializers/poli_page.rbwith a commented template documenting
every configuration key. Zero custom options to avoid Thor-reserved-name
shadowing (--force,--skip,--pretend,--quiet, etc.).- Example Rails 8 app at
example-app/with an interactive
single-page demo UI covering every SDK method (render.pdf,
render.pdf_stream,render.document,documents.get,
documents.thumbnails,documents.preview,documents.delete, an
error demo, and abin/rake demo:render_to_filetask for
render_to_file). - RBS signatures in
sig/mirroring the public API surface. - A default error handler, on by default:
PoliPage::Rails::ErrorHandleris
included intoActionController::BaseandActionController::APIand
answers every unrescuedPoliPage::Errorwith the SDK'sto_payload, as is,
as JSON{ "code", "message", "status", "requestId" }and the payload's
status (503fornetwork_error,504fortimeout,502for
invalid_response), or500with"status": nullwhen the status is
unknown (invalid_options,io_error), always asapplication/json. Set
config.poli_page.error_handler = falseto leave it out. An error raised
after a response is committed (anActionController::Livestream that wrote
its first chunk or was closed) is raised again, for Live to log and report;
close a Live stream only once it has written, or an error before the first
byte ends as an empty200. - The API contract's integration cases (
spec/contract), run in CI against
the example app on every Ruby and Rails version of the matrix, with the
contract pinned to v0.13.0 by thepoli-page/api-contractaction, including
impl.invalid-response. - Release workflow: the tag's major.minor must be the pinned API contract's (a
stable contract tag on the pinned commit, not the comment next to it) and
the requiredpoli-pageSDK's (~> X.Y.0in the gemspec and the example
app), and the example app's lockfile must lock the tag's version
(scripts/check-release-versions.sh); the error names both versions.
Changed
- Requires the
poli-pageSDK 0.13 (~> 0.13.0, that is>= 0.13.0, < 0.14). With it, a 2xx from the API whose body is not JSON (usually from a
proxy) raisesPoliPage::InvalidResponseError, codeinvalid_response(was
INTERNAL_ERROR), which the default error handler answers502; a
render_to_filethat cannot write its file raises
PoliPage::FileWriteError, codeio_error(wasinvalid_optionsor the
raw Ruby exception), answered500with"status": null; and the PDF
download is bounded by thetimeoutoption (an idle timeout for
render.pdf_streamandrender_to_file). - The default error handler forwards the SDK's
to_payloadas is: the SDK
0.13 names the request idrequestIditself, so the gem's own renaming of
request_idand itsErrorHandler::WIRE_KEYSare gone.
ErrorHandler.bodyreturns the payload's Symbol-keyed Hash. - Environment keys and no template versions, as in the SDK since 0.11:
render calls take noversion:, a key belongs to one environment
(pp_{environment}_{32 lowercase hex}, for examplepp_sandbox_…,
pp_live_…,pp_staging_…), and the key alone selects the environment and
so the published copy that renders. ConfigurationValidatoraccepts any environment key. It raises
ConfigurationErroronly for a missing or emptyapi_key; a value that does
not matchpp_{environment}_{32 lowercase hex}logs one warning through
config.loggerthat names the expected format and shows no part of the
key, not even itspp_{environment}_prefix, and the client starts anyway,
leaving the verdict to the API.
API_KEY_PATTERNis replaced byAPI_KEY_FORMAT.render_previewnow documentsDocumentPreviewResult(documents.preview)
only.- Example app: the demo routes move from
/api/*to the demo-contract
paths (GET /render/pdf,GET /documents/:id,GET /errors/not-found, …).
GET /api/errors/bad-version(INVALID_VERSION_FORMAT) is replaced by
GET /errors/not-found, which renders the templatedoes-not-existand,
through the default error handler, answers404 TEMPLATE_NOT_FOUNDwith the
error's code, message, status and request id.GET /documents/:id/preview
now goes throughrender_preview.GET /documents/:idstill answers a
302to the presigned PDF URL. - Example app:
GET /render/streamsets its PDF headers when the first chunk
arrives, after the render and the start of the download, so a render error
or a network error before that answers through the default error handler
(JSON, its own status) instead of a200 application/pdf. - The integration spec runs only with a
pp_sandbox_key. - CI: the live API job runs on
main(and on demand) against the production API with the sandbox key from thePOLI_PAGE_API_KEYsecret, and skips with a notice when the key is absent or not app_sandbox_key. - The live API CI job passes the optional
POLI_PAGE_BASE_URLsecret to the integration spec (unset: the SDK default), next to thepp_sandbox_key inPOLI_PAGE_API_KEY. The spec setsconfig.base_urlfromPOLI_PAGE_BASE_URLwhen it is set.
Removed
- Example app:
GET /api/render/preview(render.preview) and its "HTML
preview" button; the SDK no longer hasrender.preview. - Example app:
DocumentsController's ownrescue_from PoliPage::Error; the
default error handler answers instead.
Fixed
render_pdf/FilenameEncoder.disposition: control characters (CR/LF, TAB,
DEL, C1) are now stripped from theContent-Dispositionfilename before
ActionDispatch::Http::ContentDispositionformats it, instead of surviving as
%0D%0A-style escapes that clients decode back into the saved filename.- Example app: the demo page's status row no longer shows the first 8
characters ofPOLI_PAGE_API_KEY; no part of the key is shown.