boldsign 0.1.0 → 0.3.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/CHANGELOG.md +23 -0
- data/lib/boldsign/case_convert.rb +43 -0
- data/lib/boldsign/client.rb +1 -1
- data/lib/boldsign/resources/document.rb +61 -3
- data/lib/boldsign/version.rb +1 -1
- data/lib/boldsign.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9fc2965681164f6e721c5d7a18b9370d1ddfd7570916cde257078b29d3be34d5
|
|
4
|
+
data.tar.gz: 9210a75137622829403d8b6ae47dfa1f51e3f71462313b12ef076e6b240391a9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 00ab26917b2ad3ab3af835ec58842b1fa75ba19d61254447466a5eee7b5db388f9c5800ec7807806fd737526772516f43277520ba1005d18539a8e54356f0ee8
|
|
7
|
+
data.tar.gz: '038338c9aca83500340f85e0d6d2e6247466701739ff3606ae8bf59905f930541514e9e3130ac5296b9ee658085993c601126d84ee5e6527451b4ba1d75df1ab'
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.3.0] — 2026-05-22
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- Request bodies (JSON and multipart) now have their Hash keys recursively
|
|
14
|
+
converted to PascalCase before being sent to BoldSign. Callers can pass
|
|
15
|
+
idiomatic snake_case (or camelCase) Ruby symbols/strings and the gem will
|
|
16
|
+
emit the casing the API expects. Already-PascalCase keys pass through
|
|
17
|
+
unchanged. Non-Hash/Array values (including IO objects and
|
|
18
|
+
`Faraday::Multipart::FilePart` instances) are not touched.
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- `Boldsign::CaseConvert` module with `pascalize` / `pascalize_key` helpers
|
|
22
|
+
for callers that need to PascalCase keys outside of the HTTP path.
|
|
23
|
+
|
|
24
|
+
## [0.2.0] — 2026-05-22
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
- `Boldsign::Resources::Document#send_document` now supports multipart file
|
|
28
|
+
uploads via a `files:` keyword. Pass an array of `{io:, filename:,
|
|
29
|
+
content_type:}` hashes (or `Faraday::Multipart::FilePart` instances) to
|
|
30
|
+
send PDFs (or other supported file types) for signature. When `files:` is
|
|
31
|
+
omitted the request is sent as JSON, preserving the prior behavior.
|
|
32
|
+
|
|
10
33
|
## [0.1.0] — 2026-05-22
|
|
11
34
|
|
|
12
35
|
### Added
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Boldsign
|
|
2
|
+
# Converts arbitrary Ruby hash keys (snake_case or camelCase, Symbol or
|
|
3
|
+
# String) to PascalCase string keys recursively, matching the casing the
|
|
4
|
+
# BoldSign REST API expects in request bodies. Non-Hash and non-Array values
|
|
5
|
+
# — including binary IO objects, FilePart instances, scalars, dates, etc. —
|
|
6
|
+
# pass through untouched.
|
|
7
|
+
module CaseConvert
|
|
8
|
+
module_function
|
|
9
|
+
|
|
10
|
+
# Recursively PascalCase every Hash key reachable from `obj`.
|
|
11
|
+
# @param obj [Object]
|
|
12
|
+
# @return [Object] new object with the same shape and PascalCase keys
|
|
13
|
+
def pascalize(obj)
|
|
14
|
+
case obj
|
|
15
|
+
when Hash
|
|
16
|
+
obj.each_with_object({}) { |(k, v), acc| acc[pascalize_key(k)] = pascalize(v) }
|
|
17
|
+
when Array
|
|
18
|
+
obj.map { |v| pascalize(v) }
|
|
19
|
+
else
|
|
20
|
+
obj
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @param key [String, Symbol]
|
|
25
|
+
# @return [String] PascalCase string
|
|
26
|
+
def pascalize_key(key)
|
|
27
|
+
str = key.to_s
|
|
28
|
+
return str if str.empty?
|
|
29
|
+
|
|
30
|
+
if str.include?("_")
|
|
31
|
+
str.split("_").map { |part| capitalize_word(part) }.join
|
|
32
|
+
else
|
|
33
|
+
capitalize_word(str)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def capitalize_word(str)
|
|
38
|
+
return str if str.empty?
|
|
39
|
+
|
|
40
|
+
str[0].upcase + str[1..]
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
data/lib/boldsign/client.rb
CHANGED
|
@@ -125,7 +125,7 @@ module Boldsign
|
|
|
125
125
|
req.body = body
|
|
126
126
|
else
|
|
127
127
|
req.headers["Content-Type"] = "application/json"
|
|
128
|
-
req.body = body.is_a?(String) ? body : JSON.generate(body)
|
|
128
|
+
req.body = body.is_a?(String) ? body : JSON.generate(CaseConvert.pascalize(body))
|
|
129
129
|
end
|
|
130
130
|
end
|
|
131
131
|
end
|
|
@@ -4,11 +4,17 @@ module Boldsign
|
|
|
4
4
|
# sending, listing, downloading, editing, reminding, authenticating, tagging,
|
|
5
5
|
# and embedded signing flows.
|
|
6
6
|
#
|
|
7
|
-
# @example Send a document
|
|
7
|
+
# @example Send a document (JSON body)
|
|
8
|
+
# client.documents.send_document(
|
|
9
|
+
# title: "NDA",
|
|
10
|
+
# signers: [{ name: "Jane", emailAddress: "jane@example.com", signerOrder: 1 }]
|
|
11
|
+
# )
|
|
12
|
+
#
|
|
13
|
+
# @example Send a document with file uploads (multipart)
|
|
8
14
|
# client.documents.send_document(
|
|
9
15
|
# title: "NDA",
|
|
10
16
|
# signers: [{ name: "Jane", emailAddress: "jane@example.com", signerOrder: 1 }],
|
|
11
|
-
# files: [
|
|
17
|
+
# files: [{ io: StringIO.new(pdf_bytes), filename: "nda.pdf", content_type: "application/pdf" }]
|
|
12
18
|
# )
|
|
13
19
|
#
|
|
14
20
|
# @see https://developers.boldsign.com/documents
|
|
@@ -18,7 +24,25 @@ module Boldsign
|
|
|
18
24
|
def behalf_list(**params); @client.get("/v1/document/behalfList", params); end
|
|
19
25
|
def properties(document_id); @client.get("/v1/document/properties", documentId: document_id); end
|
|
20
26
|
|
|
21
|
-
|
|
27
|
+
# Send a document for signature.
|
|
28
|
+
#
|
|
29
|
+
# Pass `files:` to upload one or more PDFs (or other supported file types)
|
|
30
|
+
# via multipart/form-data. Without `files:`, the request is sent as JSON
|
|
31
|
+
# and BoldSign must already know the file content (e.g. via Base64 in the
|
|
32
|
+
# body or by referencing an existing template).
|
|
33
|
+
#
|
|
34
|
+
# @param files [Array<Hash>, nil] When present, each hash must include
|
|
35
|
+
# `:io` and `:filename` and may include `:content_type`. The request
|
|
36
|
+
# switches to multipart/form-data and remaining kwargs are serialized
|
|
37
|
+
# to multipart string parts (non-scalar values become JSON strings).
|
|
38
|
+
# @param body [Hash] Top-level BoldSign send-document fields
|
|
39
|
+
# (`title:`, `signers:`, `disableEmails:`, `metadata:`, etc.).
|
|
40
|
+
def send_document(files: nil, **body)
|
|
41
|
+
return @client.post("/v1/document/send", body: body) if files.nil?
|
|
42
|
+
|
|
43
|
+
@client.post("/v1/document/send", body: multipart_send_body(body, files), multipart: true)
|
|
44
|
+
end
|
|
45
|
+
|
|
22
46
|
def draft_send(body); @client.post("/v1/document/draftSend", body: body); end
|
|
23
47
|
def edit(document_id, body); @client.put("/v1/document/edit", body: body, params: { documentId: document_id }); end
|
|
24
48
|
def cancel_editing(document_id); @client.post("/v1/document/cancelEditing", params: { documentId: document_id }); end
|
|
@@ -46,6 +70,40 @@ module Boldsign
|
|
|
46
70
|
def add_authentication(document_id, body); @client.patch("/v1/document/addAuthentication", body: body, params: { documentId: document_id }); end
|
|
47
71
|
|
|
48
72
|
def prefill_fields(document_id, body); @client.patch("/v1/document/prefillFields", body: body, params: { documentId: document_id }); end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def multipart_send_body(body, files)
|
|
77
|
+
parts = body.each_with_object({}) do |(key, value), acc|
|
|
78
|
+
next if value.nil?
|
|
79
|
+
|
|
80
|
+
pascal_key = Boldsign::CaseConvert.pascalize_key(key)
|
|
81
|
+
acc[pascal_key] = if scalar?(value)
|
|
82
|
+
value.to_s
|
|
83
|
+
else
|
|
84
|
+
JSON.generate(Boldsign::CaseConvert.pascalize(value))
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
parts["Files"] = Array(files).map { |f| file_part(f) }
|
|
88
|
+
parts
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def file_part(file)
|
|
92
|
+
return file if file.is_a?(Faraday::Multipart::FilePart)
|
|
93
|
+
|
|
94
|
+
unless file.is_a?(Hash)
|
|
95
|
+
raise ArgumentError, "files entries must be Hash with :io and :filename, or Faraday::Multipart::FilePart"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
io = file[:io] || file["io"] or raise ArgumentError, "file part missing :io"
|
|
99
|
+
filename = file[:filename] || file["filename"] or raise ArgumentError, "file part missing :filename"
|
|
100
|
+
type = file[:content_type] || file["content_type"] || "application/octet-stream"
|
|
101
|
+
Faraday::Multipart::FilePart.new(io, type, filename)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def scalar?(value)
|
|
105
|
+
value.is_a?(String) || value.is_a?(Numeric) || value == true || value == false
|
|
106
|
+
end
|
|
49
107
|
end
|
|
50
108
|
end
|
|
51
109
|
end
|
data/lib/boldsign/version.rb
CHANGED
data/lib/boldsign.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: boldsign
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- James Klein
|
|
@@ -92,6 +92,7 @@ files:
|
|
|
92
92
|
- README.md
|
|
93
93
|
- boldsign.gemspec
|
|
94
94
|
- lib/boldsign.rb
|
|
95
|
+
- lib/boldsign/case_convert.rb
|
|
95
96
|
- lib/boldsign/client.rb
|
|
96
97
|
- lib/boldsign/error.rb
|
|
97
98
|
- lib/boldsign/resource.rb
|