seam 2.139.0 → 2.141.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 (87) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +69 -66
  3. data/README.md +86 -0
  4. data/lib/seam/http_without_workspace.rb +4 -4
  5. data/lib/seam/null.rb +23 -0
  6. data/lib/seam/paginator.rb +4 -1
  7. data/lib/seam/request.rb +49 -1
  8. data/lib/seam/resources/access_code.rb +74 -0
  9. data/lib/seam/resources/access_grant.rb +60 -0
  10. data/lib/seam/resources/access_method.rb +39 -0
  11. data/lib/seam/resources/acs_access_group.rb +45 -0
  12. data/lib/seam/resources/acs_credential.rb +67 -0
  13. data/lib/seam/resources/acs_encoder.rb +11 -0
  14. data/lib/seam/resources/acs_entrance.rb +95 -0
  15. data/lib/seam/resources/acs_system.rb +36 -0
  16. data/lib/seam/resources/acs_user.rb +66 -0
  17. data/lib/seam/resources/action_attempt.rb +192 -0
  18. data/lib/seam/resources/batch.rb +24 -0
  19. data/lib/seam/resources/client_session.rb +12 -0
  20. data/lib/seam/resources/connect_webview.rb +19 -0
  21. data/lib/seam/resources/connected_account.rb +50 -0
  22. data/lib/seam/resources/customer_portal.rb +5 -0
  23. data/lib/seam/resources/device.rb +622 -4
  24. data/lib/seam/resources/device_provider.rb +24 -0
  25. data/lib/seam/resources/event.rb +142 -3
  26. data/lib/seam/resources/instant_key.rb +13 -0
  27. data/lib/seam/resources/noise_threshold.rb +7 -0
  28. data/lib/seam/resources/pagination.rb +3 -0
  29. data/lib/seam/resources/phone.rb +29 -0
  30. data/lib/seam/resources/space.rb +19 -0
  31. data/lib/seam/resources/thermostat_daily_program.rb +9 -0
  32. data/lib/seam/resources/thermostat_schedule.rb +15 -0
  33. data/lib/seam/resources/unmanaged_access_code.rb +51 -0
  34. data/lib/seam/resources/unmanaged_access_grant.rb +56 -0
  35. data/lib/seam/resources/unmanaged_access_method.rb +36 -0
  36. data/lib/seam/resources/unmanaged_device.rb +80 -0
  37. data/lib/seam/resources/unmanaged_user_identity.rb +20 -0
  38. data/lib/seam/resources/user_identity.rb +21 -0
  39. data/lib/seam/resources/webhook.rb +4 -0
  40. data/lib/seam/resources/workspace.rb +15 -0
  41. data/lib/seam/routes/access_codes.rb +79 -79
  42. data/lib/seam/routes/access_codes_simulate.rb +3 -3
  43. data/lib/seam/routes/access_codes_unmanaged.rb +27 -23
  44. data/lib/seam/routes/access_grants.rb +57 -45
  45. data/lib/seam/routes/access_grants_unmanaged.rb +13 -13
  46. data/lib/seam/routes/access_methods.rb +32 -24
  47. data/lib/seam/routes/access_methods_unmanaged.rb +7 -7
  48. data/lib/seam/routes/acs_access_groups.rb +21 -21
  49. data/lib/seam/routes/acs_credentials.rb +40 -40
  50. data/lib/seam/routes/acs_encoders.rb +16 -16
  51. data/lib/seam/routes/acs_encoders_simulate.rb +11 -11
  52. data/lib/seam/routes/acs_entrances.rb +20 -20
  53. data/lib/seam/routes/acs_systems.rb +11 -11
  54. data/lib/seam/routes/acs_users.rb +83 -55
  55. data/lib/seam/routes/action_attempts.rb +6 -6
  56. data/lib/seam/routes/client_sessions.rb +38 -34
  57. data/lib/seam/routes/connect_webviews.rb +20 -20
  58. data/lib/seam/routes/connected_accounts.rb +24 -20
  59. data/lib/seam/routes/connected_accounts_simulate.rb +1 -1
  60. data/lib/seam/routes/customers.rb +50 -50
  61. data/lib/seam/routes/devices.rb +33 -29
  62. data/lib/seam/routes/devices_simulate.rb +7 -7
  63. data/lib/seam/routes/devices_unmanaged.rb +25 -26
  64. data/lib/seam/routes/events.rb +40 -32
  65. data/lib/seam/routes/instant_keys.rb +11 -7
  66. data/lib/seam/routes/locks.rb +20 -27
  67. data/lib/seam/routes/locks_simulate.rb +3 -3
  68. data/lib/seam/routes/noise_sensors.rb +8 -19
  69. data/lib/seam/routes/noise_sensors_noise_thresholds.rb +21 -21
  70. data/lib/seam/routes/noise_sensors_simulate.rb +1 -1
  71. data/lib/seam/routes/phones.rb +7 -7
  72. data/lib/seam/routes/phones_simulate.rb +4 -4
  73. data/lib/seam/routes/spaces.rb +53 -45
  74. data/lib/seam/routes/thermostats.rb +75 -86
  75. data/lib/seam/routes/thermostats_daily_programs.rb +9 -9
  76. data/lib/seam/routes/thermostats_schedules.rb +22 -22
  77. data/lib/seam/routes/thermostats_simulate.rb +9 -9
  78. data/lib/seam/routes/user_identities.rb +50 -46
  79. data/lib/seam/routes/user_identities_unmanaged.rb +11 -11
  80. data/lib/seam/routes/webhooks.rb +10 -10
  81. data/lib/seam/routes/workspaces.rb +19 -19
  82. data/lib/seam/strict_url_search_params_serializer.rb +17 -0
  83. data/lib/seam/url_search_params.rb +102 -0
  84. data/lib/seam/url_search_params_serializer.rb +217 -0
  85. data/lib/seam/version.rb +1 -1
  86. data/lib/seam.rb +3 -0
  87. metadata +12 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b94008b86b31b1f480fc2c3276075bc61d83a74dd09ea0af2b7831f39e603c3
4
- data.tar.gz: 1f4a039c2309d9b31c82cb9c295c09fb925161150f64eede25fcad60e35c89c0
3
+ metadata.gz: 67761c76f072fe523b56a8ee78b3112bcccd5c2da40cdd6a38c623e251a66861
4
+ data.tar.gz: 17eb707e5799d5b97c05d18abb5ce0224411a9cb5f06d00166a791de0e342c66
5
5
  SHA512:
6
- metadata.gz: c23cbe8e1da6b13568c3cdb1676d7e19c68068aaa99b651ae1915ce4ec04eb776def06af72e3b592381e200e9dd85dbc20e7d568ebe60ea5092e17b27151b67c
7
- data.tar.gz: 23f38b1e3c55349694570c17aa70a1d3e6696336d04ec0506ba4758360fdc2a651f9229263efb2c5168f95903f3525c85163ebb1b92de1856f18775e30d830df
6
+ metadata.gz: dda63b3fe99166377d432246a928f10da2f337cd8633da0df34055efb453afcffbdda6392b3ad94d4951ed12badf293dfb0bb94f5e2dd16dd8f36ef0ffe58f78
7
+ data.tar.gz: 03233cc7ee5e3136c92e3274410539c0642e69352538797198e2a2dfaebfd9d3187a6fa1e15cfbd744b36c3c8ab12e490631f6513020fd8298e295d5b3fbce34
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- seam (2.139.0)
4
+ seam (2.141.0)
5
5
  faraday (~> 2.7)
6
6
  faraday-retry (~> 2.2)
7
7
  svix (~> 1.30)
@@ -9,106 +9,109 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- addressable (2.8.7)
13
- public_suffix (>= 2.0.2, < 7.0)
14
- ansi (1.5.0)
15
- ast (2.4.2)
16
- bigdecimal (3.1.8)
17
- crack (1.0.0)
12
+ addressable (2.9.0)
13
+ public_suffix (>= 2.0.2, < 8.0)
14
+ ansi (1.6.0)
15
+ ast (2.4.3)
16
+ base64 (0.3.0)
17
+ bigdecimal (4.1.2)
18
+ crack (1.0.1)
18
19
  bigdecimal
19
20
  rexml
20
- diff-lcs (1.5.1)
21
- docile (1.4.1)
22
- faraday (2.12.0)
23
- faraday-net_http (>= 2.0, < 3.4)
21
+ diff-lcs (1.6.2)
22
+ faraday (2.14.3)
23
+ faraday-net_http (>= 2.0, < 3.5)
24
24
  json
25
25
  logger
26
- faraday-net_http (3.3.0)
27
- net-http
28
- faraday-retry (2.2.1)
26
+ faraday-net_http (3.4.4)
27
+ net-http (~> 0.5)
28
+ faraday-retry (2.4.0)
29
29
  faraday (~> 2.0)
30
- gem-release (2.2.2)
31
- hashdiff (1.1.2)
32
- json (2.8.1)
33
- language_server-protocol (3.17.0.3)
30
+ gem-release (2.2.4)
31
+ hashdiff (1.2.1)
32
+ json (2.21.2)
33
+ language_server-protocol (3.17.0.6)
34
34
  lint_roller (1.1.0)
35
- logger (1.6.1)
36
- multi_json (1.15.0)
37
- net-http (0.5.0)
38
- uri
39
- parallel (1.26.3)
35
+ logger (1.7.0)
36
+ multi_json (1.21.1)
37
+ net-http (0.9.1)
38
+ uri (>= 0.11.1)
39
+ parallel (2.1.0)
40
40
  parse_gemspec (1.0.0)
41
41
  parse_gemspec-cli (1.0.0)
42
42
  multi_json
43
43
  parse_gemspec
44
44
  thor
45
- parser (3.3.6.0)
45
+ parser (3.3.12.0)
46
46
  ast (~> 2.4.1)
47
47
  racc
48
- public_suffix (6.0.1)
48
+ prism (1.9.0)
49
+ public_suffix (7.0.5)
49
50
  racc (1.8.1)
50
51
  rainbow (3.1.1)
51
- rake (13.2.1)
52
- regexp_parser (2.9.2)
53
- rexml (3.3.9)
54
- rspec (3.13.0)
52
+ rake (13.4.2)
53
+ regexp_parser (2.12.0)
54
+ rexml (3.4.4)
55
+ rspec (3.13.2)
55
56
  rspec-core (~> 3.13.0)
56
57
  rspec-expectations (~> 3.13.0)
57
58
  rspec-mocks (~> 3.13.0)
58
- rspec-core (3.13.2)
59
+ rspec-core (3.13.6)
59
60
  rspec-support (~> 3.13.0)
60
- rspec-expectations (3.13.3)
61
+ rspec-expectations (3.13.5)
61
62
  diff-lcs (>= 1.2.0, < 2.0)
62
63
  rspec-support (~> 3.13.0)
63
- rspec-mocks (3.13.2)
64
+ rspec-mocks (3.13.8)
64
65
  diff-lcs (>= 1.2.0, < 2.0)
65
66
  rspec-support (~> 3.13.0)
66
- rspec-support (3.13.1)
67
- rubocop (1.66.1)
67
+ rspec-support (3.13.7)
68
+ rubocop (1.88.2)
68
69
  json (~> 2.3)
69
- language_server-protocol (>= 3.17.0)
70
- parallel (~> 1.10)
70
+ language_server-protocol (~> 3.17.0.2)
71
+ lint_roller (~> 1.1.0)
72
+ parallel (>= 1.10)
71
73
  parser (>= 3.3.0.2)
72
74
  rainbow (>= 2.2.2, < 4.0)
73
- regexp_parser (>= 2.4, < 3.0)
74
- rubocop-ast (>= 1.32.2, < 2.0)
75
+ regexp_parser (>= 2.9.3, < 3.0)
76
+ rubocop-ast (>= 1.49.0, < 2.0)
75
77
  ruby-progressbar (~> 1.7)
76
- unicode-display_width (>= 2.4.0, < 3.0)
77
- rubocop-ast (1.35.0)
78
- parser (>= 3.3.1.0)
79
- rubocop-performance (1.22.1)
80
- rubocop (>= 1.48.1, < 2.0)
81
- rubocop-ast (>= 1.31.1, < 2.0)
78
+ unicode-display_width (>= 2.4.0, < 4.0)
79
+ rubocop-ast (1.50.0)
80
+ parser (>= 3.3.7.2)
81
+ prism (~> 1.7)
82
+ rubocop-performance (1.26.1)
83
+ lint_roller (~> 1.1)
84
+ rubocop (>= 1.75.0, < 2.0)
85
+ rubocop-ast (>= 1.47.1, < 2.0)
82
86
  ruby-progressbar (1.13.0)
83
- simplecov (0.22.0)
84
- docile (~> 1.1)
85
- simplecov-html (~> 0.11)
86
- simplecov_json_formatter (~> 0.1)
87
- simplecov-console (0.9.2)
87
+ simplecov (1.1.1)
88
+ simplecov-console (0.9.5)
88
89
  ansi
89
90
  simplecov
90
91
  terminal-table
91
- simplecov-html (0.13.1)
92
- simplecov_json_formatter (0.1.4)
93
- standard (1.41.1)
92
+ standard (1.56.0)
94
93
  language_server-protocol (~> 3.17.0.2)
95
94
  lint_roller (~> 1.0)
96
- rubocop (~> 1.66.0)
95
+ rubocop (~> 1.88.0)
97
96
  standard-custom (~> 1.0.0)
98
- standard-performance (~> 1.5)
97
+ standard-performance (~> 1.8)
99
98
  standard-custom (1.0.2)
100
99
  lint_roller (~> 1.0)
101
100
  rubocop (~> 1.50)
102
- standard-performance (1.5.0)
101
+ standard-performance (1.9.0)
103
102
  lint_roller (~> 1.1)
104
- rubocop-performance (~> 1.22.0)
105
- svix (1.40.0)
106
- terminal-table (3.0.2)
107
- unicode-display_width (>= 1.1.1, < 3)
108
- thor (1.3.2)
109
- unicode-display_width (2.6.0)
110
- uri (1.0.1)
111
- webmock (3.24.0)
103
+ rubocop-performance (~> 1.26.0)
104
+ svix (1.99.1)
105
+ base64 (~> 0.3.0)
106
+ logger (~> 1.0)
107
+ terminal-table (4.0.0)
108
+ unicode-display_width (>= 1.1.1, < 4)
109
+ thor (1.5.0)
110
+ unicode-display_width (3.2.0)
111
+ unicode-emoji (~> 4.1)
112
+ unicode-emoji (4.2.0)
113
+ uri (1.1.1)
114
+ webmock (3.26.2)
112
115
  addressable (>= 2.8.0)
113
116
  crack (>= 0.3.2)
114
117
  hashdiff (>= 0.4.0, < 2.0.0)
@@ -124,10 +127,10 @@ DEPENDENCIES
124
127
  rake (~> 13.0)
125
128
  rspec (~> 3.0)
126
129
  seam!
127
- simplecov (~> 0.21)
130
+ simplecov (~> 1.1)
128
131
  simplecov-console (~> 0.9)
129
132
  standard (~> 1.3)
130
- webmock (~> 3.24.0)
133
+ webmock (~> 3.26.2)
131
134
 
132
135
  BUNDLED WITH
133
- 2.5.16
136
+ 2.5.22
data/README.md CHANGED
@@ -27,6 +27,7 @@ accurate and fully typed.
27
27
  - [API Key](#api-key)
28
28
  - [Personal Access Token](#personal-access-token)
29
29
  - [Action Attempts](#action-attempts)
30
+ - [Setting a value to null](#setting-a-value-to-null)
30
31
  - [Pagination](#pagination)
31
32
  - [Manually fetch pages with the next_page_cursor](#manually-fetch-pages-with-the-next_page_cursor)
32
33
  - [Resume pagination](#resume-pagination)
@@ -43,6 +44,7 @@ accurate and fully typed.
43
44
  - [Configuring the Faraday Client](#configuring-the-faraday-client)
44
45
  - [Using the Faraday Client](#using-the-faraday-client)
45
46
  - [Overriding the Client](#overriding-the-client)
47
+ - [Serializing URL search params](#serializing-url-search-params)
46
48
  - [Development and Testing](#development-and-testing)
47
49
  - [Quickstart](#quickstart)
48
50
  - [Source code](#source-code)
@@ -226,6 +228,35 @@ rescue Seam::ActionAttemptTimeoutError
226
228
  end
227
229
  ```
228
230
 
231
+ ### Setting a value to null
232
+
233
+ The Seam API distinguishes three states for an updatable parameter:
234
+ omitted (leave the stored value unchanged), null (unset the stored value),
235
+ and a value (set it).
236
+
237
+ Ruby's `nil` means omitted.
238
+ The SDK removes `nil` parameters from the request entirely,
239
+ so passing `nil` never unsets a value.
240
+ To unset a value, pass the `Seam::NULL` sentinel,
241
+ which the SDK sends as JSON `null` in request bodies
242
+ and as an empty value in query strings:
243
+
244
+ ```ruby
245
+ require "seam"
246
+
247
+ seam = Seam.new
248
+
249
+ # Leaves ends_at unchanged.
250
+ seam.access_grants.update(access_grant_id: access_grant_id, ends_at: nil)
251
+
252
+ # Unsets ends_at so the grant no longer expires.
253
+ seam.access_grants.update(access_grant_id: access_grant_id, ends_at: Seam::NULL)
254
+ ```
255
+
256
+ Only pass `Seam::NULL` for parameters the API documents as nullable.
257
+ Generated methods document nullable parameters
258
+ with `Seam::Null` in their `@param` types, e.g. `[String, Seam::Null, nil]`.
259
+
229
260
  ### Pagination
230
261
 
231
262
  Some Seam API endpoints that return lists of resources support pagination.
@@ -489,6 +520,61 @@ devices = seam.client.get("/devices/list").body["devices"]
489
520
  A Faraday compatible client may be provided to create a `Seam` instance.
490
521
  This API is used internally and is not directly supported.
491
522
 
523
+ #### Serializing URL search params
524
+
525
+ The Seam API parses URL search params as complex types.
526
+ If you call it with your own HTTP client,
527
+ `Seam.serialize_url_search_params` is exported for that purpose.
528
+ The `_strict=true` parameter is added to any non-empty query
529
+ so the Seam API uses strict, schema-aware parsing.
530
+ A query with no serializable params remains empty.
531
+
532
+ ```ruby
533
+ require "net/http"
534
+ require "seam"
535
+
536
+ uri = URI("https://connect.getseam.com/devices/list")
537
+ uri.query = Seam.serialize_url_search_params({device_ids: ["device1", "device2"]})
538
+
539
+ Net::HTTP.get(uri, {"Authorization" => "Bearer your-api-key"})
540
+ ```
541
+
542
+ The serialization defines the name and value of each search param,
543
+ where every value is a string.
544
+ `Seam::UrlSearchParams` holds those pairs and renders the query string,
545
+ as [URLSearchParams] does for the [reference implementation]:
546
+
547
+ ```ruby
548
+ require "seam"
549
+
550
+ search_params = Seam::UrlSearchParams.new
551
+
552
+ Seam.update_url_search_params(search_params, {device_ids: ["device1", "device2"]})
553
+
554
+ search_params.to_a
555
+ # => [["device_ids", "device1"], ["device_ids", "device2"], ["_strict", "true"]]
556
+
557
+ search_params.to_s
558
+ # => "device_ids=device1&device_ids=device2&_strict=true"
559
+ ```
560
+
561
+ Pass either the query string or the pairs to your HTTP client.
562
+ A client may percent-encode a few characters differently
563
+ than `URLSearchParams` does,
564
+ which the Seam API reads as the same params either way.
565
+
566
+ A param set to `nil` is omitted,
567
+ while a param set to `Seam::NULL` is serialized to an empty value,
568
+ which the Seam API reads as null,
569
+ as described in [Setting a value to null](#setting-a-value-to-null).
570
+ A param that cannot be represented raises a `Seam::UnserializableParamError`.
571
+
572
+ The Seam API parses these params with the corresponding [parser].
573
+
574
+ [URLSearchParams]: https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
575
+ [reference implementation]: https://github.com/seamapi/url-search-params-serializer
576
+ [parser]: https://github.com/seamapi/url-search-params-parser
577
+
492
578
  ## Development and Testing
493
579
 
494
580
  ### Quickstart
@@ -78,12 +78,12 @@ module Seam
78
78
  @workspaces = workspaces
79
79
  end
80
80
 
81
- def list(**kwargs)
82
- @workspaces.list(**kwargs)
81
+ def list(**)
82
+ @workspaces.list(**)
83
83
  end
84
84
 
85
- def create(**kwargs)
86
- @workspaces.create(**kwargs)
85
+ def create(**)
86
+ @workspaces.create(**)
87
87
  end
88
88
  end
89
89
 
data/lib/seam/null.rb ADDED
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "singleton"
4
+
5
+ module Seam
6
+ # The type of the {Seam::NULL} sentinel.
7
+ class Null
8
+ include Singleton
9
+
10
+ def to_s
11
+ "NULL"
12
+ end
13
+
14
+ def inspect
15
+ "NULL"
16
+ end
17
+ end
18
+
19
+ # Sentinel for an explicit JSON null: +nil+ omits a parameter, +Seam::NULL+
20
+ # unsets its stored value. Only for parameters the API documents as
21
+ # nullable.
22
+ NULL = Null.instance
23
+ end
@@ -11,6 +11,9 @@ module Seam
11
11
  def initialize(request, params = {})
12
12
  raise ArgumentError, "request must be a Method" unless request.is_a?(Method)
13
13
  raise ArgumentError, "params must be a Hash" unless params.is_a?(Hash)
14
+ unless request.parameters.any? { |_, name| name == :page_cursor }
15
+ raise ArgumentError, "request does not support pagination"
16
+ end
14
17
 
15
18
  @request = request
16
19
  @params = params.transform_keys(&:to_sym)
@@ -71,7 +74,7 @@ module Seam
71
74
  end
72
75
  end
73
76
 
74
- Pagination = Struct.new(:has_next_page, :next_page_cursor, :next_page_url, keyword_init: true) do
77
+ Pagination = Struct.new(:has_next_page, :next_page_cursor, :next_page_url) do
75
78
  def self.from_hash(hash)
76
79
  return nil unless hash.is_a?(Hash) && !hash.empty?
77
80
 
data/lib/seam/request.rb CHANGED
@@ -5,6 +5,7 @@ require "faraday/retry"
5
5
  require_relative "defaults"
6
6
  require_relative "version"
7
7
  require_relative "paginator"
8
+ require_relative "strict_url_search_params_serializer"
8
9
 
9
10
  module Seam
10
11
  module Http
@@ -16,7 +17,11 @@ module Seam
16
17
  default_options = {
17
18
  url: endpoint,
18
19
  headers: auth_headers.merge(default_headers),
19
- request: {timeout: timeout, open_timeout: timeout}
20
+ request: {
21
+ timeout: timeout,
22
+ open_timeout: timeout,
23
+ params_encoder: UrlSearchParamsEncoder
24
+ }
20
25
  }
21
26
 
22
27
  options = deep_merge(default_options, faraday_options)
@@ -33,6 +38,7 @@ module Seam
33
38
  faraday_retry_options = default_faraday_retry_options.merge(faraday_retry_options)
34
39
 
35
40
  Faraday.new(options) do |builder|
41
+ builder.use ReplaceNullMiddleware
36
42
  builder.request :json
37
43
  builder.use Seam::PaginationMiddleware
38
44
  builder.response :json
@@ -97,6 +103,14 @@ module Seam
97
103
  end
98
104
  end
99
105
 
106
+ class ReplaceNullMiddleware < Faraday::Middleware
107
+ def on_request(env)
108
+ return unless env.body.is_a?(Hash) || env.body.is_a?(Array)
109
+
110
+ env.body = Seam.replace_null(env.body)
111
+ end
112
+ end
113
+
100
114
  def self.deep_merge(hash1, hash2)
101
115
  result = hash1.dup
102
116
  hash2.each do |key, value|
@@ -111,5 +125,39 @@ module Seam
111
125
 
112
126
  private_class_method :deep_merge
113
127
  end
128
+
129
+ module UrlSearchParamsEncoder
130
+ # Pairs decoded from a query string already present in the request
131
+ # path, passed through {encode} verbatim rather than re-serialized.
132
+ Decoded = Struct.new(:values)
133
+
134
+ def self.encode(params)
135
+ search_params = Seam::UrlSearchParams.new
136
+ map_params = {}
137
+
138
+ params.each do |name, value|
139
+ if value.is_a?(Decoded)
140
+ value.values.each { |element| search_params.append(name, element) }
141
+ else
142
+ map_params[name] = value
143
+ end
144
+ end
145
+
146
+ return search_params.to_s if map_params.empty?
147
+
148
+ Seam.update_url_search_params(search_params, map_params)
149
+ search_params.to_s
150
+ end
151
+
152
+ # Called by Faraday when a request path carries its own query string.
153
+ def self.decode(query)
154
+ return {} if query.nil? || query.empty?
155
+
156
+ pairs = URI.decode_www_form(query.encode(Encoding::UTF_8))
157
+ pairs.each_with_object({}) do |(name, value), decoded|
158
+ (decoded[name] ||= Decoded.new([])).values << value
159
+ end
160
+ end
161
+ end
114
162
  end
115
163
  end