app_store_connect 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +7 -5
- data/bin/console +1 -1
- data/lib/app_store_connect/bundle_id_create_request.rb +9 -12
- data/lib/app_store_connect/client.rb +89 -33
- data/lib/app_store_connect/create_request.rb +11 -0
- data/lib/app_store_connect/object/attributes.rb +47 -0
- data/lib/app_store_connect/object/data.rb +45 -0
- data/lib/app_store_connect/object/properties.rb +23 -0
- data/lib/app_store_connect/object/type.rb +25 -0
- data/lib/app_store_connect/user_invitation_create_request.rb +8 -0
- data/lib/app_store_connect/version.rb +1 -1
- data/lib/app_store_connect/web_service_endpoint.rb +21 -0
- data/lib/app_store_connect.rb +14 -0
- data/lib/config/api.json +44 -0
- metadata +8 -4
- data/lib/app_store_connect/bundle_id_create_request/data/attributes.rb +0 -28
- data/lib/app_store_connect/bundle_id_create_request/data.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6bece2d6691fbb4f254b53de5001324dfe4d10840c8c0cf82a073f0260bde177
|
4
|
+
data.tar.gz: d45d001147d7694579c6c838a52fa376607d83cb82b82bc2481193f763cf4ed7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e9cff4c10632c74fa8bc63a04b3cd24af7be3ee04bc0d9914da6e0fae3d421a6a802d429c7adc43ad1c8cf20761c296575041e73c78ab38ee2aa2bb0c4cf0b7
|
7
|
+
data.tar.gz: 8301b52487821ab284c8f0c6ccbdd87b1fc3361337239aec2569da1ae4bc8a9f894ebdda28bb849a2ad42403ab840f7586f19c012ef156c6cc611db48333379a
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -23,15 +23,17 @@ Or install it yourself as:
|
|
23
23
|
## Usage
|
24
24
|
|
25
25
|
```ruby
|
26
|
-
|
26
|
+
AppStoreConnect.config = {
|
27
27
|
issuer_id: issuer_id,
|
28
28
|
key_id: key_id,
|
29
29
|
private_key: private_key
|
30
|
-
|
30
|
+
}
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
app_store_connect = AppStoreConnect::Client.new
|
33
|
+
|
34
|
+
app_store_connect.apps
|
35
|
+
app_store_connect.app('1234')
|
36
|
+
app_store_connect.builds('1234')
|
35
37
|
```
|
36
38
|
|
37
39
|
## Development
|
data/bin/console
CHANGED
@@ -1,19 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative './bundle_id_create_request/data'
|
4
|
-
|
5
3
|
module AppStoreConnect
|
6
|
-
class BundleIdCreateRequest
|
7
|
-
|
8
|
-
|
9
|
-
def initialize(*args)
|
10
|
-
@data = Data.new(*args)
|
11
|
-
end
|
4
|
+
class BundleIdCreateRequest < CreateRequest
|
5
|
+
data do
|
6
|
+
type 'bundleIds'
|
12
7
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
8
|
+
attributes do
|
9
|
+
property :identifier, required: true
|
10
|
+
property :name, required: true
|
11
|
+
property :platform, required: true
|
12
|
+
property :seed_id
|
13
|
+
end
|
17
14
|
end
|
18
15
|
end
|
19
16
|
end
|
@@ -2,75 +2,131 @@
|
|
2
2
|
|
3
3
|
require 'active_support/all'
|
4
4
|
|
5
|
+
require 'app_store_connect/web_service_endpoint'
|
6
|
+
|
5
7
|
module AppStoreConnect
|
6
|
-
class Client
|
7
|
-
|
8
|
+
class Client # rubocop:disable Metrics/ClassLength
|
9
|
+
def initialize(**kwargs)
|
10
|
+
@options = options(**kwargs)
|
8
11
|
|
9
|
-
def initialize(key_id:, issuer_id:, private_key:)
|
10
12
|
@authorization = Authorization.new(
|
11
|
-
private_key: private_key,
|
12
|
-
key_id: key_id,
|
13
|
-
issuer_id: issuer_id
|
13
|
+
private_key: @options[:private_key],
|
14
|
+
key_id: @options[:key_id],
|
15
|
+
issuer_id: @options[:issuer_id]
|
14
16
|
)
|
17
|
+
@web_service_endpoints_by_name ||= begin
|
18
|
+
AppStoreConnect::Config::API['web_service_endpoints'].dup.map do |config|
|
19
|
+
[config.fetch('alias').to_sym, WebServiceEndpoint.new(**config.deep_symbolize_keys)]
|
20
|
+
end.to_h
|
21
|
+
end
|
15
22
|
end
|
16
23
|
|
17
|
-
def
|
18
|
-
|
24
|
+
def respond_to_missing?(method_name, include_private = false)
|
25
|
+
web_service_endpoint_names.include?(method_name) || super
|
19
26
|
end
|
20
27
|
|
21
|
-
def
|
22
|
-
|
23
|
-
end
|
28
|
+
def method_missing(method_name, *kwargs)
|
29
|
+
super unless web_service_endpoint_names.include?(method_name)
|
24
30
|
|
25
|
-
|
26
|
-
get("apps/#{app_id}/builds")
|
27
|
-
end
|
31
|
+
web_service_endpoint = web_service_endpoint_by(name: method_name)
|
28
32
|
|
29
|
-
|
30
|
-
get("apps/#{app_id}/builds/#{build_id}")
|
33
|
+
call(web_service_endpoint, *kwargs)
|
31
34
|
end
|
32
35
|
|
33
|
-
|
34
|
-
invitation = UserInvitationCreateRequest.new(first_name, last_name, email, roles)
|
36
|
+
private
|
35
37
|
|
36
|
-
|
38
|
+
def web_service_endpoint_names
|
39
|
+
@web_service_endpoints_by_name.keys
|
37
40
|
end
|
38
41
|
|
39
|
-
def
|
40
|
-
|
42
|
+
def call(web_service_endpoint, **kwargs)
|
43
|
+
case web_service_endpoint.http_method
|
44
|
+
when :get
|
45
|
+
get(web_service_endpoint, **kwargs)
|
46
|
+
when :post
|
47
|
+
post(web_service_endpoint, **kwargs)
|
48
|
+
else
|
49
|
+
raise "invalid http method: #{web_service_endpoint.http_method}"
|
50
|
+
end
|
51
|
+
end
|
41
52
|
|
42
|
-
|
53
|
+
def build_url(web_service_endpoint, **kwargs)
|
54
|
+
web_service_endpoint
|
55
|
+
.url
|
56
|
+
.gsub(/(\{(\w+)\})/) { kwargs.fetch(Regexp.last_match(2).to_sym) }
|
43
57
|
end
|
44
58
|
|
45
|
-
def
|
46
|
-
|
59
|
+
def url_parameter_names(web_service_endpoint)
|
60
|
+
web_service_endpoint
|
61
|
+
.url
|
62
|
+
.scan(/(\{(\w+)\})/)
|
63
|
+
.map { |_, n| n.to_sym }
|
47
64
|
end
|
48
65
|
|
49
|
-
def
|
50
|
-
|
66
|
+
def web_service_endpoint_by(name:)
|
67
|
+
@web_service_endpoints_by_name[name]
|
51
68
|
end
|
52
69
|
|
53
|
-
|
70
|
+
def env_options
|
71
|
+
{}.tap do |hash|
|
72
|
+
ENV.each do |key, value|
|
73
|
+
match = key.match(/APP_STORE_CONNECT_(?<name>[A-Z_]+)/)
|
74
|
+
|
75
|
+
next unless match
|
76
|
+
|
77
|
+
hash[match[:name].downcase.to_sym] = value
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
54
81
|
|
55
|
-
def
|
82
|
+
def options(**kwargs)
|
83
|
+
AppStoreConnect.config.merge(kwargs.merge(env_options)).tap do |options|
|
84
|
+
%i[key_id issuer_id private_key].each do |key|
|
85
|
+
raise ArgumentError, "missing #{key}" unless options.keys.include?(key)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def build_body(request)
|
56
91
|
request
|
57
|
-
.
|
92
|
+
.to_h
|
58
93
|
.deep_transform_keys { |k| k.to_s.camelize(:lower) }
|
59
94
|
.to_json
|
60
95
|
end
|
61
96
|
|
62
|
-
def
|
63
|
-
|
97
|
+
def build_query(web_service_endpoint, **kwargs)
|
98
|
+
query_parameters = kwargs.dup.tap do |hash|
|
99
|
+
url_parameter_names(web_service_endpoint).each do |name|
|
100
|
+
hash.delete(name.to_sym)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
query_parameters.to_query
|
105
|
+
end
|
106
|
+
|
107
|
+
def get(web_service_endpoint, **kwargs)
|
108
|
+
url = build_url(web_service_endpoint, **kwargs)
|
109
|
+
query = build_query(web_service_endpoint, **kwargs)
|
110
|
+
|
111
|
+
response = execute(:get, url, headers: headers, query: query)
|
64
112
|
|
65
113
|
response['data']
|
66
114
|
end
|
67
115
|
|
68
|
-
def post(
|
69
|
-
|
116
|
+
def post(web_service_endpoint, **kwargs)
|
117
|
+
url = build_url(web_service_endpoint, **kwargs)
|
118
|
+
request = "AppStoreConnect::#{web_service_endpoint.http_body_type}".constantize.new(**kwargs)
|
119
|
+
body = build_body(request)
|
120
|
+
|
121
|
+
response = execute(:post, url, headers: headers, body: body)
|
70
122
|
|
71
123
|
response
|
72
124
|
end
|
73
125
|
|
126
|
+
def execute(http_method, url, **options)
|
127
|
+
HTTParty.send(http_method, url, options)
|
128
|
+
end
|
129
|
+
|
74
130
|
def headers
|
75
131
|
{
|
76
132
|
'Authorization' => "Bearer #{@authorization.token}",
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/concern'
|
4
|
+
|
5
|
+
module AppStoreConnect
|
6
|
+
module Object
|
7
|
+
module Attributes
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
class_methods do
|
11
|
+
def attributes(&block)
|
12
|
+
self::Attributes.class_eval(&block)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
included do
|
17
|
+
attr_reader :attributes
|
18
|
+
|
19
|
+
klass = Class.new do |attributes|
|
20
|
+
include Object::Properties
|
21
|
+
|
22
|
+
attributes.define_method :initialize do |**kwargs|
|
23
|
+
self.class.properties.each do |name, options|
|
24
|
+
raise ArgumentError, "#{name} required" if options[:required] && !kwargs[name]
|
25
|
+
|
26
|
+
value = kwargs.fetch(name, options[:default])
|
27
|
+
|
28
|
+
instance_variable_set("@#{name}", value)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_h
|
33
|
+
{}.tap do |hash|
|
34
|
+
self.class.properties.keys.each do |name|
|
35
|
+
value = instance_variable_get("@#{name}")
|
36
|
+
|
37
|
+
hash[name] = value unless value.nil?
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
const_set('Attributes', klass)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/concern'
|
4
|
+
|
5
|
+
module AppStoreConnect
|
6
|
+
module Object
|
7
|
+
module Data
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
attr_reader :data
|
12
|
+
|
13
|
+
klass = Class.new do |data|
|
14
|
+
include Object::Attributes
|
15
|
+
include Object::Type
|
16
|
+
|
17
|
+
data.define_method :initialize do |**kwargs|
|
18
|
+
instance_variable_set('@attributes', data::Attributes.new(kwargs))
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_h
|
22
|
+
{
|
23
|
+
attributes: attributes.to_h,
|
24
|
+
type: type
|
25
|
+
}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
const_set('Data', klass)
|
30
|
+
|
31
|
+
def to_h
|
32
|
+
{
|
33
|
+
data: data.to_h
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class_methods do
|
39
|
+
def data(&block)
|
40
|
+
self::Data.class_eval(&block)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/concern'
|
4
|
+
|
5
|
+
module AppStoreConnect
|
6
|
+
module Object
|
7
|
+
module Properties
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
class_methods do
|
11
|
+
def properties
|
12
|
+
@properties ||= {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def property(name, options = {})
|
16
|
+
properties[name] = options
|
17
|
+
|
18
|
+
attr_accessor name.to_sym
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/concern'
|
4
|
+
|
5
|
+
module AppStoreConnect
|
6
|
+
module Object
|
7
|
+
module Type
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
class_methods do
|
11
|
+
def type(type)
|
12
|
+
@type = type
|
13
|
+
|
14
|
+
const_set('TYPE', type)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
included do
|
19
|
+
def type
|
20
|
+
self.class.instance_variable_get('@type')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -2,12 +2,20 @@
|
|
2
2
|
|
3
3
|
module AppStoreConnect
|
4
4
|
class UserInvitationCreateRequest < Struct.new(:first_name, :last_name, :email, :roles)
|
5
|
+
def initialize(kwargs)
|
6
|
+
super(kwargs[:first_name], kwargs[:last_name], kwargs[:email], kwargs[:roles])
|
7
|
+
end
|
8
|
+
|
5
9
|
def body
|
6
10
|
{ 'data' =>
|
7
11
|
{ 'type' => 'userInvitations', 'attributes' =>
|
8
12
|
{ 'firstName' => first_name, 'lastName' => last_name, 'email' => email, 'roles' => roles, 'allAppsVisible' => true, 'provisioningAllowed' => true } } }
|
9
13
|
end
|
10
14
|
|
15
|
+
def to_h
|
16
|
+
body
|
17
|
+
end
|
18
|
+
|
11
19
|
def to_s
|
12
20
|
body.to_json
|
13
21
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AppStoreConnect
|
4
|
+
class WebServiceEndpoint
|
5
|
+
def initialize(**options)
|
6
|
+
@options = options
|
7
|
+
end
|
8
|
+
|
9
|
+
def http_method
|
10
|
+
@options[:http_method].to_sym
|
11
|
+
end
|
12
|
+
|
13
|
+
def http_body_type
|
14
|
+
@options[:http_body_type]
|
15
|
+
end
|
16
|
+
|
17
|
+
def url
|
18
|
+
@options[:url]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/app_store_connect.rb
CHANGED
@@ -5,6 +5,12 @@ require 'httparty'
|
|
5
5
|
|
6
6
|
require 'app_store_connect/authorization'
|
7
7
|
require 'app_store_connect/parser'
|
8
|
+
|
9
|
+
require 'app_store_connect/object/type'
|
10
|
+
require 'app_store_connect/object/attributes'
|
11
|
+
require 'app_store_connect/object/properties'
|
12
|
+
require 'app_store_connect/object/data'
|
13
|
+
require 'app_store_connect/create_request'
|
8
14
|
require 'app_store_connect/client'
|
9
15
|
require 'app_store_connect/bundle_id_create_request'
|
10
16
|
require 'app_store_connect/user_invitation_create_request'
|
@@ -21,4 +27,12 @@ module AppStoreConnect
|
|
21
27
|
Factory.register('enum', Factory::Builder::Enum)
|
22
28
|
|
23
29
|
Parser.parse!(Config::API)
|
30
|
+
|
31
|
+
@config = {}
|
32
|
+
|
33
|
+
class << self
|
34
|
+
attr_reader :config
|
35
|
+
|
36
|
+
attr_writer :config
|
37
|
+
end
|
24
38
|
end
|
data/lib/config/api.json
CHANGED
@@ -1,4 +1,48 @@
|
|
1
1
|
{
|
2
|
+
"web_service_endpoints": [
|
3
|
+
{
|
4
|
+
"alias": "apps",
|
5
|
+
"http_method": "get",
|
6
|
+
"url": "https://api.appstoreconnect.apple.com/v1/apps"
|
7
|
+
},
|
8
|
+
{
|
9
|
+
"alias": "app",
|
10
|
+
"http_method": "get",
|
11
|
+
"url": "https://api.appstoreconnect.apple.com/v1/apps/{id}"
|
12
|
+
},
|
13
|
+
{
|
14
|
+
"alias": "builds",
|
15
|
+
"http_method": "get",
|
16
|
+
"url": "https://api.appstoreconnect.apple.com/v1/apps/{id}/builds"
|
17
|
+
},
|
18
|
+
{
|
19
|
+
"alias": "build",
|
20
|
+
"http_method": "get",
|
21
|
+
"url": "https://api.appstoreconnect.apple.com/v1/builds/{id}"
|
22
|
+
},
|
23
|
+
{
|
24
|
+
"alias": "invite_user",
|
25
|
+
"url": "https://api.appstoreconnect.apple.com/v1/userInvitations",
|
26
|
+
"http_body_type": "UserInvitationCreateRequest",
|
27
|
+
"http_method": "post"
|
28
|
+
},
|
29
|
+
{
|
30
|
+
"alias": "create_bundle_id",
|
31
|
+
"url": "https://api.appstoreconnect.apple.com/v1/bundleIds",
|
32
|
+
"http_body_type": "BundleIdCreateRequest",
|
33
|
+
"http_method": "post"
|
34
|
+
},
|
35
|
+
{
|
36
|
+
"alias": "users",
|
37
|
+
"url": "https://api.appstoreconnect.apple.com/v1/users",
|
38
|
+
"http_method": "get"
|
39
|
+
},
|
40
|
+
{
|
41
|
+
"alias": "user_invitations",
|
42
|
+
"http_method": "get",
|
43
|
+
"url": "https://api.appstoreconnect.apple.com/v1/userInvitations"
|
44
|
+
}
|
45
|
+
],
|
2
46
|
"Type": {
|
3
47
|
"CapabilityType": {
|
4
48
|
"type": "enum",
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: app_store_connect
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kyle Decot
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-08-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -219,17 +219,21 @@ files:
|
|
219
219
|
- lib/app_store_connect.rb
|
220
220
|
- lib/app_store_connect/authorization.rb
|
221
221
|
- lib/app_store_connect/bundle_id_create_request.rb
|
222
|
-
- lib/app_store_connect/bundle_id_create_request/data.rb
|
223
|
-
- lib/app_store_connect/bundle_id_create_request/data/attributes.rb
|
224
222
|
- lib/app_store_connect/client.rb
|
225
223
|
- lib/app_store_connect/config.rb
|
224
|
+
- lib/app_store_connect/create_request.rb
|
226
225
|
- lib/app_store_connect/factory.rb
|
227
226
|
- lib/app_store_connect/factory/builder/enum.rb
|
227
|
+
- lib/app_store_connect/object/attributes.rb
|
228
|
+
- lib/app_store_connect/object/data.rb
|
229
|
+
- lib/app_store_connect/object/properties.rb
|
230
|
+
- lib/app_store_connect/object/type.rb
|
228
231
|
- lib/app_store_connect/parser.rb
|
229
232
|
- lib/app_store_connect/type.rb
|
230
233
|
- lib/app_store_connect/type/enum.rb
|
231
234
|
- lib/app_store_connect/user_invitation_create_request.rb
|
232
235
|
- lib/app_store_connect/version.rb
|
236
|
+
- lib/app_store_connect/web_service_endpoint.rb
|
233
237
|
- lib/config/api.json
|
234
238
|
homepage: https://github.com/kyledecot/app_store_connect
|
235
239
|
licenses:
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module AppStoreConnect
|
4
|
-
class BundleIdCreateRequest
|
5
|
-
class Data
|
6
|
-
class Attributes
|
7
|
-
attr_accessor :identifier, :name, :platform, :seed_id
|
8
|
-
|
9
|
-
def initialize(identifier:, name:, platform:, seed_id: nil)
|
10
|
-
self.identifier = identifier
|
11
|
-
self.name = name
|
12
|
-
self.platform = platform
|
13
|
-
self.seed_id = seed_id
|
14
|
-
end
|
15
|
-
|
16
|
-
def to_h
|
17
|
-
{
|
18
|
-
identifier: identifier,
|
19
|
-
name: name,
|
20
|
-
platform: platform
|
21
|
-
}.tap do |hash|
|
22
|
-
hash[:seed_id] = seed_id unless seed_id.nil?
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative './data/attributes'
|
4
|
-
|
5
|
-
module AppStoreConnect
|
6
|
-
class BundleIdCreateRequest
|
7
|
-
class Data
|
8
|
-
TYPE = 'bundleIds'
|
9
|
-
|
10
|
-
attr_reader :attributes
|
11
|
-
|
12
|
-
def initialize(*args)
|
13
|
-
@attributes = Attributes.new(*args)
|
14
|
-
end
|
15
|
-
|
16
|
-
def type
|
17
|
-
TYPE
|
18
|
-
end
|
19
|
-
|
20
|
-
def to_h
|
21
|
-
{
|
22
|
-
attributes: attributes.to_h,
|
23
|
-
type: type
|
24
|
-
}
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|