carddb 0.2.0 → 0.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f38ee7d9b3b04bbbc3cfa0c3b4954cb0a65ee7f61f64f87a7bc07c228cdec60d
4
- data.tar.gz: 80759ca9be30df5ef9c3b122caccde5c669d7828d3fbd097d5ad431b2c2885b3
3
+ metadata.gz: '086e1a7e2dff325fbe85352d4d98490bec499ac25601bd69c02d90bda39b47d4'
4
+ data.tar.gz: e383f2399ab4a45e1b740c056de488ea9f2abb450041ec6945fa8d8766355713
5
5
  SHA512:
6
- metadata.gz: 8d1f7de2a44deaa670f63f3de0879edb50b271e154d31d788464f457537a91c99e56a8db7a1717ff047456eee7f1f02d1745305f92e3fa9488945386941af6c6
7
- data.tar.gz: db96a54832d649c3bb683a01ec1c19a287062ba4ec82b08c201c628e15b407a788d587562f124447d943652d299ccd1b4b8287fd8bedd70e2c2675257022c2ef
6
+ metadata.gz: 607ac570111283d6a8eb4c86531ec9d372955e11b0eb12ad50dc057926f69cc2db472bb2e07465328c8ce2956f1e589042168b96fadaea8413b3b50d201bee39
7
+ data.tar.gz: 15ec236e12e5784c615680f4221757f29a4535e67e412a159e0f83f7d55e85964b5131677ca0aaf5f5286cba67df1255b61ed0af6e9937c709cf7e08749334ab
data/.rspec_status CHANGED
@@ -1,96 +1,112 @@
1
1
  example_id | status | run_time |
2
2
  ------------------------------------------------- | ------ | --------------- |
3
- ./spec/carddb/client_spec.rb[1:1:1] | passed | 0.00029 seconds |
3
+ ./spec/carddb/client_spec.rb[1:1:1] | passed | 0.00037 seconds |
4
4
  ./spec/carddb/client_spec.rb[1:1:2] | passed | 0.00004 seconds |
5
5
  ./spec/carddb/client_spec.rb[1:1:3] | passed | 0.00003 seconds |
6
- ./spec/carddb/client_spec.rb[1:2:1] | passed | 0.00016 seconds |
7
- ./spec/carddb/client_spec.rb[1:2:2] | passed | 0.00019 seconds |
6
+ ./spec/carddb/client_spec.rb[1:2:1] | passed | 0.00029 seconds |
7
+ ./spec/carddb/client_spec.rb[1:2:2] | passed | 0.00025 seconds |
8
8
  ./spec/carddb/client_spec.rb[1:3:1] | passed | 0.00003 seconds |
9
9
  ./spec/carddb/client_spec.rb[1:4:1] | passed | 0.00003 seconds |
10
- ./spec/carddb/client_spec.rb[1:5:1] | passed | 0.00004 seconds |
10
+ ./spec/carddb/client_spec.rb[1:5:1] | passed | 0.00003 seconds |
11
11
  ./spec/carddb/client_spec.rb[1:6:1] | passed | 0.00003 seconds |
12
- ./spec/carddb/client_spec.rb[1:7:1] | passed | 0.00032 seconds |
13
- ./spec/carddb/client_spec.rb[1:7:2] | passed | 0.01201 seconds |
12
+ ./spec/carddb/client_spec.rb[1:7:1] | passed | 0.00025 seconds |
13
+ ./spec/carddb/client_spec.rb[1:7:2] | passed | 0.00859 seconds |
14
14
  ./spec/carddb/collection_spec.rb[1:1:1] | passed | 0.00006 seconds |
15
- ./spec/carddb/collection_spec.rb[2:1:1] | passed | 0.00245 seconds |
16
- ./spec/carddb/collection_spec.rb[2:1:2] | passed | 0.00015 seconds |
17
- ./spec/carddb/collection_spec.rb[2:1:3] | passed | 0.0004 seconds |
18
- ./spec/carddb/collection_spec.rb[2:1:4] | passed | 0.00038 seconds |
19
- ./spec/carddb/collection_spec.rb[2:1:5] | passed | 0.00005 seconds |
20
- ./spec/carddb/collection_spec.rb[3:1:1] | passed | 0.00018 seconds |
21
- ./spec/carddb/collection_spec.rb[3:1:2] | passed | 0.0003 seconds |
22
- ./spec/carddb/collection_spec.rb[3:1:3] | passed | 0.00015 seconds |
23
- ./spec/carddb/collection_spec.rb[3:1:4] | passed | 0.00004 seconds |
24
- ./spec/carddb/configuration_spec.rb[1:1:1] | passed | 0.00004 seconds |
25
- ./spec/carddb/configuration_spec.rb[1:1:2] | passed | 0.0001 seconds |
26
- ./spec/carddb/configuration_spec.rb[1:1:3] | passed | 0.00004 seconds |
15
+ ./spec/carddb/collection_spec.rb[2:1:1] | passed | 0.00003 seconds |
16
+ ./spec/carddb/collection_spec.rb[3:1:1] | passed | 0.0055 seconds |
17
+ ./spec/carddb/collection_spec.rb[3:1:2] | passed | 0.00016 seconds |
18
+ ./spec/carddb/collection_spec.rb[3:1:3] | passed | 0.00041 seconds |
19
+ ./spec/carddb/collection_spec.rb[3:1:4] | passed | 0.00035 seconds |
20
+ ./spec/carddb/collection_spec.rb[3:1:5] | passed | 0.00005 seconds |
21
+ ./spec/carddb/collection_spec.rb[4:1:1] | passed | 0.0005 seconds |
22
+ ./spec/carddb/collection_spec.rb[4:1:2] | passed | 0.00014 seconds |
23
+ ./spec/carddb/collection_spec.rb[4:1:3] | passed | 0.00014 seconds |
24
+ ./spec/carddb/collection_spec.rb[4:1:4] | passed | 0.00004 seconds |
25
+ ./spec/carddb/configuration_spec.rb[1:1:1] | passed | 0.00003 seconds |
26
+ ./spec/carddb/configuration_spec.rb[1:1:2] | passed | 0.00003 seconds |
27
+ ./spec/carddb/configuration_spec.rb[1:1:3] | passed | 0.00003 seconds |
27
28
  ./spec/carddb/configuration_spec.rb[1:1:4] | passed | 0.00003 seconds |
28
29
  ./spec/carddb/configuration_spec.rb[1:1:5] | passed | 0.00003 seconds |
29
30
  ./spec/carddb/configuration_spec.rb[1:1:6] | passed | 0.00003 seconds |
30
31
  ./spec/carddb/configuration_spec.rb[1:2:1:1] | passed | 0.00004 seconds |
31
- ./spec/carddb/configuration_spec.rb[1:2:2:1] | passed | 0.00003 seconds |
32
- ./spec/carddb/configuration_spec.rb[1:2:2:2] | passed | 0.0001 seconds |
33
- ./spec/carddb/configuration_spec.rb[1:3:1:1] | passed | 0.00003 seconds |
32
+ ./spec/carddb/configuration_spec.rb[1:2:2:1] | passed | 0.00004 seconds |
33
+ ./spec/carddb/configuration_spec.rb[1:2:2:2] | passed | 0.00005 seconds |
34
+ ./spec/carddb/configuration_spec.rb[1:3:1:1] | passed | 0.00004 seconds |
34
35
  ./spec/carddb/configuration_spec.rb[1:3:2:1] | passed | 0.00003 seconds |
35
- ./spec/carddb/configuration_spec.rb[1:3:2:2] | passed | 0.00003 seconds |
36
- ./spec/carddb/configuration_spec.rb[1:3:2:3] | passed | 0.00002 seconds |
37
- ./spec/carddb/configuration_spec.rb[1:4:1] | passed | 0.00004 seconds |
36
+ ./spec/carddb/configuration_spec.rb[1:3:2:2] | passed | 0.00004 seconds |
37
+ ./spec/carddb/configuration_spec.rb[1:3:2:3] | passed | 0.00004 seconds |
38
+ ./spec/carddb/configuration_spec.rb[1:4:1] | passed | 0.00003 seconds |
38
39
  ./spec/carddb/configuration_spec.rb[1:4:2] | passed | 0.00003 seconds |
39
- ./spec/carddb/configuration_spec.rb[1:5:1] | passed | 0.00003 seconds |
40
+ ./spec/carddb/configuration_spec.rb[1:5:1] | passed | 0.00004 seconds |
40
41
  ./spec/carddb/filter_builder_spec.rb[1:1:1] | passed | 0.00004 seconds |
41
- ./spec/carddb/filter_builder_spec.rb[1:1:2] | passed | 0.00003 seconds |
42
+ ./spec/carddb/filter_builder_spec.rb[1:1:2] | passed | 0.00004 seconds |
42
43
  ./spec/carddb/filter_builder_spec.rb[1:1:3] | passed | 0.00003 seconds |
43
- ./spec/carddb/filter_builder_spec.rb[1:1:4] | passed | 0.00002 seconds |
44
- ./spec/carddb/filter_builder_spec.rb[1:1:5] | passed | 0.00002 seconds |
44
+ ./spec/carddb/filter_builder_spec.rb[1:1:4] | passed | 0.00004 seconds |
45
+ ./spec/carddb/filter_builder_spec.rb[1:1:5] | passed | 0.00003 seconds |
45
46
  ./spec/carddb/filter_builder_spec.rb[1:1:6] | passed | 0.00003 seconds |
46
47
  ./spec/carddb/filter_builder_spec.rb[1:1:7] | passed | 0.00003 seconds |
47
- ./spec/carddb/filter_builder_spec.rb[1:1:8] | passed | 0.00002 seconds |
48
+ ./spec/carddb/filter_builder_spec.rb[1:1:8] | passed | 0.00003 seconds |
48
49
  ./spec/carddb/filter_builder_spec.rb[1:2:1] | passed | 0.00003 seconds |
49
- ./spec/carddb/filter_builder_spec.rb[1:2:2] | passed | 0.00002 seconds |
50
- ./spec/carddb/filter_builder_spec.rb[1:2:3] | passed | 0.00002 seconds |
51
- ./spec/carddb/filter_builder_spec.rb[1:2:4] | passed | 0.00002 seconds |
52
- ./spec/carddb/filter_builder_spec.rb[1:2:5] | passed | 0.00002 seconds |
53
- ./spec/carddb/filter_builder_spec.rb[1:2:6] | passed | 0.00002 seconds |
54
- ./spec/carddb/filter_builder_spec.rb[1:2:7] | passed | 0.00002 seconds |
55
- ./spec/carddb/filter_builder_spec.rb[1:2:8] | passed | 0.00002 seconds |
56
- ./spec/carddb/filter_builder_spec.rb[1:2:9] | passed | 0.00002 seconds |
57
- ./spec/carddb/filter_builder_spec.rb[1:2:10] | passed | 0.00002 seconds |
50
+ ./spec/carddb/filter_builder_spec.rb[1:2:2] | passed | 0.00003 seconds |
51
+ ./spec/carddb/filter_builder_spec.rb[1:2:3] | passed | 0.00003 seconds |
52
+ ./spec/carddb/filter_builder_spec.rb[1:2:4] | passed | 0.00003 seconds |
53
+ ./spec/carddb/filter_builder_spec.rb[1:2:5] | passed | 0.00004 seconds |
54
+ ./spec/carddb/filter_builder_spec.rb[1:2:6] | passed | 0.00006 seconds |
55
+ ./spec/carddb/filter_builder_spec.rb[1:2:7] | passed | 0.00003 seconds |
56
+ ./spec/carddb/filter_builder_spec.rb[1:2:8] | passed | 0.00003 seconds |
57
+ ./spec/carddb/filter_builder_spec.rb[1:2:9] | passed | 0.00008 seconds |
58
+ ./spec/carddb/filter_builder_spec.rb[1:2:10] | passed | 0.00003 seconds |
58
59
  ./spec/carddb/filter_builder_spec.rb[1:2:11] | passed | 0.00002 seconds |
59
- ./spec/carddb/filter_builder_spec.rb[1:2:12] | passed | 0.00002 seconds |
60
- ./spec/carddb/filter_builder_spec.rb[1:2:13] | passed | 0.00003 seconds |
61
- ./spec/carddb/resources/datasets_spec.rb[1:1:1] | passed | 0.00387 seconds |
62
- ./spec/carddb/resources/datasets_spec.rb[1:1:2] | passed | 0.00363 seconds |
63
- ./spec/carddb/resources/datasets_spec.rb[1:2:1] | passed | 0.00444 seconds |
64
- ./spec/carddb/resources/decks_spec.rb[1:1:1] | passed | 0.00427 seconds |
65
- ./spec/carddb/resources/decks_spec.rb[1:2:1] | passed | 0.00438 seconds |
66
- ./spec/carddb/resources/decks_spec.rb[1:3:1] | passed | 0.00442 seconds |
67
- ./spec/carddb/resources/decks_spec.rb[1:4:1] | passed | 0.0043 seconds |
68
- ./spec/carddb/resources/decks_spec.rb[1:5:1] | passed | 0.00403 seconds |
69
- ./spec/carddb/resources/decks_spec.rb[1:6:1] | passed | 0.00384 seconds |
70
- ./spec/carddb/resources/decks_spec.rb[1:7:1] | passed | 0.00416 seconds |
71
- ./spec/carddb/resources/games_spec.rb[1:1:1] | passed | 0.00463 seconds |
72
- ./spec/carddb/resources/games_spec.rb[1:1:2] | passed | 0.00008 seconds |
73
- ./spec/carddb/resources/games_spec.rb[1:2:1] | passed | 0.00426 seconds |
74
- ./spec/carddb/resources/games_spec.rb[1:2:2] | passed | 0.00444 seconds |
75
- ./spec/carddb/resources/publishers_spec.rb[1:1:1] | passed | 0.00383 seconds |
76
- ./spec/carddb/resources/publishers_spec.rb[1:2:1] | passed | 0.00447 seconds |
77
- ./spec/carddb/resources/records_spec.rb[1:1:1] | passed | 0.00428 seconds |
78
- ./spec/carddb/resources/records_spec.rb[1:1:2] | passed | 0.00416 seconds |
79
- ./spec/carddb/resources/records_spec.rb[1:1:3] | passed | 0.00012 seconds |
60
+ ./spec/carddb/filter_builder_spec.rb[1:2:12] | passed | 0.00003 seconds |
61
+ ./spec/carddb/filter_builder_spec.rb[1:2:13] | passed | 0.00002 seconds |
62
+ ./spec/carddb/query_builder_spec.rb[1:1:1] | passed | 0.00004 seconds |
63
+ ./spec/carddb/query_builder_spec.rb[1:1:2] | passed | 0.00004 seconds |
64
+ ./spec/carddb/resources/datasets_spec.rb[1:1:1] | passed | 0.00394 seconds |
65
+ ./spec/carddb/resources/datasets_spec.rb[1:1:2] | passed | 0.00431 seconds |
66
+ ./spec/carddb/resources/datasets_spec.rb[1:2:1] | passed | 0.00428 seconds |
67
+ ./spec/carddb/resources/decks_spec.rb[1:1:1] | passed | 0.00429 seconds |
68
+ ./spec/carddb/resources/decks_spec.rb[1:1:2] | passed | 0.00472 seconds |
69
+ ./spec/carddb/resources/decks_spec.rb[1:2:1] | passed | 0.00443 seconds |
70
+ ./spec/carddb/resources/decks_spec.rb[1:3:1] | passed | 0.00398 seconds |
71
+ ./spec/carddb/resources/decks_spec.rb[1:4:1] | passed | 0.00432 seconds |
72
+ ./spec/carddb/resources/decks_spec.rb[1:5:1] | passed | 0.00428 seconds |
73
+ ./spec/carddb/resources/decks_spec.rb[1:6:1] | passed | 0.0041 seconds |
74
+ ./spec/carddb/resources/decks_spec.rb[1:7:1] | passed | 0.00435 seconds |
75
+ ./spec/carddb/resources/decks_spec.rb[1:8:1] | passed | 0.00439 seconds |
76
+ ./spec/carddb/resources/decks_spec.rb[1:9:1] | passed | 0.00417 seconds |
77
+ ./spec/carddb/resources/decks_spec.rb[1:10:1] | passed | 0.00405 seconds |
78
+ ./spec/carddb/resources/decks_spec.rb[1:11:1] | passed | 0.00427 seconds |
79
+ ./spec/carddb/resources/decks_spec.rb[1:12:1] | passed | 0.0041 seconds |
80
+ ./spec/carddb/resources/decks_spec.rb[1:13:1] | passed | 0.004 seconds |
81
+ ./spec/carddb/resources/decks_spec.rb[1:14:1] | passed | 0.00408 seconds |
82
+ ./spec/carddb/resources/decks_spec.rb[1:15:1] | passed | 0.00408 seconds |
83
+ ./spec/carddb/resources/decks_spec.rb[1:16:1] | passed | 0.00395 seconds |
84
+ ./spec/carddb/resources/decks_spec.rb[1:17:1] | passed | 0.00416 seconds |
85
+ ./spec/carddb/resources/decks_spec.rb[1:18:1] | passed | 0.0041 seconds |
86
+ ./spec/carddb/resources/decks_spec.rb[1:19:1] | passed | 0.00393 seconds |
87
+ ./spec/carddb/resources/games_spec.rb[1:1:1] | passed | 0.00398 seconds |
88
+ ./spec/carddb/resources/games_spec.rb[1:1:2] | passed | 0.00007 seconds |
89
+ ./spec/carddb/resources/games_spec.rb[1:2:1] | passed | 0.00419 seconds |
90
+ ./spec/carddb/resources/games_spec.rb[1:2:2] | passed | 0.00414 seconds |
91
+ ./spec/carddb/resources/publishers_spec.rb[1:1:1] | passed | 0.00399 seconds |
92
+ ./spec/carddb/resources/publishers_spec.rb[1:2:1] | passed | 0.00412 seconds |
93
+ ./spec/carddb/resources/records_spec.rb[1:1:1] | passed | 0.00399 seconds |
94
+ ./spec/carddb/resources/records_spec.rb[1:1:2] | passed | 0.0039 seconds |
95
+ ./spec/carddb/resources/records_spec.rb[1:1:3] | passed | 0.00011 seconds |
80
96
  ./spec/carddb/resources/records_spec.rb[1:1:4] | passed | 0.00004 seconds |
81
- ./spec/carddb/resources/records_spec.rb[1:2:1] | passed | 0.00412 seconds |
82
- ./spec/carddb/resources/records_spec.rb[1:2:2] | passed | 0.00414 seconds |
83
- ./spec/carddb/resources/records_spec.rb[1:3:1] | passed | 0.00444 seconds |
84
- ./spec/carddb/resources/records_spec.rb[1:3:2] | passed | 0.00011 seconds |
85
- ./spec/carddb/resources/records_spec.rb[1:4:1] | passed | 0.00365 seconds |
86
- ./spec/carddb/resources/records_spec.rb[1:4:2] | passed | 0.00004 seconds |
87
- ./spec/carddb/resources/records_spec.rb[1:4:3] | passed | 0.00009 seconds |
88
- ./spec/carddb/resources/rules_spec.rb[1:1:1] | passed | 0.00403 seconds |
89
- ./spec/carddb/resources/rules_spec.rb[1:2:1] | passed | 0.00419 seconds |
97
+ ./spec/carddb/resources/records_spec.rb[1:2:1] | passed | 0.00448 seconds |
98
+ ./spec/carddb/resources/records_spec.rb[1:2:2] | passed | 0.0037 seconds |
99
+ ./spec/carddb/resources/records_spec.rb[1:3:1] | passed | 0.0038 seconds |
100
+ ./spec/carddb/resources/records_spec.rb[1:3:2] | passed | 0.00016 seconds |
101
+ ./spec/carddb/resources/records_spec.rb[1:4:1] | passed | 0.00431 seconds |
102
+ ./spec/carddb/resources/records_spec.rb[1:4:2] | passed | 0.00005 seconds |
103
+ ./spec/carddb/resources/records_spec.rb[1:4:3] | passed | 0.00011 seconds |
104
+ ./spec/carddb/resources/rules_spec.rb[1:1:1] | passed | 0.00408 seconds |
105
+ ./spec/carddb/resources/rules_spec.rb[1:2:1] | passed | 0.00417 seconds |
90
106
  ./spec/carddb_spec.rb[1:1] | passed | 0.00004 seconds |
91
107
  ./spec/carddb_spec.rb[1:2:1] | passed | 0.00003 seconds |
92
108
  ./spec/carddb_spec.rb[1:3:1] | passed | 0.00003 seconds |
93
109
  ./spec/carddb_spec.rb[1:4:1] | passed | 0.00004 seconds |
94
- ./spec/carddb_spec.rb[1:5:1] | passed | 0.00003 seconds |
95
- ./spec/carddb_spec.rb[1:6:1] | passed | 0.00003 seconds |
96
- ./spec/carddb_spec.rb[1:7:1] | passed | 0.00003 seconds |
110
+ ./spec/carddb_spec.rb[1:5:1] | passed | 0.00005 seconds |
111
+ ./spec/carddb_spec.rb[1:6:1] | passed | 0.00005 seconds |
112
+ ./spec/carddb_spec.rb[1:7:1] | passed | 0.00004 seconds |
data/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.1] - 2026-05-01
11
+
12
+ ### Fixed
13
+
14
+ - Fetch dataset schemas with recursive `nestedFields` selections to preserve deeper nested field definitions.
15
+
10
16
  ## [0.2.0] - 2026-04-29
11
17
 
12
18
  ### Added
data/carddb.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/carddb/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'carddb'
7
+ spec.version = CardDB::VERSION
8
+ spec.authors = ['CardDB Team']
9
+ spec.email = ['support@carddb.xtda.org']
10
+
11
+ spec.summary = 'Ruby client for the CardDB API'
12
+ spec.description = 'A Ruby client library for interacting with the CardDB GraphQL API. ' \
13
+ 'Search and fetch card game data with an expressive filter DSL.'
14
+ spec.homepage = 'https://github.com/xtda/carddb-ruby'
15
+ spec.license = 'MIT'
16
+ spec.required_ruby_version = '>= 3.0.0'
17
+
18
+ spec.metadata['homepage_uri'] = spec.homepage
19
+ spec.metadata['source_code_uri'] = 'https://github.com/xtda/carddb-ruby'
20
+ spec.metadata['changelog_uri'] = 'https://github.com/xtda/carddb-ruby/blob/main/CHANGELOG.md'
21
+ spec.metadata['rubygems_mfa_required'] = 'true'
22
+
23
+ spec.files = Dir.chdir(__dir__) do
24
+ `git ls-files -z`.split("\x0").reject do |f|
25
+ (File.expand_path(f) == __FILE__) ||
26
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git .github appveyor Gemfile])
27
+ end
28
+ end
29
+ spec.bindir = 'exe'
30
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ['lib']
32
+
33
+ spec.add_dependency 'faraday', '~> 2.0'
34
+ spec.add_dependency 'faraday-retry', '~> 2.0'
35
+ end
@@ -786,6 +786,99 @@ module CardDB
786
786
  @game ||= data['game'] ? Game.new(data['game'], client: client) : nil
787
787
  end
788
788
 
789
+ def slug
790
+ data['slug']
791
+ end
792
+
793
+ def identifier
794
+ data['identifier']
795
+ end
796
+
797
+ def title
798
+ data['title']
799
+ end
800
+
801
+ def description
802
+ data['description']
803
+ end
804
+
805
+ def format_key
806
+ data['formatKey']
807
+ end
808
+
809
+ def visibility
810
+ data['visibility']
811
+ end
812
+
813
+ def external_ref
814
+ data['externalRef']
815
+ end
816
+
817
+ def source_url
818
+ data['sourceUrl']
819
+ end
820
+
821
+ def metadata
822
+ data['metadata'] || {}
823
+ end
824
+
825
+ def entries
826
+ @entries ||= (data['entries'] || []).map { |entry| DeckEntry.new(entry, client: client) }
827
+ end
828
+
829
+ def latest_published_version
830
+ @latest_published_version ||= data['latestPublishedVersion'] ? DeckVersion.new(data['latestPublishedVersion'], client: client) : nil
831
+ end
832
+
833
+ def published_at
834
+ parse_time(data['publishedAt'])
835
+ end
836
+
837
+ def has_unpublished_changes?
838
+ !!data['hasUnpublishedChanges']
839
+ end
840
+
841
+ def created_at
842
+ parse_time(data['createdAt'])
843
+ end
844
+
845
+ def updated_at
846
+ parse_time(data['updatedAt'])
847
+ end
848
+
849
+ private
850
+
851
+ def parse_time(value)
852
+ return nil unless value
853
+
854
+ Time.parse(value)
855
+ rescue ArgumentError
856
+ value
857
+ end
858
+ end
859
+
860
+ # Wrapper for immutable published DeckVersion objects
861
+ class DeckVersion < Resource
862
+ def id
863
+ data['id']
864
+ end
865
+
866
+ def deck_id
867
+ data['deckId']
868
+ end
869
+
870
+ def version_number
871
+ data['versionNumber']
872
+ end
873
+
874
+ def slug
875
+ data['slug']
876
+ end
877
+
878
+ def identifier
879
+ data['identifier']
880
+ end
881
+
789
882
  def title
790
883
  data['title']
791
884
  end
@@ -818,6 +911,59 @@ module CardDB
818
911
  @entries ||= (data['entries'] || []).map { |entry| DeckEntry.new(entry, client: client) }
819
912
  end
820
913
 
914
+ def publish_note
915
+ data['publishNote']
916
+ end
917
+
918
+ def computed_diff
919
+ data['computedDiff'] || {}
920
+ end
921
+
922
+ def published_by_account_id
923
+ data['publishedByAccountId']
924
+ end
925
+
926
+ def published_by_api_application_id
927
+ data['publishedByApiApplicationId']
928
+ end
929
+
930
+ def created_at
931
+ parse_time(data['createdAt'])
932
+ end
933
+
934
+ private
935
+
936
+ def parse_time(value)
937
+ return nil unless value
938
+
939
+ Time.parse(value)
940
+ rescue ArgumentError
941
+ value
942
+ end
943
+ end
944
+
945
+ # Wrapper for deck collaborator objects
946
+ class DeckCollaborator < Resource
947
+ def id
948
+ data['id']
949
+ end
950
+
951
+ def deck_id
952
+ data['deckId']
953
+ end
954
+
955
+ def account_id
956
+ data['accountId']
957
+ end
958
+
959
+ def role
960
+ data['role']
961
+ end
962
+
963
+ def created_by_account_id
964
+ data['createdByAccountId']
965
+ end
966
+
821
967
  def created_at
822
968
  parse_time(data['createdAt'])
823
969
  end
@@ -837,6 +983,62 @@ module CardDB
837
983
  end
838
984
  end
839
985
 
986
+ # Wrapper for deck preview token metadata
987
+ class DeckPreviewToken < Resource
988
+ def id
989
+ data['id']
990
+ end
991
+
992
+ def deck_id
993
+ data['deckId']
994
+ end
995
+
996
+ def label
997
+ data['label']
998
+ end
999
+
1000
+ def expires_at
1001
+ parse_time(data['expiresAt'])
1002
+ end
1003
+
1004
+ def revoked_at
1005
+ parse_time(data['revokedAt'])
1006
+ end
1007
+
1008
+ def last_used_at
1009
+ parse_time(data['lastUsedAt'])
1010
+ end
1011
+
1012
+ def created_at
1013
+ parse_time(data['createdAt'])
1014
+ end
1015
+
1016
+ def updated_at
1017
+ parse_time(data['updatedAt'])
1018
+ end
1019
+
1020
+ private
1021
+
1022
+ def parse_time(value)
1023
+ return nil unless value
1024
+
1025
+ Time.parse(value)
1026
+ rescue ArgumentError
1027
+ value
1028
+ end
1029
+ end
1030
+
1031
+ # Wrapper for deck preview token creation payloads
1032
+ class DeckPreviewTokenCreatePayload < Resource
1033
+ def token
1034
+ data['token']
1035
+ end
1036
+
1037
+ def preview_token
1038
+ @preview_token ||= data['previewToken'] ? DeckPreviewToken.new(data['previewToken'], client: client) : nil
1039
+ end
1040
+ end
1041
+
840
1042
  # Wrapper for hosted DeckEntry objects
841
1043
  class DeckEntry < Resource
842
1044
  def id
@@ -4,6 +4,8 @@ module CardDB
4
4
  # Builds GraphQL queries for the CardDB API.
5
5
  # rubocop:disable Metrics/ModuleLength
6
6
  module QueryBuilder
7
+ SCHEMA_NESTED_FIELDS_DEPTH = 4
8
+
7
9
  # rubocop:disable Metrics/ClassLength
8
10
  class << self
9
11
  # Builds a searchPublishers query
@@ -268,6 +270,28 @@ module CardDB
268
270
  GRAPHQL
269
271
  end
270
272
 
273
+ # Builds a myDeck query
274
+ def my_deck
275
+ <<~GRAPHQL
276
+ query MyDeck($id: UUID!) {
277
+ myDeck(id: $id) {
278
+ #{deck_fields}
279
+ }
280
+ }
281
+ GRAPHQL
282
+ end
283
+
284
+ # Builds a fetchDeckBySlug query
285
+ def fetch_deck_by_slug
286
+ <<~GRAPHQL
287
+ query FetchDeckBySlug($publisherSlug: String!, $gameKey: String!, $slug: String!) {
288
+ fetchDeckBySlug(publisherSlug: $publisherSlug, gameKey: $gameKey, slug: $slug) {
289
+ #{deck_fields}
290
+ }
291
+ }
292
+ GRAPHQL
293
+ end
294
+
271
295
  # Builds a fetchDeckByExternalRef query
272
296
  def fetch_deck_by_external_ref
273
297
  <<~GRAPHQL
@@ -279,6 +303,63 @@ module CardDB
279
303
  GRAPHQL
280
304
  end
281
305
 
306
+ # Builds a deckVersion query
307
+ def deck_version
308
+ <<~GRAPHQL
309
+ query DeckVersion($id: UUID!) {
310
+ deckVersion(id: $id) {
311
+ #{deck_version_fields}
312
+ }
313
+ }
314
+ GRAPHQL
315
+ end
316
+
317
+ # Builds a deckVersions query
318
+ def deck_versions(first: nil, after: nil)
319
+ args = build_args({ deckId: true, first: first, after: after }, required: [:deckId])
320
+
321
+ <<~GRAPHQL
322
+ query DeckVersions#{args[:definition]} {
323
+ deckVersions#{args[:call]} {
324
+ #{deck_version_connection_fields}
325
+ }
326
+ }
327
+ GRAPHQL
328
+ end
329
+
330
+ # Builds a deckPreview query
331
+ def deck_preview
332
+ <<~GRAPHQL
333
+ query DeckPreview($token: String!) {
334
+ deckPreview(token: $token) {
335
+ #{deck_fields}
336
+ }
337
+ }
338
+ GRAPHQL
339
+ end
340
+
341
+ # Builds a deckCollaborators query
342
+ def deck_collaborators
343
+ <<~GRAPHQL
344
+ query DeckCollaborators($deckId: UUID!) {
345
+ deckCollaborators(deckId: $deckId) {
346
+ #{deck_collaborator_fields}
347
+ }
348
+ }
349
+ GRAPHQL
350
+ end
351
+
352
+ # Builds a deckPreviewTokens query
353
+ def deck_preview_tokens
354
+ <<~GRAPHQL
355
+ query DeckPreviewTokens($deckId: UUID!) {
356
+ deckPreviewTokens(deckId: $deckId) {
357
+ #{deck_preview_token_fields}
358
+ }
359
+ }
360
+ GRAPHQL
361
+ end
362
+
282
363
  # Builds a deckCreate mutation
283
364
  def create_deck
284
365
  <<~GRAPHQL
@@ -301,6 +382,60 @@ module CardDB
301
382
  GRAPHQL
302
383
  end
303
384
 
385
+ # Builds a deckPublish mutation
386
+ def publish_deck
387
+ <<~GRAPHQL
388
+ mutation DeckPublish($id: UUID!, $input: DeckPublishInput!) {
389
+ deckPublish(id: $id, input: $input) {
390
+ #{deck_version_fields}
391
+ }
392
+ }
393
+ GRAPHQL
394
+ end
395
+
396
+ # Builds a deckCollaboratorUpsert mutation
397
+ def upsert_deck_collaborator
398
+ <<~GRAPHQL
399
+ mutation DeckCollaboratorUpsert($deckId: UUID!, $accountId: UUID!, $role: DeckCollaboratorRole!) {
400
+ deckCollaboratorUpsert(deckId: $deckId, accountId: $accountId, role: $role) {
401
+ #{deck_collaborator_fields}
402
+ }
403
+ }
404
+ GRAPHQL
405
+ end
406
+
407
+ # Builds a deckCollaboratorRemove mutation
408
+ def remove_deck_collaborator
409
+ <<~GRAPHQL
410
+ mutation DeckCollaboratorRemove($deckId: UUID!, $accountId: UUID!) {
411
+ deckCollaboratorRemove(deckId: $deckId, accountId: $accountId)
412
+ }
413
+ GRAPHQL
414
+ end
415
+
416
+ # Builds a deckPreviewTokenCreate mutation
417
+ def create_deck_preview_token
418
+ <<~GRAPHQL
419
+ mutation DeckPreviewTokenCreate($input: DeckPreviewTokenCreateInput!) {
420
+ deckPreviewTokenCreate(input: $input) {
421
+ token
422
+ previewToken {
423
+ #{deck_preview_token_fields}
424
+ }
425
+ }
426
+ }
427
+ GRAPHQL
428
+ end
429
+
430
+ # Builds a deckPreviewTokenRevoke mutation
431
+ def revoke_deck_preview_token
432
+ <<~GRAPHQL
433
+ mutation DeckPreviewTokenRevoke($id: UUID!) {
434
+ deckPreviewTokenRevoke(id: $id)
435
+ }
436
+ GRAPHQL
437
+ end
438
+
304
439
  # Builds a deckDelete mutation
305
440
  def delete_deck
306
441
  <<~GRAPHQL
@@ -357,6 +492,7 @@ module CardDB
357
492
  first: 'Int',
358
493
  after: 'String',
359
494
  externalRef: 'String',
495
+ deckId: 'UUID!',
360
496
  validateSchema: 'Boolean',
361
497
  purpose: 'DatasetPurpose',
362
498
  id: 'UUID!',
@@ -492,29 +628,7 @@ module CardDB
492
628
  <<~FIELDS
493
629
  schema {
494
630
  fields {
495
- key
496
- label
497
- description
498
- type
499
- isRequired
500
- filterable
501
- searchable
502
- isIdentifier
503
- itemType
504
- displayFormat
505
- semanticType
506
- allowedValues
507
- nestedFields {
508
- key
509
- label
510
- description
511
- type
512
- isRequired
513
- filterable
514
- searchable
515
- itemType
516
- semanticType
517
- }
631
+ #{field_info_fields(depth: SCHEMA_NESTED_FIELDS_DEPTH)}
518
632
  }
519
633
  filterableFields
520
634
  searchableFields
@@ -529,6 +643,32 @@ module CardDB
529
643
  FIELDS
530
644
  end
531
645
 
646
+ def field_info_fields(depth:)
647
+ nested_fields = if depth.positive?
648
+ <<~FIELDS
649
+ nestedFields {
650
+ #{field_info_fields(depth: depth - 1)}
651
+ }
652
+ FIELDS
653
+ end
654
+
655
+ <<~FIELDS
656
+ key
657
+ label
658
+ description
659
+ type
660
+ isRequired
661
+ filterable
662
+ searchable
663
+ isIdentifier
664
+ itemType
665
+ displayFormat
666
+ semanticType
667
+ allowedValues
668
+ #{nested_fields}
669
+ FIELDS
670
+ end
671
+
532
672
  def dataset_connection_fields
533
673
  <<~FIELDS
534
674
  totalCount
@@ -606,6 +746,8 @@ module CardDB
606
746
  accountId
607
747
  apiApplicationId
608
748
  gameId
749
+ slug
750
+ identifier
609
751
  title
610
752
  description
611
753
  formatKey
@@ -613,6 +755,11 @@ module CardDB
613
755
  externalRef
614
756
  sourceUrl
615
757
  metadata
758
+ latestPublishedVersion {
759
+ #{deck_version_fields}
760
+ }
761
+ publishedAt
762
+ hasUnpublishedChanges
616
763
  createdAt
617
764
  updatedAt
618
765
  game {
@@ -634,6 +781,84 @@ module CardDB
634
781
  FIELDS
635
782
  end
636
783
 
784
+ def deck_version_fields
785
+ <<~FIELDS
786
+ id
787
+ deckId
788
+ versionNumber
789
+ slug
790
+ identifier
791
+ title
792
+ description
793
+ formatKey
794
+ visibility
795
+ externalRef
796
+ sourceUrl
797
+ metadata
798
+ publishNote
799
+ computedDiff
800
+ publishedByAccountId
801
+ publishedByApiApplicationId
802
+ createdAt
803
+ entries {
804
+ id
805
+ datasetId
806
+ recordId
807
+ identifier
808
+ quantity
809
+ section
810
+ sortOrder
811
+ annotations
812
+ record {
813
+ #{record_fields}
814
+ }
815
+ }
816
+ FIELDS
817
+ end
818
+
819
+ def deck_version_connection_fields
820
+ <<~FIELDS
821
+ totalCount
822
+ pageInfo {
823
+ hasNextPage
824
+ hasPreviousPage
825
+ startCursor
826
+ endCursor
827
+ }
828
+ edges {
829
+ cursor
830
+ node {
831
+ #{deck_version_fields}
832
+ }
833
+ }
834
+ FIELDS
835
+ end
836
+
837
+ def deck_collaborator_fields
838
+ <<~FIELDS
839
+ id
840
+ deckId
841
+ accountId
842
+ role
843
+ createdByAccountId
844
+ createdAt
845
+ updatedAt
846
+ FIELDS
847
+ end
848
+
849
+ def deck_preview_token_fields
850
+ <<~FIELDS
851
+ id
852
+ deckId
853
+ label
854
+ expiresAt
855
+ revokedAt
856
+ lastUsedAt
857
+ createdAt
858
+ updatedAt
859
+ FIELDS
860
+ end
861
+
637
862
  def deck_connection_fields
638
863
  <<~FIELDS
639
864
  totalCount
@@ -31,6 +31,31 @@ module CardDB
31
31
  end
32
32
  end
33
33
 
34
+ # Fetch one deck owned by the current account or API application.
35
+ def fetch_mine(id, cache: nil)
36
+ key = cache_key('decks', 'fetch_mine', id: id)
37
+ with_cache(key, resource: :decks, cache: cache) do
38
+ data = connection.execute(QueryBuilder.my_deck, { id: id })
39
+ data['myDeck'] ? Deck.new(data['myDeck'], client: client) : nil
40
+ end
41
+ end
42
+
43
+ # Fetch a hosted deck by canonical or historical slug.
44
+ def fetch_by_slug(slug:, publisher_slug: nil, game_key: nil, cache: nil)
45
+ resolved_publisher = resolve_publisher(publisher_slug)
46
+ resolved_game = resolve_game(game_key)
47
+ validate_access!(resolved_publisher, resolved_game)
48
+
49
+ key = cache_key('decks', 'fetch_by_slug', publisher_slug: resolved_publisher, game_key: resolved_game, slug: slug)
50
+ with_cache(key, resource: :decks, cache: cache) do
51
+ data = connection.execute(
52
+ QueryBuilder.fetch_deck_by_slug,
53
+ { publisherSlug: resolved_publisher, gameKey: resolved_game, slug: slug }
54
+ )
55
+ data['fetchDeckBySlug'] ? Deck.new(data['fetchDeckBySlug'], client: client) : nil
56
+ end
57
+ end
58
+
34
59
  # Fetch a hosted deck by external reference for the current API application.
35
60
  def fetch_by_external_ref(external_ref:, cache: nil)
36
61
  key = cache_key('decks', 'fetch_by_external_ref', external_ref: external_ref)
@@ -40,6 +65,60 @@ module CardDB
40
65
  end
41
66
  end
42
67
 
68
+ # Fetch one immutable published deck version.
69
+ def fetch_version(id, cache: nil)
70
+ key = cache_key('decks', 'fetch_version', id: id)
71
+ with_cache(key, resource: :decks, cache: cache) do
72
+ data = connection.execute(QueryBuilder.deck_version, { id: id })
73
+ data['deckVersion'] ? DeckVersion.new(data['deckVersion'], client: client) : nil
74
+ end
75
+ end
76
+
77
+ # List immutable published versions for a deck.
78
+ def list_versions(deck_id:, first: nil, after: nil, cache: nil)
79
+ query = QueryBuilder.deck_versions(first: first, after: after)
80
+ variables = build_variables(deckId: deck_id, first: first, after: after)
81
+ key = cache_key('decks', 'list_versions', **variables)
82
+
83
+ data = with_cache(key, resource: :decks, cache: cache) do
84
+ connection.execute(query, variables)
85
+ end
86
+
87
+ Collection.new(
88
+ data['deckVersions'],
89
+ item_class: DeckVersion,
90
+ next_page_loader: ->(cursor) { list_versions(deck_id: deck_id, first: first, after: cursor, cache: cache) },
91
+ client: client
92
+ )
93
+ end
94
+
95
+ # Fetch current draft data using a revocable preview token.
96
+ def preview(token:, cache: nil)
97
+ key = cache_key('decks', 'preview', token: token)
98
+ with_cache(key, resource: :decks, cache: cache) do
99
+ data = connection.execute(QueryBuilder.deck_preview, { token: token })
100
+ data['deckPreview'] ? Deck.new(data['deckPreview'], client: client) : nil
101
+ end
102
+ end
103
+
104
+ # List collaborators for a deck.
105
+ def collaborators(deck_id:, cache: nil)
106
+ key = cache_key('decks', 'collaborators', deck_id: deck_id)
107
+ with_cache(key, resource: :decks, cache: cache) do
108
+ data = connection.execute(QueryBuilder.deck_collaborators, { deckId: deck_id })
109
+ (data['deckCollaborators'] || []).map { |collaborator| DeckCollaborator.new(collaborator, client: client) }
110
+ end
111
+ end
112
+
113
+ # List draft preview tokens for a deck.
114
+ def preview_tokens(deck_id:, cache: nil)
115
+ key = cache_key('decks', 'preview_tokens', deck_id: deck_id)
116
+ with_cache(key, resource: :decks, cache: cache) do
117
+ data = connection.execute(QueryBuilder.deck_preview_tokens, { deckId: deck_id })
118
+ (data['deckPreviewTokens'] || []).map { |token| DeckPreviewToken.new(token, client: client) }
119
+ end
120
+ end
121
+
43
122
  # Create a hosted deck.
44
123
  def create(input:)
45
124
  data = connection.execute(QueryBuilder.create_deck, { input: input })
@@ -52,6 +131,46 @@ module CardDB
52
131
  Deck.new(data['deckUpdate'], client: client)
53
132
  end
54
133
 
134
+ # Publish the current draft as an immutable deck version.
135
+ def publish(id:, input: {})
136
+ data = connection.execute(QueryBuilder.publish_deck, { id: id, input: input })
137
+ DeckVersion.new(data['deckPublish'], client: client)
138
+ end
139
+
140
+ # Create or update a deck collaborator.
141
+ def upsert_collaborator(deck_id:, account_id:, role:)
142
+ data = connection.execute(
143
+ QueryBuilder.upsert_deck_collaborator,
144
+ { deckId: deck_id, accountId: account_id, role: role }
145
+ )
146
+ DeckCollaborator.new(data['deckCollaboratorUpsert'], client: client)
147
+ end
148
+
149
+ # Remove a deck collaborator.
150
+ # rubocop:disable Naming/PredicateMethod
151
+ def remove_collaborator(deck_id:, account_id:)
152
+ data = connection.execute(
153
+ QueryBuilder.remove_deck_collaborator,
154
+ { deckId: deck_id, accountId: account_id }
155
+ )
156
+ !!data['deckCollaboratorRemove']
157
+ end
158
+ # rubocop:enable Naming/PredicateMethod
159
+
160
+ # Create a revocable draft preview token.
161
+ def create_preview_token(input:)
162
+ data = connection.execute(QueryBuilder.create_deck_preview_token, { input: input })
163
+ DeckPreviewTokenCreatePayload.new(data['deckPreviewTokenCreate'], client: client)
164
+ end
165
+
166
+ # Revoke a draft preview token.
167
+ # rubocop:disable Naming/PredicateMethod
168
+ def revoke_preview_token(id:)
169
+ data = connection.execute(QueryBuilder.revoke_deck_preview_token, { id: id })
170
+ !!data['deckPreviewTokenRevoke']
171
+ end
172
+ # rubocop:enable Naming/PredicateMethod
173
+
55
174
  # Delete a hosted deck.
56
175
  # rubocop:disable Naming/PredicateMethod
57
176
  def delete(id:)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CardDB
4
- VERSION = '0.2.0'
4
+ VERSION = '0.2.1'
5
5
  end
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+ cd "$ROOT_DIR"
6
+
7
+ GEMSPEC="carddb.gemspec"
8
+
9
+ if ! command -v bundle >/dev/null 2>&1; then
10
+ printf 'bundle is required but was not found in PATH.\n' >&2
11
+ exit 1
12
+ fi
13
+
14
+ if [[ ! -f "$GEMSPEC" ]]; then
15
+ printf 'Expected %s in %s.\n' "$GEMSPEC" "$ROOT_DIR" >&2
16
+ exit 1
17
+ fi
18
+
19
+ version="$(ruby -Ilib -rcarddb/version -e 'print CardDB::VERSION')"
20
+ gem_file="pkg/carddb-${version}.gem"
21
+
22
+ if [[ -n "$(git status --porcelain)" ]]; then
23
+ printf 'Working tree has uncommitted changes. Commit or stash before publishing.\n' >&2
24
+ git status --short >&2
25
+ exit 1
26
+ fi
27
+
28
+ bundle exec rspec
29
+ bundle exec rubocop
30
+
31
+ rm -f "$gem_file"
32
+ gem build "$GEMSPEC" --output "$gem_file"
33
+ gem push "$gem_file"
34
+
35
+ printf 'Published carddb %s from %s.\n' "$version" "$gem_file"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carddb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - CardDB Team
@@ -53,6 +53,7 @@ files:
53
53
  - LICENSE.txt
54
54
  - README.md
55
55
  - Rakefile
56
+ - carddb.gemspec
56
57
  - examples/basic_usage.rb
57
58
  - examples/filtering.rb
58
59
  - examples/pagination.rb
@@ -74,6 +75,7 @@ files:
74
75
  - lib/carddb/resources/records.rb
75
76
  - lib/carddb/resources/rules.rb
76
77
  - lib/carddb/version.rb
78
+ - scripts/publish.sh
77
79
  homepage: https://github.com/xtda/carddb-ruby
78
80
  licenses:
79
81
  - MIT