carddb 0.2.1 → 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/.rspec_status +109 -70
- data/CHANGELOG.md +6 -0
- data/README.md +216 -2
- data/lib/carddb/client.rb +14 -1
- data/lib/carddb/collection.rb +517 -3
- data/lib/carddb/configuration.rb +27 -1
- data/lib/carddb/connection.rb +5 -2
- data/lib/carddb/query_builder.rb +1096 -127
- data/lib/carddb/resources/decks.rb +432 -6
- data/lib/carddb/resources/records.rb +39 -15
- data/lib/carddb/version.rb +1 -1
- metadata +1 -1
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
module CardDB
|
|
4
4
|
module Resources
|
|
5
5
|
# Decks resource for hosted decks and external deck hydration.
|
|
6
|
+
# rubocop:disable Metrics/ClassLength
|
|
6
7
|
class Decks < Base
|
|
7
8
|
# List decks owned by the current account or API application.
|
|
8
|
-
def list_mine(first: nil, after: nil, cache: nil)
|
|
9
|
-
query = QueryBuilder.list_my_decks(first: first, after: after)
|
|
10
|
-
variables = build_variables(first: first, after: after)
|
|
9
|
+
def list_mine(first: nil, after: nil, include_archived: nil, cache: nil)
|
|
10
|
+
query = QueryBuilder.list_my_decks(first: first, after: after, include_archived: include_archived)
|
|
11
|
+
variables = build_variables(first: first, after: after, includeArchived: include_archived)
|
|
11
12
|
key = cache_key('decks', 'list_mine', **variables)
|
|
12
13
|
|
|
13
14
|
data = with_cache(key, resource: :decks, cache: cache) do
|
|
@@ -17,7 +18,65 @@ module CardDB
|
|
|
17
18
|
Collection.new(
|
|
18
19
|
data['myDecks'],
|
|
19
20
|
item_class: Deck,
|
|
20
|
-
next_page_loader:
|
|
21
|
+
next_page_loader: lambda { |cursor|
|
|
22
|
+
list_mine(first: first, after: cursor, include_archived: include_archived, cache: cache)
|
|
23
|
+
},
|
|
24
|
+
client: client
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# List decks owned by the current account or OAuth grant.
|
|
29
|
+
def list_viewer(filter: nil, first: nil, after: nil, cache: nil)
|
|
30
|
+
query = QueryBuilder.viewer_decks(filter: filter, first: first, after: after)
|
|
31
|
+
variables = build_variables(filter: filter, first: first, after: after)
|
|
32
|
+
key = cache_key('decks', 'list_viewer', **variables)
|
|
33
|
+
|
|
34
|
+
data = with_cache(key, resource: :decks, cache: cache) do
|
|
35
|
+
connection.execute(query, variables)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
Collection.new(
|
|
39
|
+
data['viewerDecks'],
|
|
40
|
+
item_class: Deck,
|
|
41
|
+
next_page_loader: ->(cursor) { list_viewer(filter: filter, first: first, after: cursor, cache: cache) },
|
|
42
|
+
client: client
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# List app-owned decks for the current secret-key API application.
|
|
47
|
+
def list_app(filter: nil, first: nil, after: nil, cache: nil)
|
|
48
|
+
config.require_secret_credential!('decks.list_app')
|
|
49
|
+
|
|
50
|
+
query = QueryBuilder.app_decks(filter: filter, first: first, after: after)
|
|
51
|
+
variables = build_variables(filter: filter, first: first, after: after)
|
|
52
|
+
key = cache_key('decks', 'list_app', **variables)
|
|
53
|
+
|
|
54
|
+
data = with_cache(key, resource: :decks, cache: cache) do
|
|
55
|
+
connection.execute(query, variables)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
Collection.new(
|
|
59
|
+
data['appDecks'],
|
|
60
|
+
item_class: Deck,
|
|
61
|
+
next_page_loader: ->(cursor) { list_app(filter: filter, first: first, after: cursor, cache: cache) },
|
|
62
|
+
client: client
|
|
63
|
+
)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# List published live decks eligible for public discovery.
|
|
67
|
+
def list_public(filter: nil, first: nil, after: nil, cache: nil)
|
|
68
|
+
query = QueryBuilder.public_decks(filter: filter, first: first, after: after)
|
|
69
|
+
variables = build_variables(filter: filter, first: first, after: after)
|
|
70
|
+
key = cache_key('decks', 'list_public', **variables)
|
|
71
|
+
|
|
72
|
+
data = with_cache(key, resource: :decks, cache: cache) do
|
|
73
|
+
connection.execute(query, variables)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
Collection.new(
|
|
77
|
+
data['publicDecks'],
|
|
78
|
+
item_class: Deck,
|
|
79
|
+
next_page_loader: ->(cursor) { list_public(filter: filter, first: first, after: cursor, cache: cache) },
|
|
21
80
|
client: client
|
|
22
81
|
)
|
|
23
82
|
end
|
|
@@ -31,6 +90,15 @@ module CardDB
|
|
|
31
90
|
end
|
|
32
91
|
end
|
|
33
92
|
|
|
93
|
+
# Fetch by UUID using the ownership-aware deck API.
|
|
94
|
+
def get(id, cache: nil)
|
|
95
|
+
key = cache_key('decks', 'get', id: id)
|
|
96
|
+
with_cache(key, resource: :decks, cache: cache) do
|
|
97
|
+
data = connection.execute(QueryBuilder.deck, { id: id })
|
|
98
|
+
data['deck'] ? Deck.new(data['deck'], client: client) : nil
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
34
102
|
# Fetch one deck owned by the current account or API application.
|
|
35
103
|
def fetch_mine(id, cache: nil)
|
|
36
104
|
key = cache_key('decks', 'fetch_mine', id: id)
|
|
@@ -56,6 +124,22 @@ module CardDB
|
|
|
56
124
|
end
|
|
57
125
|
end
|
|
58
126
|
|
|
127
|
+
# Fetch by slug using the ownership-aware deckBySlug API.
|
|
128
|
+
def get_by_slug(slug:, publisher_slug: nil, game_key: nil, cache: nil)
|
|
129
|
+
resolved_publisher = resolve_publisher(publisher_slug)
|
|
130
|
+
resolved_game = resolve_game(game_key)
|
|
131
|
+
validate_access!(resolved_publisher, resolved_game)
|
|
132
|
+
|
|
133
|
+
key = cache_key('decks', 'get_by_slug', publisher_slug: resolved_publisher, game_key: resolved_game, slug: slug)
|
|
134
|
+
with_cache(key, resource: :decks, cache: cache) do
|
|
135
|
+
data = connection.execute(
|
|
136
|
+
QueryBuilder.deck_by_slug,
|
|
137
|
+
{ publisherSlug: resolved_publisher, gameKey: resolved_game, slug: slug }
|
|
138
|
+
)
|
|
139
|
+
data['deckBySlug'] ? Deck.new(data['deckBySlug'], client: client) : nil
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
59
143
|
# Fetch a hosted deck by external reference for the current API application.
|
|
60
144
|
def fetch_by_external_ref(external_ref:, cache: nil)
|
|
61
145
|
key = cache_key('decks', 'fetch_by_external_ref', external_ref: external_ref)
|
|
@@ -65,6 +149,15 @@ module CardDB
|
|
|
65
149
|
end
|
|
66
150
|
end
|
|
67
151
|
|
|
152
|
+
# Fetch by external reference using the ownership-aware deckByExternalRef API.
|
|
153
|
+
def get_by_external_ref(external_ref:, cache: nil)
|
|
154
|
+
key = cache_key('decks', 'get_by_external_ref', external_ref: external_ref)
|
|
155
|
+
with_cache(key, resource: :decks, cache: cache) do
|
|
156
|
+
data = connection.execute(QueryBuilder.deck_by_external_ref, { externalRef: external_ref })
|
|
157
|
+
data['deckByExternalRef'] ? Deck.new(data['deckByExternalRef'], client: client) : nil
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
68
161
|
# Fetch one immutable published deck version.
|
|
69
162
|
def fetch_version(id, cache: nil)
|
|
70
163
|
key = cache_key('decks', 'fetch_version', id: id)
|
|
@@ -101,6 +194,96 @@ module CardDB
|
|
|
101
194
|
end
|
|
102
195
|
end
|
|
103
196
|
|
|
197
|
+
# Fetch published embed data using a revocable embed token.
|
|
198
|
+
def embed(token:, cache: nil)
|
|
199
|
+
key = cache_key('decks', 'embed', token: token)
|
|
200
|
+
with_cache(key, resource: :decks, cache: cache) do
|
|
201
|
+
data = connection.execute(QueryBuilder.deck_embed, { token: token })
|
|
202
|
+
data['deckEmbed'] ? Deck.new(data['deckEmbed'], client: client) : nil
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Fetch token-authorized published data using an exchanged access token.
|
|
207
|
+
def access(token:, cache: nil)
|
|
208
|
+
key = cache_key('decks', 'access', token: token)
|
|
209
|
+
with_cache(key, resource: :decks, cache: cache) do
|
|
210
|
+
data = connection.execute(QueryBuilder.deck_access, { token: token })
|
|
211
|
+
data['deckAccess'] ? Deck.new(data['deckAccess'], client: client) : nil
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def draft_diff(id:, cache: nil)
|
|
216
|
+
key = cache_key('decks', 'draft_diff', id: id)
|
|
217
|
+
with_cache(key, resource: :decks, cache: cache) do
|
|
218
|
+
data = connection.execute(QueryBuilder.deck_draft_diff, { id: id })
|
|
219
|
+
DeckDiff.new(data['deckDraftDiff'], client: client)
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def version_diff(from_version_id:, to_version_id:, cache: nil)
|
|
224
|
+
variables = { fromVersionId: from_version_id, toVersionId: to_version_id }
|
|
225
|
+
key = cache_key('decks', 'version_diff', **variables)
|
|
226
|
+
with_cache(key, resource: :decks, cache: cache) do
|
|
227
|
+
data = connection.execute(QueryBuilder.deck_version_diff, variables)
|
|
228
|
+
DeckDiff.new(data['deckVersionDiff'], client: client)
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def validate(id:, input: nil, cache: nil)
|
|
233
|
+
variables = build_variables(id: id, input: input)
|
|
234
|
+
key = cache_key('decks', 'validate', **variables)
|
|
235
|
+
with_cache(key, resource: :decks, cache: cache) do
|
|
236
|
+
data = connection.execute(QueryBuilder.deck_validate, variables)
|
|
237
|
+
DeckValidation.new(data['deckValidate'], client: client)
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def hydrate_deck_entries(input:, cache: nil)
|
|
242
|
+
key = cache_key('decks', 'hydrate_deck_entries', input: input)
|
|
243
|
+
with_cache(key, resource: :decks, cache: cache) do
|
|
244
|
+
data = connection.execute(QueryBuilder.deck_hydrate_entries, { input: input })
|
|
245
|
+
DeckHydrateEntriesPayload.new(data['deckHydrateEntries'], client: client)
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def export_deck(id:, format: 'SIMPLE_TEXT', cache: nil)
|
|
250
|
+
variables = { id: id, format: format }
|
|
251
|
+
key = cache_key('decks', 'export_deck', **variables)
|
|
252
|
+
with_cache(key, resource: :decks, cache: cache) do
|
|
253
|
+
data = connection.execute(QueryBuilder.deck_export, variables)
|
|
254
|
+
DeckExportPayload.new(data['deckExport'], client: client)
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def section_definitions(
|
|
259
|
+
publisher_slug: nil,
|
|
260
|
+
game_key: nil,
|
|
261
|
+
game_id: nil,
|
|
262
|
+
ruleset_key: nil,
|
|
263
|
+
ruleset_version_id: nil,
|
|
264
|
+
cache: nil
|
|
265
|
+
)
|
|
266
|
+
query = QueryBuilder.deck_section_definitions(
|
|
267
|
+
publisher_slug: publisher_slug,
|
|
268
|
+
game_key: game_key,
|
|
269
|
+
game_id: game_id,
|
|
270
|
+
ruleset_key: ruleset_key,
|
|
271
|
+
ruleset_version_id: ruleset_version_id
|
|
272
|
+
)
|
|
273
|
+
variables = build_variables(
|
|
274
|
+
publisherSlug: publisher_slug,
|
|
275
|
+
gameKey: game_key,
|
|
276
|
+
gameId: game_id,
|
|
277
|
+
rulesetKey: ruleset_key,
|
|
278
|
+
rulesetVersionId: ruleset_version_id
|
|
279
|
+
)
|
|
280
|
+
key = cache_key('decks', 'section_definitions', **variables)
|
|
281
|
+
with_cache(key, resource: :decks, cache: cache) do
|
|
282
|
+
data = connection.execute(query, variables)
|
|
283
|
+
(data['deckSectionDefinitions'] || []).map { |definition| DeckSectionDefinition.new(definition, client: client) }
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
104
287
|
# List collaborators for a deck.
|
|
105
288
|
def collaborators(deck_id:, cache: nil)
|
|
106
289
|
key = cache_key('decks', 'collaborators', deck_id: deck_id)
|
|
@@ -119,6 +302,44 @@ module CardDB
|
|
|
119
302
|
end
|
|
120
303
|
end
|
|
121
304
|
|
|
305
|
+
def embed_tokens(deck_id:, cache: nil)
|
|
306
|
+
key = cache_key('decks', 'embed_tokens', deck_id: deck_id)
|
|
307
|
+
with_cache(key, resource: :decks, cache: cache) do
|
|
308
|
+
data = connection.execute(QueryBuilder.deck_embed_tokens, { deckId: deck_id })
|
|
309
|
+
(data['deckEmbedTokens'] || []).map { |token| DeckEmbedToken.new(token, client: client) }
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
def access_token_issuers(deck_id:, cache: nil)
|
|
314
|
+
key = cache_key('decks', 'access_token_issuers', deck_id: deck_id)
|
|
315
|
+
with_cache(key, resource: :decks, cache: cache) do
|
|
316
|
+
data = connection.execute(QueryBuilder.deck_access_token_issuers, { deckId: deck_id })
|
|
317
|
+
(data['deckAccessTokenIssuers'] || []).map { |issuer| DeckAccessTokenIssuer.new(issuer, client: client) }
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
def api_application_accesses(deck_id:, include_revoked: nil, cache: nil)
|
|
322
|
+
variables = build_variables(deckId: deck_id, includeRevoked: include_revoked)
|
|
323
|
+
key = cache_key('decks', 'api_application_accesses', **variables)
|
|
324
|
+
with_cache(key, resource: :decks, cache: cache) do
|
|
325
|
+
data = connection.execute(QueryBuilder.deck_api_application_accesses, variables)
|
|
326
|
+
(data['deckApiApplicationAccesses'] || []).map do |access|
|
|
327
|
+
DeckAPIApplicationAccess.new(access, client: client)
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def my_api_application_accesses(application_id: nil, cache: nil)
|
|
333
|
+
variables = build_variables(applicationId: application_id)
|
|
334
|
+
key = cache_key('decks', 'my_api_application_accesses', **variables)
|
|
335
|
+
with_cache(key, resource: :decks, cache: cache) do
|
|
336
|
+
data = connection.execute(QueryBuilder.my_deck_api_application_accesses, variables)
|
|
337
|
+
(data['myDeckApiApplicationAccesses'] || []).map do |access|
|
|
338
|
+
DeckAPIApplicationAccess.new(access, client: client)
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
|
|
122
343
|
# Create a hosted deck.
|
|
123
344
|
def create(input:)
|
|
124
345
|
data = connection.execute(QueryBuilder.create_deck, { input: input })
|
|
@@ -131,10 +352,154 @@ module CardDB
|
|
|
131
352
|
Deck.new(data['deckUpdate'], client: client)
|
|
132
353
|
end
|
|
133
354
|
|
|
355
|
+
# Update deck-level metadata without mutating entries.
|
|
356
|
+
def update_metadata(id:, input:)
|
|
357
|
+
update(id: id, input: input)
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
def upsert_by_external_ref(input:)
|
|
361
|
+
config.require_secret_credential!('decks.upsert_by_external_ref')
|
|
362
|
+
|
|
363
|
+
data = connection.execute(QueryBuilder.upsert_deck_by_external_ref, { input: input })
|
|
364
|
+
DeckUpsertByExternalRefPayload.new(data['deckUpsertByExternalRef'], client: client)
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
def claim(id:, input:)
|
|
368
|
+
data = connection.execute(QueryBuilder.claim_deck, { id: id, input: input })
|
|
369
|
+
DeckOwnershipTransferPayload.new(data['deckClaim'], client: client)
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
def transfer_ownership(id:, input:)
|
|
373
|
+
data = connection.execute(QueryBuilder.transfer_deck_ownership, { id: id, input: input })
|
|
374
|
+
DeckOwnershipTransferPayload.new(data['deckTransferOwnership'], client: client)
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
def copy(id:, input:)
|
|
378
|
+
data = connection.execute(QueryBuilder.copy_deck, { id: id, input: input })
|
|
379
|
+
DeckCopyPayload.new(data['deckCopy'], client: client)
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
def add_entry(input:)
|
|
383
|
+
data = connection.execute(QueryBuilder.add_deck_entry, { input: input })
|
|
384
|
+
DeckEntryMutationPayload.new(data['deckEntryAdd'], client: client)
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
def update_entry(id:, input:)
|
|
388
|
+
data = connection.execute(QueryBuilder.update_deck_entry, { id: id, input: input })
|
|
389
|
+
DeckEntryMutationPayload.new(data['deckEntryUpdate'], client: client)
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
def remove_entry(id:, expected_draft_revision:)
|
|
393
|
+
data = connection.execute(
|
|
394
|
+
QueryBuilder.remove_deck_entry,
|
|
395
|
+
{ id: id, expectedDraftRevision: expected_draft_revision }
|
|
396
|
+
)
|
|
397
|
+
DeckEntryMutationPayload.new(data['deckEntryRemove'], client: client)
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
def reorder_entries(deck_id:, input:)
|
|
401
|
+
data = connection.execute(QueryBuilder.reorder_deck_entries, { deckId: deck_id, input: input })
|
|
402
|
+
DeckEntryReorderPayload.new(data['deckEntryReorder'], client: client)
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
def replace_entries(deck_id:, input:)
|
|
406
|
+
data = connection.execute(QueryBuilder.replace_deck_entries, { deckId: deck_id, input: input })
|
|
407
|
+
DeckEntriesReplacePayload.new(data['deckEntriesReplace'], client: client)
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
# Import a decklist into an existing deck or dry-run resolution.
|
|
411
|
+
def import_deck(input:)
|
|
412
|
+
data = connection.execute(QueryBuilder.import_deck, { input: input })
|
|
413
|
+
DeckImportPayload.new(data['deckImport'], client: client)
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
def import_formats(game_id:, include_archived: nil, first: nil, after: nil, cache: nil)
|
|
417
|
+
query = QueryBuilder.deck_import_formats(
|
|
418
|
+
game_id: game_id,
|
|
419
|
+
include_archived: include_archived,
|
|
420
|
+
first: first,
|
|
421
|
+
after: after
|
|
422
|
+
)
|
|
423
|
+
variables = build_variables(gameId: game_id, includeArchived: include_archived, first: first, after: after)
|
|
424
|
+
key = cache_key('decks', 'import_formats', **variables)
|
|
425
|
+
|
|
426
|
+
data = with_cache(key, resource: :decks, cache: cache) do
|
|
427
|
+
connection.execute(query, variables)
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
Collection.new(
|
|
431
|
+
data['deckImportFormats'],
|
|
432
|
+
item_class: DeckImportFormatDefinition,
|
|
433
|
+
next_page_loader: lambda { |cursor|
|
|
434
|
+
import_formats(
|
|
435
|
+
game_id: game_id,
|
|
436
|
+
include_archived: include_archived,
|
|
437
|
+
first: first,
|
|
438
|
+
after: cursor,
|
|
439
|
+
cache: cache
|
|
440
|
+
)
|
|
441
|
+
},
|
|
442
|
+
client: client
|
|
443
|
+
)
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
def fetch_import_format(id, cache: nil)
|
|
447
|
+
key = cache_key('decks', 'fetch_import_format', id: id)
|
|
448
|
+
with_cache(key, resource: :decks, cache: cache) do
|
|
449
|
+
data = connection.execute(QueryBuilder.deck_import_format, { id: id })
|
|
450
|
+
data['deckImportFormat'] ? DeckImportFormatDefinition.new(data['deckImportFormat'], client: client) : nil
|
|
451
|
+
end
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
def test_import_format(input:)
|
|
455
|
+
data = connection.execute(QueryBuilder.deck_import_format_test, { input: input })
|
|
456
|
+
DeckImportFormatTestPayload.new(data['deckImportFormatTest'], client: client)
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
def create_import_format(input:)
|
|
460
|
+
data = connection.execute(QueryBuilder.create_deck_import_format, { input: input })
|
|
461
|
+
DeckImportFormatDefinition.new(data['deckImportFormatCreate'], client: client)
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
def update_import_format(id:, input:)
|
|
465
|
+
data = connection.execute(QueryBuilder.update_deck_import_format, { id: id, input: input })
|
|
466
|
+
DeckImportFormatDefinition.new(data['deckImportFormatUpdate'], client: client)
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
def archive_import_format(id:)
|
|
470
|
+
data = connection.execute(QueryBuilder.archive_deck_import_format, { id: id })
|
|
471
|
+
DeckImportFormatDefinition.new(data['deckImportFormatArchive'], client: client)
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
def unarchive_import_format(id:)
|
|
475
|
+
data = connection.execute(QueryBuilder.unarchive_deck_import_format, { id: id })
|
|
476
|
+
DeckImportFormatDefinition.new(data['deckImportFormatUnarchive'], client: client)
|
|
477
|
+
end
|
|
478
|
+
|
|
134
479
|
# Publish the current draft as an immutable deck version.
|
|
135
|
-
def publish(id:, input:
|
|
480
|
+
def publish(id:, input:)
|
|
136
481
|
data = connection.execute(QueryBuilder.publish_deck, { id: id, input: input })
|
|
137
|
-
|
|
482
|
+
DeckPublishPayload.new(data['deckPublish'], client: client)
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
def remove_invalid_entries(id:, input:)
|
|
486
|
+
data = connection.execute(QueryBuilder.remove_invalid_deck_entries, { id: id, input: input })
|
|
487
|
+
Deck.new(data['deckRemoveInvalidEntries'], client: client)
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
def archive(id:)
|
|
491
|
+
data = connection.execute(QueryBuilder.archive_deck, { id: id })
|
|
492
|
+
Deck.new(data['deckArchive'], client: client)
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
def restore(id:)
|
|
496
|
+
data = connection.execute(QueryBuilder.restore_deck, { id: id })
|
|
497
|
+
Deck.new(data['deckRestore'], client: client)
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
def unpublish(id:)
|
|
501
|
+
data = connection.execute(QueryBuilder.unpublish_deck, { id: id })
|
|
502
|
+
Deck.new(data['deckUnpublish'], client: client)
|
|
138
503
|
end
|
|
139
504
|
|
|
140
505
|
# Create or update a deck collaborator.
|
|
@@ -171,6 +536,66 @@ module CardDB
|
|
|
171
536
|
end
|
|
172
537
|
# rubocop:enable Naming/PredicateMethod
|
|
173
538
|
|
|
539
|
+
def create_embed_token(input:)
|
|
540
|
+
data = connection.execute(QueryBuilder.create_deck_embed_token, { input: input })
|
|
541
|
+
DeckEmbedTokenCreatePayload.new(data['deckEmbedTokenCreate'], client: client)
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
# rubocop:disable Naming/PredicateMethod
|
|
545
|
+
def revoke_embed_token(id:)
|
|
546
|
+
data = connection.execute(QueryBuilder.revoke_deck_embed_token, { id: id })
|
|
547
|
+
!!data['deckEmbedTokenRevoke']
|
|
548
|
+
end
|
|
549
|
+
# rubocop:enable Naming/PredicateMethod
|
|
550
|
+
|
|
551
|
+
def create_access_token_issuer(input:)
|
|
552
|
+
data = connection.execute(QueryBuilder.create_deck_access_token_issuer, { input: input })
|
|
553
|
+
DeckAccessTokenIssuer.new(data['deckAccessTokenIssuerCreate'], client: client)
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
# rubocop:disable Naming/PredicateMethod
|
|
557
|
+
def revoke_access_token_issuer(id:)
|
|
558
|
+
data = connection.execute(QueryBuilder.revoke_deck_access_token_issuer, { id: id })
|
|
559
|
+
!!data['deckAccessTokenIssuerRevoke']
|
|
560
|
+
end
|
|
561
|
+
# rubocop:enable Naming/PredicateMethod
|
|
562
|
+
|
|
563
|
+
def revoke_access_token_issuer_signing_key(id:)
|
|
564
|
+
data = connection.execute(QueryBuilder.revoke_deck_access_token_issuer_signing_key, { id: id })
|
|
565
|
+
DeckAccessTokenIssuer.new(data['deckAccessTokenIssuerSigningKeyRevoke'], client: client)
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
def grant_api_application_access(input:)
|
|
569
|
+
data = connection.execute(QueryBuilder.grant_deck_api_application_access, { input: input })
|
|
570
|
+
DeckAPIApplicationAccess.new(data['deckApiApplicationAccessGrant'], client: client)
|
|
571
|
+
end
|
|
572
|
+
|
|
573
|
+
# rubocop:disable Naming/PredicateMethod
|
|
574
|
+
def revoke_api_application_access(deck_id:, api_application_id:)
|
|
575
|
+
data = connection.execute(
|
|
576
|
+
QueryBuilder.revoke_deck_api_application_access,
|
|
577
|
+
{ deckId: deck_id, apiApplicationId: api_application_id }
|
|
578
|
+
)
|
|
579
|
+
!!data['deckApiApplicationAccessRevoke']
|
|
580
|
+
end
|
|
581
|
+
# rubocop:enable Naming/PredicateMethod
|
|
582
|
+
|
|
583
|
+
def exchange_access_token(input:)
|
|
584
|
+
config.require_secret_credential!('decks.exchange_access_token')
|
|
585
|
+
|
|
586
|
+
data = connection.execute(QueryBuilder.exchange_deck_access_token, { input: input })
|
|
587
|
+
DeckAccessTokenExchangePayload.new(data['deckAccessTokenExchange'], client: client)
|
|
588
|
+
end
|
|
589
|
+
|
|
590
|
+
# rubocop:disable Naming/PredicateMethod
|
|
591
|
+
def revoke_access_token(id:)
|
|
592
|
+
config.require_secret_credential!('decks.revoke_access_token')
|
|
593
|
+
|
|
594
|
+
data = connection.execute(QueryBuilder.revoke_deck_access_token, { id: id })
|
|
595
|
+
!!data['deckAccessTokenRevoke']
|
|
596
|
+
end
|
|
597
|
+
# rubocop:enable Naming/PredicateMethod
|
|
598
|
+
|
|
174
599
|
# Delete a hosted deck.
|
|
175
600
|
# rubocop:disable Naming/PredicateMethod
|
|
176
601
|
def delete(id:)
|
|
@@ -240,5 +665,6 @@ module CardDB
|
|
|
240
665
|
record.record_data&.values&.find { |value| remaining[value.to_s] }
|
|
241
666
|
end
|
|
242
667
|
end
|
|
668
|
+
# rubocop:enable Metrics/ClassLength
|
|
243
669
|
end
|
|
244
670
|
end
|
|
@@ -18,6 +18,7 @@ module CardDB
|
|
|
18
18
|
# @param first [Integer, nil] Maximum number of results
|
|
19
19
|
# @param after [String, nil] Cursor for pagination
|
|
20
20
|
# @param validate_schema [Boolean, nil] Whether to validate against schema
|
|
21
|
+
# @param include_pricing [Boolean] Include live TCGPlayer pricing when configured
|
|
21
22
|
# @yield [FilterBuilder] Optional block for filter DSL
|
|
22
23
|
# @return [Collection<Record>] Collection of records
|
|
23
24
|
#
|
|
@@ -35,7 +36,7 @@ module CardDB
|
|
|
35
36
|
# dataset_key: "cards",
|
|
36
37
|
# filter: { "type" => "creature" }
|
|
37
38
|
# )
|
|
38
|
-
# rubocop:disable Metrics/MethodLength
|
|
39
|
+
# rubocop:disable Metrics/MethodLength, Metrics/ParameterLists
|
|
39
40
|
def search(
|
|
40
41
|
dataset_key:,
|
|
41
42
|
publisher_slug: nil,
|
|
@@ -47,6 +48,7 @@ module CardDB
|
|
|
47
48
|
first: nil,
|
|
48
49
|
after: nil,
|
|
49
50
|
validate_schema: nil,
|
|
51
|
+
include_pricing: false,
|
|
50
52
|
&block
|
|
51
53
|
)
|
|
52
54
|
resolved_publisher = resolve_publisher(publisher_slug)
|
|
@@ -71,7 +73,8 @@ module CardDB
|
|
|
71
73
|
resolve_links: resolve_links,
|
|
72
74
|
first: first,
|
|
73
75
|
after: after,
|
|
74
|
-
validate_schema: validate_schema
|
|
76
|
+
validate_schema: validate_schema,
|
|
77
|
+
include_pricing: include_pricing
|
|
75
78
|
)
|
|
76
79
|
|
|
77
80
|
variables = build_variables(
|
|
@@ -99,7 +102,8 @@ module CardDB
|
|
|
99
102
|
order_by: order_by,
|
|
100
103
|
resolve_links: resolve_links,
|
|
101
104
|
first: first,
|
|
102
|
-
validate_schema: validate_schema
|
|
105
|
+
validate_schema: validate_schema,
|
|
106
|
+
include_pricing: include_pricing
|
|
103
107
|
}
|
|
104
108
|
|
|
105
109
|
next_page_loader = lambda do |cursor|
|
|
@@ -113,17 +117,18 @@ module CardDB
|
|
|
113
117
|
client: client
|
|
114
118
|
)
|
|
115
119
|
end
|
|
116
|
-
# rubocop:enable Metrics/MethodLength
|
|
120
|
+
# rubocop:enable Metrics/MethodLength, Metrics/ParameterLists
|
|
117
121
|
|
|
118
122
|
# Fetch a single record by ID
|
|
119
123
|
#
|
|
120
124
|
# @param id [String] The record UUID
|
|
121
125
|
# @param cache [Boolean, nil] Whether to cache (nil = use config setting)
|
|
126
|
+
# @param include_pricing [Boolean] Include live TCGPlayer pricing when configured
|
|
122
127
|
# @return [Record, nil] The record or nil if not found
|
|
123
|
-
def fetch(id, cache: nil)
|
|
124
|
-
key = cache_key('records', 'fetch', id: id)
|
|
128
|
+
def fetch(id, cache: nil, include_pricing: false)
|
|
129
|
+
key = cache_key('records', 'fetch', id: id, include_pricing: include_pricing)
|
|
125
130
|
with_cache(key, resource: :records, cache: cache) do
|
|
126
|
-
query = QueryBuilder.fetch_record
|
|
131
|
+
query = QueryBuilder.fetch_record(include_pricing: include_pricing)
|
|
127
132
|
data = connection.execute(query, { id: id })
|
|
128
133
|
|
|
129
134
|
return nil unless data['fetchRecord']
|
|
@@ -142,20 +147,29 @@ module CardDB
|
|
|
142
147
|
# @param publisher_slug [String, nil] Publisher slug (uses default if not provided)
|
|
143
148
|
# @param game_key [String, nil] Game key (uses default if not provided)
|
|
144
149
|
# @param cache [Boolean, nil] Whether to cache (nil = use config setting)
|
|
150
|
+
# @param include_pricing [Boolean] Include live TCGPlayer pricing when configured
|
|
145
151
|
# @return [Record, nil] The record or nil if not found
|
|
146
152
|
#
|
|
147
153
|
# @example
|
|
148
154
|
# record = client.records.get(identifier: "xy1-1", dataset_key: "cards")
|
|
149
|
-
def get(
|
|
155
|
+
def get(
|
|
156
|
+
identifier:,
|
|
157
|
+
dataset_key:,
|
|
158
|
+
publisher_slug: nil,
|
|
159
|
+
game_key: nil,
|
|
160
|
+
cache: nil,
|
|
161
|
+
include_pricing: false
|
|
162
|
+
)
|
|
150
163
|
resolved_publisher = resolve_publisher(publisher_slug)
|
|
151
164
|
resolved_game = resolve_game(game_key)
|
|
152
165
|
|
|
153
166
|
validate_access!(resolved_publisher, resolved_game)
|
|
154
167
|
|
|
155
168
|
key = cache_key('records', 'get', publisher_slug: resolved_publisher, game_key: resolved_game,
|
|
156
|
-
dataset_key: dataset_key, identifier: identifier
|
|
169
|
+
dataset_key: dataset_key, identifier: identifier,
|
|
170
|
+
include_pricing: include_pricing)
|
|
157
171
|
with_cache(key, resource: :records, cache: cache) do
|
|
158
|
-
query = QueryBuilder.fetch_record_by_identifier
|
|
172
|
+
query = QueryBuilder.fetch_record_by_identifier(include_pricing: include_pricing)
|
|
159
173
|
variables = {
|
|
160
174
|
publisherSlug: resolved_publisher,
|
|
161
175
|
gameKey: resolved_game,
|
|
@@ -181,6 +195,7 @@ module CardDB
|
|
|
181
195
|
# @param publisher_slug [String, nil] Publisher slug (uses default if not provided)
|
|
182
196
|
# @param game_key [String, nil] Game key (uses default if not provided)
|
|
183
197
|
# @param cache [Boolean, nil] Whether to cache (nil = use config setting)
|
|
198
|
+
# @param include_pricing [Boolean] Include live TCGPlayer pricing when configured
|
|
184
199
|
# @return [Array<Record>] Matching records
|
|
185
200
|
# @raise [ArgumentError] If more than 1000 identifiers are provided
|
|
186
201
|
#
|
|
@@ -189,7 +204,14 @@ module CardDB
|
|
|
189
204
|
# identifiers: ["xy1-1", "xy1-2"],
|
|
190
205
|
# dataset_key: "cards"
|
|
191
206
|
# )
|
|
192
|
-
def get_many(
|
|
207
|
+
def get_many(
|
|
208
|
+
identifiers:,
|
|
209
|
+
dataset_key:,
|
|
210
|
+
publisher_slug: nil,
|
|
211
|
+
game_key: nil,
|
|
212
|
+
cache: nil,
|
|
213
|
+
include_pricing: false
|
|
214
|
+
)
|
|
193
215
|
raise ArgumentError, 'Maximum 1000 identifiers allowed' if identifiers.length > 1000
|
|
194
216
|
return [] if identifiers.empty?
|
|
195
217
|
|
|
@@ -204,10 +226,11 @@ module CardDB
|
|
|
204
226
|
publisher_slug: resolved_publisher,
|
|
205
227
|
game_key: resolved_game,
|
|
206
228
|
dataset_key: dataset_key,
|
|
207
|
-
identifiers: identifiers
|
|
229
|
+
identifiers: identifiers,
|
|
230
|
+
include_pricing: include_pricing
|
|
208
231
|
)
|
|
209
232
|
with_cache(key, resource: :records, cache: cache) do
|
|
210
|
-
query = QueryBuilder.fetch_records_by_identifier
|
|
233
|
+
query = QueryBuilder.fetch_records_by_identifier(include_pricing: include_pricing)
|
|
211
234
|
variables = {
|
|
212
235
|
publisherSlug: resolved_publisher,
|
|
213
236
|
gameKey: resolved_game,
|
|
@@ -224,12 +247,13 @@ module CardDB
|
|
|
224
247
|
# Fetch multiple records by IDs
|
|
225
248
|
#
|
|
226
249
|
# @param ids [Array<String>] Array of record UUIDs (max 1000)
|
|
250
|
+
# @param include_pricing [Boolean] Include live TCGPlayer pricing when configured
|
|
227
251
|
# @return [Array<Record>] Array of records
|
|
228
252
|
# @raise [ArgumentError] If more than 1000 IDs provided
|
|
229
|
-
def fetch_many(ids)
|
|
253
|
+
def fetch_many(ids, include_pricing: false)
|
|
230
254
|
raise ArgumentError, 'Maximum 1000 IDs allowed' if ids.length > 1000
|
|
231
255
|
|
|
232
|
-
query = QueryBuilder.fetch_records
|
|
256
|
+
query = QueryBuilder.fetch_records(include_pricing: include_pricing)
|
|
233
257
|
data = connection.execute(query, { ids: ids })
|
|
234
258
|
|
|
235
259
|
(data['fetchRecords'] || []).map { |r| Record.new(r, client: client) }
|
data/lib/carddb/version.rb
CHANGED