poli-page 0.9.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.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +62 -0
  3. data/CODE_OF_CONDUCT.md +38 -0
  4. data/LICENSE +21 -0
  5. data/MIGRATION.md +68 -0
  6. data/README.md +376 -0
  7. data/SECURITY.md +100 -0
  8. data/lib/poli_page/client.rb +228 -0
  9. data/lib/poli_page/documents.rb +148 -0
  10. data/lib/poli_page/errors.rb +157 -0
  11. data/lib/poli_page/inputs/inline_mode_input.rb +31 -0
  12. data/lib/poli_page/inputs/project_mode_input.rb +38 -0
  13. data/lib/poli_page/inputs/thumbnail_options.rb +25 -0
  14. data/lib/poli_page/internal/constants.rb +38 -0
  15. data/lib/poli_page/internal/http.rb +123 -0
  16. data/lib/poli_page/internal/presigned_fetch.rb +89 -0
  17. data/lib/poli_page/internal/transport.rb +98 -0
  18. data/lib/poli_page/internal/uuid.rb +20 -0
  19. data/lib/poli_page/internal/wire.rb +49 -0
  20. data/lib/poli_page/models/document_descriptor.rb +52 -0
  21. data/lib/poli_page/models/document_preview_result.rb +10 -0
  22. data/lib/poli_page/models/orientation.rb +15 -0
  23. data/lib/poli_page/models/page_format.rb +23 -0
  24. data/lib/poli_page/models/preview_result.rb +9 -0
  25. data/lib/poli_page/models/thumbnail.rb +8 -0
  26. data/lib/poli_page/render.rb +163 -0
  27. data/lib/poli_page/render_to_file.rb +52 -0
  28. data/lib/poli_page/request_event.rb +17 -0
  29. data/lib/poli_page/response_event.rb +15 -0
  30. data/lib/poli_page/retry_event.rb +12 -0
  31. data/lib/poli_page/version.rb +5 -0
  32. data/lib/poli_page.rb +28 -0
  33. data/sig/poli_page/client.rbs +46 -0
  34. data/sig/poli_page/documents.rbs +12 -0
  35. data/sig/poli_page/errors.rbs +84 -0
  36. data/sig/poli_page/models.rbs +106 -0
  37. data/sig/poli_page/render.rbs +32 -0
  38. data/sig/poli_page/request_event.rbs +9 -0
  39. data/sig/poli_page/response_event.rbs +9 -0
  40. data/sig/poli_page/retry_event.rbs +9 -0
  41. data/sig/poli_page.rbs +3 -0
  42. metadata +87 -0
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+ require "pathname"
5
+
6
+ module PoliPage
7
+ class Client
8
+ # Render a PDF and stream the bytes straight to `path`. Built on
9
+ # `render.pdf_stream`, so memory usage stays bounded regardless of
10
+ # document size. Creates parent directories if missing. Overwrites
11
+ # existing files. On render error the partial file is removed before
12
+ # the error is re-raised.
13
+ #
14
+ # @param path [String, Pathname]
15
+ # @param kwargs forwarded to `Resources::Render#pdf_stream`
16
+ # @return [nil]
17
+ # @raise [PoliPage::InvalidOptionsError] on filesystem failure
18
+ # @raise any error raised by `Resources::Render#pdf_stream`
19
+ #
20
+ # @example Write a PDF to disk
21
+ # client.render_to_file(
22
+ # "out/welcome.pdf",
23
+ # project: "getting-started",
24
+ # template: "welcome",
25
+ # version: "1.0.0",
26
+ # data: { name: "World" }
27
+ # )
28
+ def render_to_file(path, **kwargs)
29
+ pathname = Pathname(path)
30
+ FileUtils.mkdir_p(pathname.dirname) unless pathname.dirname.directory?
31
+
32
+ stream_to_path(pathname, kwargs)
33
+ nil
34
+ rescue Errno::EACCES, Errno::ENOSPC, Errno::EISDIR, Errno::ENOENT, Errno::EROFS => e
35
+ raise PoliPage::InvalidOptionsError,
36
+ "failed to write to #{pathname}: #{e.class}: #{e.message}"
37
+ end
38
+
39
+ private
40
+
41
+ def stream_to_path(pathname, kwargs)
42
+ File.open(pathname, "wb") do |io|
43
+ render.pdf_stream(**kwargs) { |chunk| io.write(chunk) }
44
+ end
45
+ rescue StandardError
46
+ # Clean up the partial / empty file so the caller can see the failure
47
+ # cleanly. Mirrors Node `fs.createWriteStream` cleanup behaviour.
48
+ FileUtils.rm_f(pathname)
49
+ raise
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PoliPage
4
+ # Event payload for the `on_request` constructor hook. Fired immediately
5
+ # before each HTTP attempt — including the first one and every retry.
6
+ # Parity with sdk-node `RequestEvent` (src/types.ts:171-175).
7
+ #
8
+ # - `method` [String] uppercase HTTP verb ("GET" / "POST" / "DELETE").
9
+ # - `url` [String] fully-resolved request URL (base_url + path).
10
+ # - `attempt` [Integer] 1-based attempt counter — first send is `1`, the
11
+ # first retry is `2`, etc.
12
+ #
13
+ # Naming `:method` shadows `Object#method`, but the field name is fixed by
14
+ # Node-SDK parity (`RequestEvent.method` is the public payload shape).
15
+ # Callers won't reach for `event.method(:foo)` on a value-typed event.
16
+ RequestEvent = Data.define(:method, :url, :attempt) # rubocop:disable Lint/DataDefineOverride
17
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PoliPage
4
+ # Event payload for the `on_response` constructor hook. Fired immediately
5
+ # after a 2xx response is received from the transport (NOT fired on
6
+ # non-2xx — those go through `on_retry` / `on_error` instead).
7
+ # Parity with sdk-node `ResponseEvent` (src/types.ts:177-181).
8
+ #
9
+ # - `status` [Integer] HTTP status code (always 200-299).
10
+ # - `request_id` [String, nil] value of the `x-request-id` response
11
+ # header, or nil if the server didn't send one.
12
+ # - `duration_ms` [Integer] wall-clock duration of the HTTP attempt,
13
+ # measured around `@transport.execute`.
14
+ ResponseEvent = Data.define(:status, :request_id, :duration_ms)
15
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PoliPage
4
+ # Event payload for the `on_retry` constructor hook (sdk-ruby-plan.md §10.2).
5
+ #
6
+ # - `attempt` [Integer] 1-based — the attempt about to be made.
7
+ # - `delay_ms` [Integer] sleep duration in milliseconds before this
8
+ # attempt. Canonical units across the SDK fleet
9
+ # (Plan 0 / roadmap D3).
10
+ # - `reason` [PoliPage::Error] error that triggered the retry.
11
+ RetryEvent = Data.define(:attempt, :delay_ms, :reason)
12
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PoliPage
4
+ VERSION = "0.9.0"
5
+ end
data/lib/poli_page.rb ADDED
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "poli_page/version"
4
+ require_relative "poli_page/errors"
5
+ require_relative "poli_page/internal/constants"
6
+ require_relative "poli_page/internal/http"
7
+ require_relative "poli_page/internal/uuid"
8
+ require_relative "poli_page/internal/wire"
9
+ require_relative "poli_page/internal/transport"
10
+ require_relative "poli_page/models/page_format"
11
+ require_relative "poli_page/models/orientation"
12
+ require_relative "poli_page/models/preview_result"
13
+ require_relative "poli_page/models/document_descriptor"
14
+ require_relative "poli_page/models/document_preview_result"
15
+ require_relative "poli_page/models/thumbnail"
16
+ require_relative "poli_page/inputs/project_mode_input"
17
+ require_relative "poli_page/inputs/inline_mode_input"
18
+ require_relative "poli_page/inputs/thumbnail_options"
19
+ require_relative "poli_page/retry_event"
20
+ require_relative "poli_page/request_event"
21
+ require_relative "poli_page/response_event"
22
+ require_relative "poli_page/render"
23
+ require_relative "poli_page/documents"
24
+ require_relative "poli_page/client"
25
+ require_relative "poli_page/render_to_file"
26
+
27
+ module PoliPage
28
+ end
@@ -0,0 +1,46 @@
1
+ module PoliPage
2
+ type request_hook = ^(PoliPage::RequestEvent) -> void
3
+ type response_hook = ^(PoliPage::ResponseEvent) -> void
4
+ type retry_hook = ^(PoliPage::RetryEvent) -> void
5
+ type error_hook = ^(PoliPage::Error) -> void
6
+
7
+ class Client
8
+ attr_reader base_url: String
9
+ attr_reader max_retries: Integer
10
+ attr_reader retry_delay: Numeric
11
+ attr_reader timeout: Numeric
12
+ attr_reader render: PoliPage::Resources::Render
13
+ attr_reader documents: PoliPage::Resources::Documents
14
+
15
+ def initialize: (api_key: String, ?base_url: String, ?max_retries: Integer,
16
+ ?retry_delay: Numeric, ?timeout: Numeric,
17
+ ?logger: untyped?, ?on_request: request_hook?,
18
+ ?on_response: response_hook?,
19
+ ?on_retry: retry_hook?,
20
+ ?on_error: error_hook?,
21
+ ?proxy: String?, ?ca_file: String?, ?ca_path: String?) -> void
22
+
23
+ def inspect: () -> String
24
+ def to_s: () -> String
25
+
26
+ # @api private
27
+ def execute_post: (String path, body: Hash[untyped, untyped], ?idempotency_key: String?) -> Hash[Symbol, untyped]
28
+
29
+ # @api private
30
+ def execute_get: (String path) -> Hash[Symbol, untyped]
31
+
32
+ # @api private
33
+ def execute_delete: (String path) -> untyped
34
+
35
+ # @api private
36
+ def execute_get_raw: (String path) -> untyped
37
+
38
+ # @api private — from PresignedFetch mixin
39
+ def fetch_bytes: (String url) -> String
40
+
41
+ # @api private — from PresignedFetch mixin
42
+ def stream_bytes: (String url) { (String) -> void } -> void
43
+
44
+ def render_to_file: (String | Pathname path, **untyped kwargs) -> nil
45
+ end
46
+ end
@@ -0,0 +1,12 @@
1
+ module PoliPage
2
+ module Resources
3
+ class Documents
4
+ def initialize: (PoliPage::Client client) -> void
5
+
6
+ def get: (String id) -> PoliPage::DocumentDescriptor
7
+ def preview: (String id) -> PoliPage::DocumentPreviewResult
8
+ def thumbnails: (String id, **untyped options) -> Array[PoliPage::Thumbnail]
9
+ def delete: (String id) -> nil
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,84 @@
1
+ module PoliPage
2
+ class Error < StandardError
3
+ attr_reader code: String
4
+ attr_reader status: Integer?
5
+ attr_reader request_id: String?
6
+
7
+ def initialize: (?String? message, code: String, ?status: Integer?, ?request_id: String?) -> void
8
+
9
+ def auth_error?: () -> bool
10
+ def rate_limit_error?: () -> bool
11
+ def validation_error?: () -> bool
12
+ def network_error?: () -> bool
13
+ def retryable?: () -> bool
14
+ end
15
+
16
+ class ValidationError < Error
17
+ end
18
+
19
+ class AuthenticationError < Error
20
+ end
21
+
22
+ class PermissionDeniedError < Error
23
+ end
24
+
25
+ class NotFoundError < Error
26
+ end
27
+
28
+ class GoneError < Error
29
+ end
30
+
31
+ class RateLimitError < Error
32
+ end
33
+
34
+ class APIError < Error
35
+ end
36
+
37
+ class InvalidOptionsError < Error
38
+ def initialize: (String message, ?code: String) -> void
39
+ end
40
+
41
+ class ConnectionError < Error
42
+ attr_reader cause: Exception?
43
+
44
+ def initialize: (message: String, ?cause: Exception?) -> void
45
+ end
46
+
47
+ class TimeoutError < Error
48
+ attr_reader timeout: Numeric
49
+
50
+ def initialize: (timeout: Numeric) -> void
51
+ end
52
+
53
+ class DownloadError < Error
54
+ def initialize: (message: String, ?status: Integer?) -> void
55
+ end
56
+
57
+ class InternalError < Error
58
+ def initialize: (String message, ?status: Integer?) -> void
59
+ end
60
+
61
+ module ErrorCodes
62
+ MISSING_API_KEY: String
63
+ INVALID_API_KEY: String
64
+ PAYMENT_REQUIRED: String
65
+ FORBIDDEN: String
66
+ ORGANIZATION_CANCELLED: String
67
+ ORGANIZATION_PURGED: String
68
+ NOT_FOUND: String
69
+ VERSION_NOT_FOUND: String
70
+ DOCUMENT_NOT_FOUND: String
71
+ GONE: String
72
+ VALIDATION_ERROR: String
73
+ MISSING_DATA: String
74
+ MISSING_PROJECT_OR_TEMPLATE: String
75
+ MISSING_TEMPLATE_SLUG: String
76
+ PROJECT_REQUIRED_FOR_DOCUMENT: String
77
+ INVALID_VERSION_FORMAT: String
78
+ VERSION_REQUIRED: String
79
+ INVALID_VERSION_FOR_KEY_ENV: String
80
+ QUOTA_EXCEEDED: String
81
+ OVERAGE_CAP_EXCEEDED: String
82
+ INTERNAL_ERROR: String
83
+ end
84
+ end
@@ -0,0 +1,106 @@
1
+ module PoliPage
2
+ module PageFormat
3
+ FORMATS: Set[String]
4
+
5
+ def self?.valid?: (untyped value) -> bool
6
+ end
7
+
8
+ module Orientation
9
+ ORIENTATIONS: Set[String]
10
+
11
+ def self?.valid?: (untyped value) -> bool
12
+ end
13
+
14
+ class PreviewResult < Data
15
+ attr_reader html: String
16
+ attr_reader total_pages: Integer
17
+ attr_reader environment: String
18
+
19
+ def self.new: (html: String, total_pages: Integer, environment: String) -> PreviewResult
20
+ end
21
+
22
+ class DocumentPreviewResult < Data
23
+ attr_reader html: String
24
+ attr_reader page_count: Integer
25
+
26
+ def self.new: (html: String, page_count: Integer) -> DocumentPreviewResult
27
+ end
28
+
29
+ class Thumbnail < Data
30
+ attr_reader page: Integer
31
+ attr_reader width: Integer
32
+ attr_reader height: Integer
33
+ attr_reader content_type: String
34
+ attr_reader data: String
35
+
36
+ def self.new: (page: Integer, width: Integer, height: Integer, content_type: String, data: String) -> Thumbnail
37
+ end
38
+
39
+ class DocumentDescriptor < Data
40
+ attr_reader document_id: String
41
+ attr_reader organization_id: String
42
+ attr_reader project_id: String?
43
+ attr_reader project_slug: String
44
+ attr_reader template_id: String
45
+ attr_reader template_slug: String?
46
+ attr_reader version: String
47
+ attr_reader environment: String
48
+ attr_reader api_key_id: String?
49
+ attr_reader format: String
50
+ attr_reader orientation: String?
51
+ attr_reader locale: String?
52
+ attr_reader page_count: Integer
53
+ attr_reader size_bytes: Integer
54
+ attr_reader created_at: String
55
+ attr_reader metadata: Hash[untyped, untyped]
56
+ attr_reader presigned_pdf_url: String
57
+ attr_reader expires_at: String
58
+ attr_reader _client: PoliPage::Client?
59
+
60
+ def self.new: (**untyped) -> DocumentDescriptor
61
+
62
+ def download_pdf: () -> String
63
+ def to_h: () -> Hash[Symbol, untyped]
64
+ def inspect: () -> String
65
+ end
66
+
67
+ class ProjectModeInput < Data
68
+ attr_reader project: String
69
+ attr_reader template: String
70
+ attr_reader data: Hash[untyped, untyped]
71
+ attr_reader version: String?
72
+ attr_reader format: String?
73
+ attr_reader orientation: String?
74
+ attr_reader locale: String?
75
+ attr_reader metadata: Hash[untyped, untyped]?
76
+
77
+ def self.new: (project: String, template: String, data: Hash[untyped, untyped],
78
+ ?version: String?, ?format: String?, ?orientation: String?,
79
+ ?locale: String?, ?metadata: Hash[untyped, untyped]?) -> ProjectModeInput
80
+ def to_h: () -> Hash[Symbol, untyped]
81
+ end
82
+
83
+ class InlineModeInput < Data
84
+ attr_reader template: String
85
+ attr_reader data: Hash[untyped, untyped]
86
+ attr_reader format: String?
87
+ attr_reader orientation: String?
88
+ attr_reader locale: String?
89
+ attr_reader metadata: Hash[untyped, untyped]?
90
+
91
+ def self.new: (template: String, data: Hash[untyped, untyped],
92
+ ?format: String?, ?orientation: String?,
93
+ ?locale: String?, ?metadata: Hash[untyped, untyped]?) -> InlineModeInput
94
+ def to_h: () -> Hash[Symbol, untyped]
95
+ end
96
+
97
+ class ThumbnailOptions < Data
98
+ attr_reader width: Integer
99
+ attr_reader format: String?
100
+ attr_reader quality: Integer?
101
+ attr_reader pages: Array[Integer]?
102
+
103
+ def self.new: (width: Integer, ?format: String?, ?quality: Integer?, ?pages: Array[Integer]?) -> ThumbnailOptions
104
+ def to_h: () -> Hash[Symbol, untyped]
105
+ end
106
+ end
@@ -0,0 +1,32 @@
1
+ module PoliPage
2
+ module Resources
3
+ class Render
4
+ def initialize: (PoliPage::Client client) -> void
5
+
6
+ def preview: (template: String, data: Hash[untyped, untyped],
7
+ ?project: String?, ?version: String?, ?format: String?,
8
+ ?orientation: String?, ?locale: String?,
9
+ ?metadata: Hash[untyped, untyped]?,
10
+ ?idempotency_key: String?) -> PoliPage::PreviewResult
11
+
12
+ def document: (project: String, template: String, data: Hash[untyped, untyped],
13
+ ?version: String?, ?format: String?, ?orientation: String?,
14
+ ?locale: String?, ?metadata: Hash[untyped, untyped]?,
15
+ ?idempotency_key: String?) -> PoliPage::DocumentDescriptor
16
+
17
+ def pdf: (project: String, template: String, data: Hash[untyped, untyped],
18
+ ?version: String?, ?format: String?, ?orientation: String?,
19
+ ?locale: String?, ?metadata: Hash[untyped, untyped]?,
20
+ ?idempotency_key: String?) -> String
21
+
22
+ def pdf_stream: (project: String, template: String, data: Hash[untyped, untyped],
23
+ ?version: String?, ?format: String?, ?orientation: String?,
24
+ ?locale: String?, ?metadata: Hash[untyped, untyped]?,
25
+ ?idempotency_key: String?) { (String) -> void } -> void
26
+ | (project: String, template: String, data: Hash[untyped, untyped],
27
+ ?version: String?, ?format: String?, ?orientation: String?,
28
+ ?locale: String?, ?metadata: Hash[untyped, untyped]?,
29
+ ?idempotency_key: String?) -> Enumerator[String, void]
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,9 @@
1
+ module PoliPage
2
+ class RequestEvent < Data
3
+ attr_reader method: String
4
+ attr_reader url: String
5
+ attr_reader attempt: Integer
6
+
7
+ def self.new: (method: String, url: String, attempt: Integer) -> RequestEvent
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module PoliPage
2
+ class ResponseEvent < Data
3
+ attr_reader status: Integer
4
+ attr_reader request_id: String?
5
+ attr_reader duration_ms: Integer
6
+
7
+ def self.new: (status: Integer, request_id: String?, duration_ms: Integer) -> ResponseEvent
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module PoliPage
2
+ class RetryEvent < Data
3
+ attr_reader attempt: Integer
4
+ attr_reader delay_ms: Integer
5
+ attr_reader reason: PoliPage::Error
6
+
7
+ def self.new: (attempt: Integer, delay_ms: Integer, reason: PoliPage::Error) -> RetryEvent
8
+ end
9
+ end
data/sig/poli_page.rbs ADDED
@@ -0,0 +1,3 @@
1
+ module PoliPage
2
+ VERSION: String
3
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: poli-page
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ platform: ruby
6
+ authors:
7
+ - Poli Page
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: Official Ruby client for Poli Page. Renders PDFs, previews, and thumbnails
13
+ via api.poli.page.
14
+ email: support@poli.page
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - CHANGELOG.md
20
+ - CODE_OF_CONDUCT.md
21
+ - LICENSE
22
+ - MIGRATION.md
23
+ - README.md
24
+ - SECURITY.md
25
+ - lib/poli_page.rb
26
+ - lib/poli_page/client.rb
27
+ - lib/poli_page/documents.rb
28
+ - lib/poli_page/errors.rb
29
+ - lib/poli_page/inputs/inline_mode_input.rb
30
+ - lib/poli_page/inputs/project_mode_input.rb
31
+ - lib/poli_page/inputs/thumbnail_options.rb
32
+ - lib/poli_page/internal/constants.rb
33
+ - lib/poli_page/internal/http.rb
34
+ - lib/poli_page/internal/presigned_fetch.rb
35
+ - lib/poli_page/internal/transport.rb
36
+ - lib/poli_page/internal/uuid.rb
37
+ - lib/poli_page/internal/wire.rb
38
+ - lib/poli_page/models/document_descriptor.rb
39
+ - lib/poli_page/models/document_preview_result.rb
40
+ - lib/poli_page/models/orientation.rb
41
+ - lib/poli_page/models/page_format.rb
42
+ - lib/poli_page/models/preview_result.rb
43
+ - lib/poli_page/models/thumbnail.rb
44
+ - lib/poli_page/render.rb
45
+ - lib/poli_page/render_to_file.rb
46
+ - lib/poli_page/request_event.rb
47
+ - lib/poli_page/response_event.rb
48
+ - lib/poli_page/retry_event.rb
49
+ - lib/poli_page/version.rb
50
+ - sig/poli_page.rbs
51
+ - sig/poli_page/client.rbs
52
+ - sig/poli_page/documents.rbs
53
+ - sig/poli_page/errors.rbs
54
+ - sig/poli_page/models.rbs
55
+ - sig/poli_page/render.rbs
56
+ - sig/poli_page/request_event.rbs
57
+ - sig/poli_page/response_event.rbs
58
+ - sig/poli_page/retry_event.rbs
59
+ homepage: https://poli.page
60
+ licenses:
61
+ - MIT
62
+ metadata:
63
+ homepage_uri: https://poli.page
64
+ source_code_uri: https://github.com/poli-page/sdk-ruby
65
+ changelog_uri: https://github.com/poli-page/sdk-ruby/blob/main/CHANGELOG.md
66
+ documentation_uri: https://poli-page.github.io/sdk-ruby/
67
+ bug_tracker_uri: https://github.com/poli-page/sdk-ruby/issues
68
+ rubygems_mfa_required: 'true'
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '3.2'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubygems_version: 3.6.7
84
+ specification_version: 4
85
+ summary: Poli Page SDK for Ruby — render PDFs from HTML templates via the Poli Page
86
+ API
87
+ test_files: []