seatlayer 0.6.0 → 0.7.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 +15 -0
- data/README.md +102 -17
- data/lib/seatlayer/channels.rb +2 -4
- data/lib/seatlayer/http_client.rb +6 -0
- data/lib/seatlayer/inventory.rb +1 -2
- data/lib/seatlayer/resources.rb +1 -2
- data/lib/seatlayer/seasons.rb +272 -0
- data/lib/seatlayer/version.rb +1 -1
- data/lib/seatlayer.rb +3 -1
- metadata +5 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a65cc789351eb854341bf167fdedbd818035c29639e212df5312597f46e3f23c
|
|
4
|
+
data.tar.gz: 0fc4163ccaedd380264fbc53853c71c476f4bbfdb4f99180663f66c434d94b66
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dc59365e346c8a14cf52014ca804f70aa63eabee928214906913c060bf58f4c2edb0dbb3eaec90305096b396bf2257468f444b5d8ba3f154e78f57625b125126
|
|
7
|
+
data.tar.gz: c74c63603bd068dd4566b18b1c940762de0258fbcf186b083608c263ce10ffa8a9934db69a135cdbb0d3c225a4334ecfb15a6f672e6e853c745a11d3cc9eab44
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.0 — 2026-08-30
|
|
4
|
+
|
|
5
|
+
- Added coverage for all 48 Fixed Renewable Season server
|
|
6
|
+
operations under `client.seasons`, with exact path encoding and
|
|
7
|
+
operation-specific retry/idempotency behavior.
|
|
8
|
+
- Season allocations are identity-only and the API response declares host
|
|
9
|
+
pricing authority. Buyer rehearsal validation sends no evidence body because
|
|
10
|
+
SeatLayer discovers the retained hold, booking, cancellation, and delivered
|
|
11
|
+
webhook chain automatically.
|
|
12
|
+
|
|
13
|
+
## 0.6.1
|
|
14
|
+
|
|
15
|
+
- Documentation only. Refreshes the README, adds frequently asked
|
|
16
|
+
questions, and aligns package metadata. No API or behaviour changes.
|
|
17
|
+
|
|
3
18
|
## 0.6.0 — 2026-08-23
|
|
4
19
|
|
|
5
20
|
- Added exact immutable Event configuration binding reads and compare-and-set
|
data/README.md
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
|
-
# SeatLayer Ruby SDK
|
|
1
|
+
# SeatLayer Ruby Server SDK for Reserved Seating
|
|
2
2
|
|
|
3
3
|
[](https://github.com/seatlayer/seatlayer-ruby/actions/workflows/ci.yml)
|
|
4
4
|
[](https://rubygems.org/gems/seatlayer)
|
|
5
5
|
[](https://www.ruby-lang.org/)
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
The official SeatLayer Ruby server SDK — the trusted side of a reserved-seating
|
|
9
|
+
integration. Inspect what a hold really contains, price from server-owned seating-chart
|
|
10
|
+
data, and book with a stable `booking_ref`, while managing charts, events, inventory,
|
|
11
|
+
allocations, and webhooks through one typed ticketing API client.
|
|
12
|
+
|
|
13
|
+
[`seatlayer` gem on RubyGems](https://rubygems.org/gems/seatlayer) ·
|
|
14
|
+
[SeatLayer server SDK documentation](https://docs.seatlayer.io/server-sdk/install/) ·
|
|
15
|
+
[SeatLayer developer platform](https://seatlayer.io/developers/) ·
|
|
16
|
+
[SeatLayer JavaScript seat map SDK](https://www.npmjs.com/package/@seatlayer/js) ·
|
|
17
|
+
[Server API reference](https://docs.seatlayer.io/server-api/events/)
|
|
9
18
|
|
|
10
19
|
> **Server-side only.** This gem authenticates with your secret key. Never load it anywhere a
|
|
11
20
|
> ticket buyer can reach — browser surfaces get short-lived, origin-bound tokens that you mint here.
|
|
@@ -48,6 +57,34 @@ Nullable event-create fields distinguish omission from an explicit reset: passin
|
|
|
48
57
|
|
|
49
58
|
## Test vs live
|
|
50
59
|
|
|
60
|
+
## Fixed Renewable Seasons
|
|
61
|
+
|
|
62
|
+
Version `0.7.0` exposes all 48 trusted organizer operations through
|
|
63
|
+
`client.seasons`.
|
|
64
|
+
|
|
65
|
+
After the test hold/book/cancel journey and matching webhook deliveries,
|
|
66
|
+
`validate_season_buyer_rehearsal(season_key)` sends no evidence body; SeatLayer
|
|
67
|
+
discovers the retained chain automatically. Retrieved Season holds contain
|
|
68
|
+
inventory identity, not an authoritative amount—your platform owns package
|
|
69
|
+
price, payment, order, tax, refunds, benefits, and ticket or pass delivery.
|
|
70
|
+
|
|
71
|
+
```ruby
|
|
72
|
+
checked = client.seasons.validate_season(
|
|
73
|
+
source_performance_group_keys: ["pg_subscription_run"]
|
|
74
|
+
)
|
|
75
|
+
draft = client.seasons.create_season(
|
|
76
|
+
name: "2027 subscription",
|
|
77
|
+
source_performance_group_keys: ["pg_subscription_run"],
|
|
78
|
+
idempotency_key: "season-create-2027"
|
|
79
|
+
).fetch("season")
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Treat `202` as accepted work and poll `retrieve_season_lifecycle` with the
|
|
83
|
+
returned operation identity. Buyer-session minting and domain-exact booking,
|
|
84
|
+
cancellation, and renewal actions remain single-attempt; only declared
|
|
85
|
+
header-replay catalogue mutations retry automatically.
|
|
86
|
+
|
|
87
|
+
|
|
51
88
|
Keys carry their own mode. `sk_test_…` keys can only touch test-mode events and `sk_live_…` only
|
|
52
89
|
live ones; crossing them returns `403 mode_mismatch`, surfaced as `AuthError` with `mode_mismatch?`.
|
|
53
90
|
|
|
@@ -316,32 +353,80 @@ Some API surface is intentionally unwrapped, not merely pending:
|
|
|
316
353
|
None of these are reachable through `request` as a supported path either — they are excluded from
|
|
317
354
|
the public manifest, not just from the wrapper.
|
|
318
355
|
|
|
319
|
-
##
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
356
|
+
## Frequently asked questions
|
|
357
|
+
|
|
358
|
+
### How do I book seats from Ruby?
|
|
359
|
+
|
|
360
|
+
Create a client with your secret key, obtain a hold id — either from the buyer's
|
|
361
|
+
browser session or by holding server-side — and call `inventory.book(event_key, hold_id: ..., booking_ref: ...)`.
|
|
362
|
+
`booking_ref` is your own stable order id and is the join between SeatLayer
|
|
363
|
+
inventory and your commercial order, so the same reference identifies the booking
|
|
364
|
+
in Booking History and when you later cancel it. For phone orders, box office, and
|
|
365
|
+
comps, `inventory.book_best_available` books outright with no browser involved.
|
|
366
|
+
|
|
367
|
+
### What does the server SDK do compared with the buyer SDK?
|
|
368
|
+
|
|
369
|
+
The buyer SDK runs where the ticket buyer is: it renders the interactive seating
|
|
370
|
+
chart, handles seat selection, and creates temporary holds. This server SDK is the
|
|
371
|
+
trusted side. It authenticates with your secret key, inspects what a hold actually
|
|
372
|
+
contains, prices from server-owned data, and books. Never bundle the secret key
|
|
373
|
+
into a browser or a mobile app — browser surfaces get short-lived, origin-bound
|
|
374
|
+
tokens that you mint here.
|
|
375
|
+
|
|
376
|
+
### How do temporary holds work server-side?
|
|
377
|
+
|
|
378
|
+
A hold reserves seats against concurrent buyers for a limited window.
|
|
379
|
+
`inventory.retrieve_hold(event_key, hold_id)` is the authoritative answer for what is held
|
|
380
|
+
and at what price, so charge from its `items` rather than from anything the browser
|
|
381
|
+
sent you. When an order runs longer than the checkout window, `inventory.extend_hold`
|
|
382
|
+
renews the hold instead of releasing and re-holding, which would hand the seats to
|
|
383
|
+
whoever is racing for them. Bookings carry the server's exact-selection plus
|
|
384
|
+
`booking_ref` safeguard, but the SDK sends each booking once — reconcile an unknown
|
|
385
|
+
outcome before trying again.
|
|
386
|
+
|
|
387
|
+
### Can I use my own payment provider?
|
|
388
|
+
|
|
389
|
+
Yes. SeatLayer never processes payment. Inspect the hold, compute the charge from
|
|
390
|
+
the returned `items` and their authoritative `unitPrice` and `currency`, take the
|
|
391
|
+
money through whichever provider you already use — Stripe, Adyen, Razorpay, or your
|
|
392
|
+
own — and then book the hold with your order id as `booking_ref`. SeatLayer owns
|
|
393
|
+
seating state, holds, booking concurrency, and the inventory ledger; your platform
|
|
394
|
+
owns payments, commercial orders, tickets, delivery, and refunds.
|
|
395
|
+
|
|
396
|
+
## Continue your Ruby integration
|
|
397
|
+
|
|
398
|
+
- [Follow the SeatLayer server SDK guide](https://docs.seatlayer.io/server-sdk/install/)
|
|
399
|
+
for installation, authentication, and the full hold-to-booking flow.
|
|
400
|
+
- [Handle errors, retries, and safe booking repeats](https://docs.seatlayer.io/server-sdk/reliability/)
|
|
401
|
+
before connecting a production order flow.
|
|
402
|
+
- [Verify SeatLayer webhooks](https://docs.seatlayer.io/server-sdk/webhooks/)
|
|
403
|
+
to react to holds, expiry, and bookings on your server.
|
|
404
|
+
- [Browse the SeatLayer server API reference](https://docs.seatlayer.io/server-api/events/)
|
|
405
|
+
for every endpoint behind this SDK.
|
|
406
|
+
- [Generate clients from the SeatLayer OpenAPI description](https://docs.seatlayer.io/openapi.json)
|
|
407
|
+
or explore the raw API surface.
|
|
408
|
+
- [Point AI coding agents at the SeatLayer docs index](https://docs.seatlayer.io/llms.txt)
|
|
409
|
+
(`llms.txt`) for an agent-readable map of the documentation.
|
|
410
|
+
- [Explore every SeatLayer SDK on GitHub](https://github.com/seatlayer)
|
|
411
|
+
across web, mobile, and server.
|
|
328
412
|
|
|
329
413
|
### Other SeatLayer SDKs
|
|
330
414
|
|
|
331
|
-
| Surface | Package |
|
|
332
|
-
|
|
333
|
-
|
|
|
415
|
+
| Surface | Package or source |
|
|
416
|
+
| --- | --- |
|
|
417
|
+
| JavaScript | [`@seatlayer/js`](https://www.npmjs.com/package/@seatlayer/js) |
|
|
334
418
|
| React | [`@seatlayer/react`](https://www.npmjs.com/package/@seatlayer/react) |
|
|
335
419
|
| React Native | [`@seatlayer/react-native`](https://www.npmjs.com/package/@seatlayer/react-native) |
|
|
336
420
|
| iOS | [`seatlayer-ios`](https://github.com/seatlayer/seatlayer-ios) |
|
|
337
|
-
| Android | [`seatlayer-android`](https://github.com/seatlayer/seatlayer-android) |
|
|
338
421
|
| Flutter | [`seatlayer`](https://pub.dev/packages/seatlayer) |
|
|
422
|
+
| Android | [`seatlayer-android`](https://github.com/seatlayer/seatlayer-android) |
|
|
339
423
|
| Node.js (server) | [`@seatlayer/server`](https://www.npmjs.com/package/@seatlayer/server) |
|
|
340
424
|
| Python (server) | [`seatlayer`](https://pypi.org/project/seatlayer/) |
|
|
341
425
|
| PHP (server) | [`seatlayer/seatlayer-php`](https://packagist.org/packages/seatlayer/seatlayer-php) |
|
|
342
|
-
|
|
|
343
|
-
| Go (server) | [`github.com/seatlayer/seatlayer-go`](https://pkg.go.dev/github.com/seatlayer/seatlayer-go) |
|
|
426
|
+
| Ruby (server) | [`seatlayer`](https://rubygems.org/gems/seatlayer) (this package) |
|
|
344
427
|
| .NET (server) | [`SeatLayer`](https://www.nuget.org/packages/SeatLayer) |
|
|
428
|
+
| Java (server) | [`io.seatlayer:seatlayer-java`](https://central.sonatype.com/artifact/io.seatlayer/seatlayer-java) |
|
|
429
|
+
| Go (server) | [`github.com/seatlayer/seatlayer-go`](https://pkg.go.dev/github.com/seatlayer/seatlayer-go) |
|
|
345
430
|
|
|
346
431
|
## Development
|
|
347
432
|
|
data/lib/seatlayer/channels.rb
CHANGED
|
@@ -63,7 +63,7 @@ module SeatLayer
|
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
# Explicit keywords document each security boundary carried by the token.
|
|
66
|
-
# rubocop:disable Metrics/ParameterLists
|
|
66
|
+
# rubocop:disable-next Metrics/ParameterLists
|
|
67
67
|
def create_buyer_access_session(event_key, include_public:, allowed_origin:, channel_ids: nil,
|
|
68
68
|
expires_in_seconds: nil, max_quantity: UNSET, buyer_ref: UNSET,
|
|
69
69
|
partner_ref: UNSET, client_request_id: UNSET, idempotency_key: nil)
|
|
@@ -75,7 +75,6 @@ module SeatLayer
|
|
|
75
75
|
@client.post("/v1/events/#{encode(event_key)}/buyer-access-sessions", body,
|
|
76
76
|
idempotency_key: idempotency_key)
|
|
77
77
|
end
|
|
78
|
-
# rubocop:enable Metrics/ParameterLists
|
|
79
78
|
|
|
80
79
|
def list_buyer_access_sessions(event_key, limit: nil)
|
|
81
80
|
@client.get("/v1/events/#{encode(event_key)}/buyer-access-sessions",
|
|
@@ -88,7 +87,7 @@ module SeatLayer
|
|
|
88
87
|
|
|
89
88
|
# The URL and capability in this response are revealed once. Persist them
|
|
90
89
|
# immediately; this mutation is deliberately never retried automatically.
|
|
91
|
-
# rubocop:disable Metrics/ParameterLists
|
|
90
|
+
# rubocop:disable-next Metrics/ParameterLists
|
|
92
91
|
def create_access_link(event_key, channel_id, label: UNSET, expires_at: nil,
|
|
93
92
|
max_redemptions: nil, max_quantity: nil,
|
|
94
93
|
session_ttl_seconds: nil, include_public: nil, reason: nil,
|
|
@@ -101,7 +100,6 @@ module SeatLayer
|
|
|
101
100
|
@client.post(path(event_key, "/#{encode(channel_id)}/access-links"), body,
|
|
102
101
|
idempotency_key: idempotency_key)
|
|
103
102
|
end
|
|
104
|
-
# rubocop:enable Metrics/ParameterLists
|
|
105
103
|
|
|
106
104
|
# Status only: the API never returns a previously revealed capability.
|
|
107
105
|
def list_access_links(event_key, channel_id)
|
|
@@ -101,6 +101,12 @@ module SeatLayer
|
|
|
101
101
|
request("POST", path, body: body, idempotency_key: idempotency_key, retry_policy: retry_policy)
|
|
102
102
|
end
|
|
103
103
|
|
|
104
|
+
# Internal path for non-POST mutations backed by exact response replay.
|
|
105
|
+
def mutation_with_header_replay(method, path, body = nil, idempotency_key: nil)
|
|
106
|
+
request(method, path, body: body, idempotency_key: idempotency_key,
|
|
107
|
+
retry_policy: :header_replay)
|
|
108
|
+
end
|
|
109
|
+
|
|
104
110
|
def put(path, body)
|
|
105
111
|
request("PUT", path, body: body)
|
|
106
112
|
end
|
data/lib/seatlayer/inventory.rb
CHANGED
|
@@ -186,7 +186,7 @@ module SeatLayer
|
|
|
186
186
|
# Mint a designer token so an organiser can edit a chart inside your own UI.
|
|
187
187
|
# Requires a chart id that already exists — create or copy one first.
|
|
188
188
|
# Explicit keywords keep each security and feature-policy boundary visible.
|
|
189
|
-
# rubocop:disable Metrics/ParameterLists
|
|
189
|
+
# rubocop:disable-next Metrics/ParameterLists
|
|
190
190
|
def create_designer_session(workspace_id:, chart_id:, allowed_origin:,
|
|
191
191
|
authority: nil, can_publish: nil, mode: nil,
|
|
192
192
|
safe_mode_options: nil, features: nil, expires_in_seconds: nil)
|
|
@@ -197,7 +197,6 @@ module SeatLayer
|
|
|
197
197
|
"expiresInSeconds" => expires_in_seconds })
|
|
198
198
|
@client.post("/v1/designer/sessions", body)
|
|
199
199
|
end
|
|
200
|
-
# rubocop:enable Metrics/ParameterLists
|
|
201
200
|
|
|
202
201
|
def revoke_designer_session(session_id)
|
|
203
202
|
@client.delete("/v1/designer/sessions/#{encode(session_id)}")
|
data/lib/seatlayer/resources.rb
CHANGED
|
@@ -175,7 +175,7 @@ module SeatLayer
|
|
|
175
175
|
end
|
|
176
176
|
end
|
|
177
177
|
|
|
178
|
-
# rubocop:disable Metrics/ParameterLists
|
|
178
|
+
# rubocop:disable-next Metrics/ParameterLists
|
|
179
179
|
def create(chart_id:, name: nil, slug: nil, starts_at: UNSET, venue: UNSET,
|
|
180
180
|
external_ref: UNSET, currency: UNSET, idempotency_key: nil,
|
|
181
181
|
description: UNSET, ends_at: UNSET, timezone: UNSET, locale: UNSET,
|
|
@@ -190,7 +190,6 @@ module SeatLayer
|
|
|
190
190
|
"/v1/events", body, idempotency_key: idempotency_key, retry_policy: :header_replay
|
|
191
191
|
)
|
|
192
192
|
end
|
|
193
|
-
# rubocop:enable Metrics/ParameterLists
|
|
194
193
|
|
|
195
194
|
def retrieve(event_key)
|
|
196
195
|
@client.get("/v1/events/#{encode(event_key)}")
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SeatLayer
|
|
4
|
+
# Fixed Renewable Season organizer operations for trusted backends.
|
|
5
|
+
#
|
|
6
|
+
# Browser selection belongs in the distinct SeasonPicker. Give it only the
|
|
7
|
+
# show-once scoped token returned by +create_season_buyer_access_session+.
|
|
8
|
+
class Seasons < Resource
|
|
9
|
+
def list_seasons(workspace_id: nil, structure_state: nil, limit: nil, cursor: nil)
|
|
10
|
+
@client.get("/v1/seasons", compact({ "workspaceId" => workspace_id,
|
|
11
|
+
"structureState" => structure_state,
|
|
12
|
+
"limit" => limit, "cursor" => cursor }))
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Read-only compatibility preflight.
|
|
16
|
+
def validate_season(event_keys: nil, source_performance_group_keys: nil)
|
|
17
|
+
@client.post("/v1/seasons/validate",
|
|
18
|
+
selection(event_keys, source_performance_group_keys))
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def create_season(name:, event_keys: nil, source_performance_group_keys: nil,
|
|
22
|
+
edition: UNSET, idempotency_key: nil)
|
|
23
|
+
body = selection(event_keys, source_performance_group_keys).merge("name" => name)
|
|
24
|
+
body.merge!(supplied({ "edition" => edition }))
|
|
25
|
+
@client.post("/v1/seasons", body, idempotency_key: idempotency_key,
|
|
26
|
+
retry_policy: :header_replay)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def retrieve_season(season_key)
|
|
30
|
+
@client.get(path(season_key))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def update_season(season_key, expected_revision:, name: nil, edition: UNSET,
|
|
34
|
+
idempotency_key: nil)
|
|
35
|
+
body = compact({ "expectedRevision" => expected_revision, "name" => name })
|
|
36
|
+
body.merge!(supplied({ "edition" => edition }))
|
|
37
|
+
@client.mutation_with_header_replay(
|
|
38
|
+
"PATCH", path(season_key), body, idempotency_key: idempotency_key
|
|
39
|
+
)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def delete_season(season_key, idempotency_key: nil)
|
|
43
|
+
@client.mutation_with_header_replay(
|
|
44
|
+
"DELETE", path(season_key), idempotency_key: idempotency_key
|
|
45
|
+
)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def activate_season(season_key, expected_revision:)
|
|
49
|
+
lifecycle(season_key, "activate", expected_revision)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def close_season(season_key, expected_revision:)
|
|
53
|
+
lifecycle(season_key, "close", expected_revision)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def archive_season(season_key, expected_revision:)
|
|
57
|
+
lifecycle(season_key, "archive", expected_revision)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def retrieve_season_lifecycle(season_key, operation_id)
|
|
61
|
+
@client.get(path(season_key, "/lifecycle/#{encode(operation_id)}"))
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def create_season_plan(season_key, name:, event_keys: nil,
|
|
65
|
+
source_performance_group_keys: nil, idempotency_key: nil)
|
|
66
|
+
body = selection(event_keys, source_performance_group_keys).merge("name" => name)
|
|
67
|
+
@client.post(path(season_key, "/plans"), body, idempotency_key: idempotency_key,
|
|
68
|
+
retry_policy: :header_replay)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def retrieve_season_plan(season_key, plan_key)
|
|
72
|
+
@client.get(path(season_key, "/plans/#{encode(plan_key)}"))
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def publish_season_plan(season_key, plan_key, expected_revision:)
|
|
76
|
+
@client.post(path(season_key, "/plans/#{encode(plan_key)}/publish"),
|
|
77
|
+
{ "expectedRevision" => expected_revision })
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def supersede_season_plan(season_key, plan_key, expected_revision:)
|
|
81
|
+
@client.post(path(season_key, "/plans/#{encode(plan_key)}/supersede"),
|
|
82
|
+
{ "expectedRevision" => expected_revision })
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def open_season_sales(season_key, expected_revision:)
|
|
86
|
+
sales(season_key, "open", expected_revision)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def pause_season_sales(season_key, expected_revision:)
|
|
90
|
+
sales(season_key, "pause", expected_revision)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def resume_season_sales(season_key, expected_revision:)
|
|
94
|
+
sales(season_key, "resume", expected_revision)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def end_season_sales(season_key, expected_revision:)
|
|
98
|
+
sales(season_key, "end", expected_revision)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def duplicate_season_to_live(season_key, event_keys:, name: nil, idempotency_key: nil)
|
|
102
|
+
@client.post(path(season_key, "/duplicate-to-live"),
|
|
103
|
+
compact({ "eventKeys" => event_keys, "name" => name }),
|
|
104
|
+
idempotency_key: idempotency_key, retry_policy: :header_replay)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Reveal one show-once browser bearer. This call is deliberately single-attempt.
|
|
108
|
+
def create_season_buyer_access_session(season_key, allowed_origin:, include_public:,
|
|
109
|
+
expires_in_seconds: nil, max_quantity: UNSET,
|
|
110
|
+
buyer_ref: UNSET)
|
|
111
|
+
body = compact({ "allowedOrigin" => allowed_origin, "includePublic" => include_public,
|
|
112
|
+
"expiresInSeconds" => expires_in_seconds })
|
|
113
|
+
body.merge!(supplied({ "maxQuantity" => max_quantity, "buyerRef" => buyer_ref }))
|
|
114
|
+
@client.post(path(season_key, "/buyer-access-sessions"), body)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def list_season_buyer_access_sessions(season_key, limit: nil)
|
|
118
|
+
@client.get(path(season_key, "/buyer-access-sessions"), compact({ "limit" => limit }))
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def revoke_season_buyer_access_session(season_key, session_id)
|
|
122
|
+
@client.delete(path(season_key, "/buyer-access-sessions/#{encode(session_id)}"))
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def retrieve_season_hold(season_key, operation_id)
|
|
126
|
+
@client.get(path(season_key, "/holds/#{encode(operation_id)}"))
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def book_season_hold(season_key, operation_id, book_action_id:, booking_ref:)
|
|
130
|
+
@client.post(path(season_key, "/holds/#{encode(operation_id)}/book"),
|
|
131
|
+
{ "bookActionId" => book_action_id, "bookingRef" => booking_ref })
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def retrieve_season_booking(season_key, action_id)
|
|
135
|
+
@client.get(path(season_key, "/bookings/#{encode(action_id)}"))
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def cancel_season_booking(season_key, action_id, cancel_action_id:, booking_ref:,
|
|
139
|
+
plan_activation_id:, right_disposition:)
|
|
140
|
+
@client.post(path(season_key, "/bookings/#{encode(action_id)}/cancel"),
|
|
141
|
+
{ "cancelActionId" => cancel_action_id, "bookingRef" => booking_ref,
|
|
142
|
+
"planActivationId" => plan_activation_id,
|
|
143
|
+
"rightDisposition" => right_disposition })
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def validate_season_buyer_rehearsal(season_key)
|
|
147
|
+
@client.post(path(season_key, "/buyer-rehearsals/validate"))
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def create_season_holder_import(season_key, successor_plan_activation_id:, rows:,
|
|
151
|
+
dry_run: UNSET, idempotency_key: nil)
|
|
152
|
+
body = { "successorPlanActivationId" => successor_plan_activation_id, "rows" => rows }
|
|
153
|
+
body.merge!(supplied({ "dryRun" => dry_run }))
|
|
154
|
+
@client.post(path(season_key, "/imports"), body, idempotency_key: idempotency_key,
|
|
155
|
+
retry_policy: :header_replay)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def retrieve_season_holder_import(season_key, import_id)
|
|
159
|
+
@client.get(path(season_key, "/imports/#{encode(import_id)}"))
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def create_season_renewal_offers(season_key, deadline_at:,
|
|
163
|
+
successor_plan_activation_id: nil, contract_ids: nil,
|
|
164
|
+
idempotency_key: nil)
|
|
165
|
+
body = compact({ "successorPlanActivationId" => successor_plan_activation_id,
|
|
166
|
+
"deadlineAt" => deadline_at, "contractIds" => contract_ids })
|
|
167
|
+
@client.post(path(season_key, "/renewal-offers"), body,
|
|
168
|
+
idempotency_key: idempotency_key, retry_policy: :header_replay)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def list_season_renewal_offers(season_key)
|
|
172
|
+
@client.get(path(season_key, "/renewal-offers"))
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def retrieve_season_renewal_offer(season_key, offer_id)
|
|
176
|
+
@client.get(path(season_key, "/renewal-offers/#{encode(offer_id)}"))
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def extend_season_renewal_offer(season_key, offer_id, deadline_at:)
|
|
180
|
+
@client.post(path(season_key, "/renewal-offers/#{encode(offer_id)}/extend"),
|
|
181
|
+
{ "deadlineAt" => deadline_at })
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def inspect_season_renewal_offer(season_key, offer_id)
|
|
185
|
+
@client.get(path(season_key, "/renewal-offers/#{encode(offer_id)}/inspect"))
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def commit_season_renewal_offer(season_key, offer_id, commit_action_id:, order_ref:,
|
|
189
|
+
booking_ref:, plan_activation_id:)
|
|
190
|
+
@client.post(path(season_key, "/renewal-offers/#{encode(offer_id)}/commit"),
|
|
191
|
+
{ "commitActionId" => commit_action_id, "orderRef" => order_ref,
|
|
192
|
+
"bookingRef" => booking_ref, "planActivationId" => plan_activation_id })
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def decline_season_renewal_offer(season_key, offer_id)
|
|
196
|
+
@client.post(path(season_key, "/renewal-offers/#{encode(offer_id)}/decline"), {})
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def release_season_renewal_offer(season_key, offer_id)
|
|
200
|
+
@client.post(path(season_key, "/renewal-offers/#{encode(offer_id)}/release"), {})
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def list_season_occurrences(season_key)
|
|
204
|
+
@client.get(path(season_key, "/occurrences"))
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def create_season_amendment(season_key, event_key:, kind:, starts_at: nil, name: nil,
|
|
208
|
+
idempotency_key: nil)
|
|
209
|
+
@client.post(path(season_key, "/amendments"),
|
|
210
|
+
compact({ "eventKey" => event_key, "kind" => kind,
|
|
211
|
+
"startsAt" => starts_at, "name" => name }),
|
|
212
|
+
idempotency_key: idempotency_key, retry_policy: :header_replay)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def list_season_amendments(season_key)
|
|
216
|
+
@client.get(path(season_key, "/amendments"))
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def retrieve_season_amendment(season_key, amendment_id)
|
|
220
|
+
@client.get(path(season_key, "/amendments/#{encode(amendment_id)}"))
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def retrieve_season_report(season_key)
|
|
224
|
+
@client.get(path(season_key, "/reports"))
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def list_season_operations(season_key)
|
|
228
|
+
@client.get(path(season_key, "/operations"))
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def retrieve_season_support_lookup(season_key, booking_ref: nil, holder_ref: nil)
|
|
232
|
+
@client.get(path(season_key, "/support-lookups"),
|
|
233
|
+
compact({ "bookingRef" => booking_ref, "holderRef" => holder_ref }))
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def list_season_outbox(season_key)
|
|
237
|
+
@client.get(path(season_key, "/outbox"))
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def replay_season_outbox(season_key, occurrence_id)
|
|
241
|
+
@client.post(path(season_key, "/outbox/#{encode(occurrence_id)}/replay"), {})
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def list_season_audit(season_key)
|
|
245
|
+
@client.get(path(season_key, "/audit"))
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def export_season_support_snapshot(season_key)
|
|
249
|
+
@client.get(path(season_key, "/export"))
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
private
|
|
253
|
+
|
|
254
|
+
def path(season_key, suffix = "")
|
|
255
|
+
"/v1/seasons/#{encode(season_key)}#{suffix}"
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def selection(event_keys, source_performance_group_keys)
|
|
259
|
+
compact({ "eventKeys" => event_keys,
|
|
260
|
+
"sourcePerformanceGroupKeys" => source_performance_group_keys })
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def lifecycle(season_key, action, expected_revision)
|
|
264
|
+
@client.post(path(season_key, "/#{action}"), { "expectedRevision" => expected_revision })
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def sales(season_key, action, expected_revision)
|
|
268
|
+
@client.post(path(season_key, "/sales/#{action}"),
|
|
269
|
+
{ "expectedRevision" => expected_revision })
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
end
|
data/lib/seatlayer/version.rb
CHANGED
data/lib/seatlayer.rb
CHANGED
|
@@ -7,6 +7,7 @@ require_relative "seatlayer/resources"
|
|
|
7
7
|
require_relative "seatlayer/inventory"
|
|
8
8
|
require_relative "seatlayer/channels"
|
|
9
9
|
require_relative "seatlayer/performance_groups"
|
|
10
|
+
require_relative "seatlayer/seasons"
|
|
10
11
|
require_relative "seatlayer/webhook"
|
|
11
12
|
|
|
12
13
|
# Official Ruby server SDK for the SeatLayer reserved-seating API.
|
|
@@ -21,7 +22,7 @@ module SeatLayer
|
|
|
21
22
|
# The SeatLayer client.
|
|
22
23
|
class Client
|
|
23
24
|
attr_reader :charts, :events, :inventory, :channels, :performance_groups, :sessions,
|
|
24
|
-
:webhooks, :workspaces, :templates
|
|
25
|
+
:seasons, :webhooks, :workspaces, :templates
|
|
25
26
|
|
|
26
27
|
def initialize(secret_key, base_url: HTTPClient::DEFAULT_BASE_URL,
|
|
27
28
|
max_retries: HTTPClient::DEFAULT_MAX_RETRIES,
|
|
@@ -34,6 +35,7 @@ module SeatLayer
|
|
|
34
35
|
@inventory = Inventory.new(@http)
|
|
35
36
|
@channels = Channels.new(@http)
|
|
36
37
|
@performance_groups = PerformanceGroups.new(@http)
|
|
38
|
+
@seasons = Seasons.new(@http)
|
|
37
39
|
@sessions = Sessions.new(@http)
|
|
38
40
|
@templates = Templates.new(@http)
|
|
39
41
|
@webhooks = Webhooks.new(@http)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: seatlayer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- SeatLayer
|
|
@@ -9,8 +9,9 @@ bindir: bin
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies: []
|
|
12
|
-
description: 'Server-side Ruby client for SeatLayer
|
|
13
|
-
|
|
12
|
+
description: 'Server-side Ruby client for SeatLayer reserved seating: seating charts,
|
|
13
|
+
events, seat maps, holds, seat booking, embed sessions and webhook verification,
|
|
14
|
+
with idempotency and retries built in.'
|
|
14
15
|
email:
|
|
15
16
|
- hello@seatlayer.io
|
|
16
17
|
executables: []
|
|
@@ -27,6 +28,7 @@ files:
|
|
|
27
28
|
- lib/seatlayer/inventory.rb
|
|
28
29
|
- lib/seatlayer/performance_groups.rb
|
|
29
30
|
- lib/seatlayer/resources.rb
|
|
31
|
+
- lib/seatlayer/seasons.rb
|
|
30
32
|
- lib/seatlayer/version.rb
|
|
31
33
|
- lib/seatlayer/webhook.rb
|
|
32
34
|
homepage: https://seatlayer.io
|