app_store_dev_api 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. checksums.yaml +7 -0
  2. data/.DS_Store +0 -0
  3. data/.gitignore +56 -0
  4. data/CHANGELOG.md +5 -0
  5. data/CODE_OF_CONDUCT.md +84 -0
  6. data/Gemfile +8 -0
  7. data/Gemfile.lock +198 -0
  8. data/LICENSE +21 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +39 -0
  11. data/Rakefile +4 -0
  12. data/app_store_dev_api.gemspec +54 -0
  13. data/bin/.DS_Store +0 -0
  14. data/bin/console +10 -0
  15. data/bin/setup +10 -0
  16. data/lib/.DS_Store +0 -0
  17. data/lib/app_store_dev_api/.DS_Store +0 -0
  18. data/lib/app_store_dev_api/base.rb +83 -0
  19. data/lib/app_store_dev_api/bundle_id_capability_create_request.rb +13 -0
  20. data/lib/app_store_dev_api/bundle_id_create_request.rb +16 -0
  21. data/lib/app_store_dev_api/certificate_create_request.rb +14 -0
  22. data/lib/app_store_dev_api/client/authorization.rb +38 -0
  23. data/lib/app_store_dev_api/client/builder.rb +91 -0
  24. data/lib/app_store_dev_api/client/options.rb +48 -0
  25. data/lib/app_store_dev_api/client/registry.rb +15 -0
  26. data/lib/app_store_dev_api/client/utils.rb +32 -0
  27. data/lib/app_store_dev_api/client.rb +66 -0
  28. data/lib/app_store_dev_api/device_create_request.rb +15 -0
  29. data/lib/app_store_dev_api/object/attributes.rb +47 -0
  30. data/lib/app_store_dev_api/object/data.rb +45 -0
  31. data/lib/app_store_dev_api/object/id.rb +28 -0
  32. data/lib/app_store_dev_api/object/included.rb +27 -0
  33. data/lib/app_store_dev_api/object/properties.rb +23 -0
  34. data/lib/app_store_dev_api/object/type.rb +23 -0
  35. data/lib/app_store_dev_api/profile_create_request.rb +14 -0
  36. data/lib/app_store_dev_api/request/body.rb +26 -0
  37. data/lib/app_store_dev_api/request/builder/create.rb +69 -0
  38. data/lib/app_store_dev_api/request.rb +93 -0
  39. data/lib/app_store_dev_api/requests/.DS_Store +0 -0
  40. data/lib/app_store_dev_api/requests/v1/.DS_Store +0 -0
  41. data/lib/app_store_dev_api/requests/v1/app/.DS_Store +0 -0
  42. data/lib/app_store_dev_api/requests/v1/app/update.rb +27 -0
  43. data/lib/app_store_dev_api/requests/v1/app_availability/.DS_Store +0 -0
  44. data/lib/app_store_dev_api/requests/v1/app_availability/update.rb +21 -0
  45. data/lib/app_store_dev_api/requests/v1/app_info/.DS_Store +0 -0
  46. data/lib/app_store_dev_api/requests/v1/app_info/update.rb +25 -0
  47. data/lib/app_store_dev_api/requests/v1/app_info_localization/create.rb +24 -0
  48. data/lib/app_store_dev_api/requests/v1/app_info_localization/update.rb +25 -0
  49. data/lib/app_store_dev_api/requests/v1/app_price_ schedule/.DS_Store +0 -0
  50. data/lib/app_store_dev_api/requests/v1/app_price_ schedule/update.rb +17 -0
  51. data/lib/app_store_dev_api/requests/v1/app_promoted_purchases/.DS_Store +0 -0
  52. data/lib/app_store_dev_api/requests/v1/app_promoted_purchases/update.rb +16 -0
  53. data/lib/app_store_dev_api/requests/v1/app_store_review_detail/create.rb +27 -0
  54. data/lib/app_store_dev_api/requests/v1/app_store_review_detail/update.rb +25 -0
  55. data/lib/app_store_dev_api/requests/v1/app_store_version/create.rb +23 -0
  56. data/lib/app_store_dev_api/requests/v1/app_store_version/update.rb +25 -0
  57. data/lib/app_store_dev_api/requests/v1/app_store_version_build_linkage_request/.DS_Store +0 -0
  58. data/lib/app_store_dev_api/requests/v1/app_store_version_build_linkage_request/update.rb +17 -0
  59. data/lib/app_store_dev_api/requests/v1/app_store_version_localization/create.rb +25 -0
  60. data/lib/app_store_dev_api/requests/v1/app_store_version_localization/update.rb +25 -0
  61. data/lib/app_store_dev_api/requests/v1/app_store_version_phased_releases/create.rb +20 -0
  62. data/lib/app_store_dev_api/requests/v1/app_store_version_phased_releases/update.rb +20 -0
  63. data/lib/app_store_dev_api/requests/v1/app_store_version_promotion/.DS_Store +0 -0
  64. data/lib/app_store_dev_api/requests/v1/app_store_version_promotion/create.rb +20 -0
  65. data/lib/app_store_dev_api/requests/v1/app_store_version_releases_request/.DS_Store +0 -0
  66. data/lib/app_store_dev_api/requests/v1/app_store_version_releases_request/create.rb +20 -0
  67. data/lib/app_store_dev_api/requests/v1/beta_build_localization/.DS_Store +0 -0
  68. data/lib/app_store_dev_api/requests/v1/beta_build_localization/create.rb +14 -0
  69. data/lib/app_store_dev_api/requests/v1/beta_build_localization/update.rb +13 -0
  70. data/lib/app_store_dev_api/requests/v1/builds/.DS_Store +0 -0
  71. data/lib/app_store_dev_api/requests/v1/builds/update.rb +21 -0
  72. data/lib/app_store_dev_api/requests/v1/customer_review_response/.DS_Store +0 -0
  73. data/lib/app_store_dev_api/requests/v1/customer_review_response/create.rb +19 -0
  74. data/lib/app_store_dev_api/requests/v1/in_app_purchase_ territory/.DS_Store +0 -0
  75. data/lib/app_store_dev_api/requests/v1/in_app_purchase_ territory/create.rb +19 -0
  76. data/lib/app_store_dev_api/requests/v1/in_app_purchase_localization/create.rb +21 -0
  77. data/lib/app_store_dev_api/requests/v1/in_app_purchase_localization/update.rb +21 -0
  78. data/lib/app_store_dev_api/requests/v1/in_app_purchase_price_schedule/create.rb +17 -0
  79. data/lib/app_store_dev_api/requests/v1/in_app_purchase_review_screenshot/create.rb +20 -0
  80. data/lib/app_store_dev_api/requests/v1/in_app_purchase_review_screenshot/update.rb +21 -0
  81. data/lib/app_store_dev_api/requests/v1/in_app_purchase_submission/create.rb +17 -0
  82. data/lib/app_store_dev_api/requests/v1/promoted_purchases/create.rb +20 -0
  83. data/lib/app_store_dev_api/requests/v1/promoted_purchases/update.rb +21 -0
  84. data/lib/app_store_dev_api/requests/v1/promoted_purchases_image/create.rb +20 -0
  85. data/lib/app_store_dev_api/requests/v1/promoted_purchases_image/update.rb +21 -0
  86. data/lib/app_store_dev_api/requests/v1/review_submission/.DS_Store +0 -0
  87. data/lib/app_store_dev_api/requests/v1/review_submission/create.rb +20 -0
  88. data/lib/app_store_dev_api/requests/v1/review_submission/update.rb +22 -0
  89. data/lib/app_store_dev_api/requests/v1/review_submission_item/.DS_Store +0 -0
  90. data/lib/app_store_dev_api/requests/v1/review_submission_item/create.rb +15 -0
  91. data/lib/app_store_dev_api/requests/v1/subscription/create.rb +25 -0
  92. data/lib/app_store_dev_api/requests/v1/subscription/update.rb +25 -0
  93. data/lib/app_store_dev_api/requests/v1/subscription_availability/.DS_Store +0 -0
  94. data/lib/app_store_dev_api/requests/v1/subscription_availability/create.rb +19 -0
  95. data/lib/app_store_dev_api/requests/v1/subscription_grace_period/.DS_Store +0 -0
  96. data/lib/app_store_dev_api/requests/v1/subscription_grace_period/update.rb +23 -0
  97. data/lib/app_store_dev_api/requests/v1/subscription_group/create.rb +20 -0
  98. data/lib/app_store_dev_api/requests/v1/subscription_group/update.rb +21 -0
  99. data/lib/app_store_dev_api/requests/v1/subscription_group_localization/create.rb +22 -0
  100. data/lib/app_store_dev_api/requests/v1/subscription_group_localization/update.rb +24 -0
  101. data/lib/app_store_dev_api/requests/v1/subscription_group_submission/.DS_Store +0 -0
  102. data/lib/app_store_dev_api/requests/v1/subscription_group_submission/create.rb +17 -0
  103. data/lib/app_store_dev_api/requests/v1/subscription_introductory_offer/create.rb +25 -0
  104. data/lib/app_store_dev_api/requests/v1/subscription_introductory_offer/update.rb +22 -0
  105. data/lib/app_store_dev_api/requests/v1/subscription_localization/create.rb +23 -0
  106. data/lib/app_store_dev_api/requests/v1/subscription_localization/update.rb +23 -0
  107. data/lib/app_store_dev_api/requests/v1/subscription_offer_code/create.rb +26 -0
  108. data/lib/app_store_dev_api/requests/v1/subscription_offer_code/update.rb +22 -0
  109. data/lib/app_store_dev_api/requests/v1/subscription_offer_code_cunstom_code/create.rb +23 -0
  110. data/lib/app_store_dev_api/requests/v1/subscription_offer_code_cunstom_code/update.rb +22 -0
  111. data/lib/app_store_dev_api/requests/v1/subscription_offer_code_one_time_use_code/create.rb +22 -0
  112. data/lib/app_store_dev_api/requests/v1/subscription_offer_code_one_time_use_code/update.rb +22 -0
  113. data/lib/app_store_dev_api/requests/v1/subscription_price/.DS_Store +0 -0
  114. data/lib/app_store_dev_api/requests/v1/subscription_price/create.rb +20 -0
  115. data/lib/app_store_dev_api/requests/v1/subscription_promotional_offer/create.rb +25 -0
  116. data/lib/app_store_dev_api/requests/v1/subscription_promotional_offer/update.rb +19 -0
  117. data/lib/app_store_dev_api/requests/v1/subscription_review_screenshot/create.rb +20 -0
  118. data/lib/app_store_dev_api/requests/v1/subscription_review_screenshot/update.rb +21 -0
  119. data/lib/app_store_dev_api/requests/v1/subscription_submission/.DS_Store +0 -0
  120. data/lib/app_store_dev_api/requests/v1/subscription_submission/create.rb +15 -0
  121. data/lib/app_store_dev_api/requests/v2/.DS_Store +0 -0
  122. data/lib/app_store_dev_api/requests/v2/in_app_purchase/create.rb +25 -0
  123. data/lib/app_store_dev_api/requests/v2/in_app_purchase/update.rb +23 -0
  124. data/lib/app_store_dev_api/requests/v2/sandbox_tester/.DS_Store +0 -0
  125. data/lib/app_store_dev_api/requests/v2/sandbox_tester/update.rb +22 -0
  126. data/lib/app_store_dev_api/requests/v2/sandbox_tester_clear_purchase_history/.DS_Store +0 -0
  127. data/lib/app_store_dev_api/requests/v2/sandbox_tester_clear_purchase_history/update.rb +16 -0
  128. data/lib/app_store_dev_api/schema/object.rb +14 -0
  129. data/lib/app_store_dev_api/schema/type.rb +15 -0
  130. data/lib/app_store_dev_api/schema/web_service_endpoint.rb +27 -0
  131. data/lib/app_store_dev_api/schema.rb +24 -0
  132. data/lib/app_store_dev_api/specification/component/schema.rb +25 -0
  133. data/lib/app_store_dev_api/specification.rb +54 -0
  134. data/lib/app_store_dev_api/user_invitation_create_request.rb +18 -0
  135. data/lib/app_store_dev_api/version.rb +5 -0
  136. data/lib/app_store_dev_api.rb +23 -0
  137. data/lib/config/schema.json +1650 -0
  138. data/lib/tasks/build.rake +8 -0
  139. data/lib/tasks/bundle.rake +7 -0
  140. data/lib/tasks/changelog.rake +17 -0
  141. data/lib/tasks/console.rake +9 -0
  142. data/lib/tasks/git.rake +19 -0
  143. data/lib/tasks/push.rake +18 -0
  144. data/lib/tasks/release.rake +17 -0
  145. data/lib/tasks/version.rake +28 -0
  146. data/sig/app_store_connect_api.rbs +4 -0
  147. metadata +429 -0
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jwt'
4
+
5
+ module AppStoreDevApi
6
+ class Client
7
+ class Authorization
8
+ OPTIONS = %i[key_id issuer_id private_key].freeze
9
+
10
+ AUDIENCE = 'appstoreconnect-v1'
11
+ ALGORITHM = 'ES256'
12
+
13
+ attr_reader(*OPTIONS)
14
+
15
+ def initialize(options)
16
+ @key_id = options.fetch(:key_id)
17
+ @issuer_id = options.fetch(:issuer_id)
18
+ @private_key = OpenSSL::PKey.read(options.fetch(:private_key))
19
+ end
20
+
21
+ def payload
22
+ {
23
+ exp: Time.now.to_i + 20 * 60,
24
+ iss: issuer_id,
25
+ aud: AUDIENCE
26
+ }
27
+ end
28
+
29
+ def header_fields
30
+ { kid: key_id }
31
+ end
32
+
33
+ def token
34
+ JWT.encode(payload, private_key, ALGORITHM, header_fields)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AppStoreDevApi
4
+ class Client
5
+ class Builder
6
+ TEMPLATE = <<~'SOURCE'
7
+ # frozen_string_literal: true
8
+
9
+ # WARNING ABOUT GENERATED CODE
10
+ #
11
+ # This file is generated.
12
+ #
13
+ # WARNING ABOUT GENERATED CODE
14
+
15
+ module AppStoreDevApi
16
+ class Client < Base
17
+ <%- web_service_endpoints.each do |web_service_endpoint| -%>
18
+ #
19
+ # @see <%= web_service_endpoint.delete(:see) %>
20
+ #
21
+ def <%= web_service_endpoint.delete(:alias) -%>(**kwargs)
22
+ web_service_endpoint = Schema::WebServiceEndpoint.new(
23
+ <%= web_service_endpoint.sort.to_h %>
24
+ )
25
+
26
+ call(web_service_endpoint, **kwargs)
27
+ end
28
+
29
+ <%- end -%>
30
+ end
31
+ end
32
+ SOURCE
33
+ private_constant :TEMPLATE
34
+
35
+ def web_service_endpoints
36
+ [
37
+ {
38
+ "alias": 'create_certificate',
39
+ "http_method": 'post',
40
+ "url": 'https://api.appstoreconnect.apple.com/v1/certificates',
41
+ "http_body_type": 'CertificateCreateRequest',
42
+ "see": 'https://developer.apple.com/documentation/AppStoreDevApi'
43
+ },
44
+ {
45
+ "http_method": 'delete',
46
+ "url": 'https://api.appstoreconnect.apple.com/v1/users/{id}/relationships/visibleApps',
47
+ "alias": 'delete_visible_app',
48
+ "see": 'https://developer.apple.com/documentation/AppStoreDevApi'
49
+ },
50
+ {
51
+ "alias": 'create_bundle_id',
52
+ "url": 'https://api.appstoreconnect.apple.com/v1/bundleIds',
53
+ "http_body_type": 'BundleIdCreateRequest',
54
+ "http_method": 'post',
55
+ "see": 'https://developer.apple.com/documentation/AppStoreDevApi/register_a_new_bundle_id'
56
+ },
57
+ {
58
+ "alias": 'create_bundle_id_capability',
59
+ "url": 'https://api.appstoreconnect.apple.com/v1/bundleIdCapabilities',
60
+ "http_body_type": 'BundleIdCapabilityCreateRequest',
61
+ "http_method": 'post',
62
+ "see": 'https://developer.apple.com/documentation/AppStoreDevApi'
63
+ },
64
+ {
65
+ "alias": 'create_beta_build_localization',
66
+ "url": 'https://api.appstoreconnect.apple.com/v1/betaBuildLocalizations',
67
+ "http_body_type": 'BetaBuildLocalizationCreateRequest',
68
+ "http_method": 'post',
69
+ "see": 'https://developer.apple.com/documentation/AppStoreDevApi'
70
+ }
71
+ ].map(&:symbolize_keys)
72
+ end
73
+
74
+ def write
75
+ File.write('lib/app_store_dev_api/client.rb', source)
76
+ end
77
+
78
+ def source
79
+ @source ||= begin
80
+ require 'erb'
81
+
82
+ erb = ERB.new(TEMPLATE, trim_mode: '%-')
83
+
84
+ erb.result(binding)
85
+ end
86
+
87
+ @source
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'delegate'
4
+
5
+ module AppStoreDevApi
6
+ class Client
7
+ class Options < SimpleDelegator
8
+ attr_reader :kwargs, :config, :env
9
+
10
+ DEFAULTS = {
11
+ analytics_enabled: true,
12
+ schema: Schema.new(File.join(__dir__, '..', '..', 'config', 'schema.json'))
13
+ }.freeze
14
+ private_constant :DEFAULTS
15
+
16
+ ENV_REGEXP = /APP_STORE_CONNECT_(?<suffix>[A-Z_]+)/.freeze
17
+ private_constant :ENV_REGEXP
18
+
19
+ def initialize(kwargs = {})
20
+ @kwargs = kwargs
21
+ @config = build_config
22
+ @env = build_env
23
+
24
+ options = DEFAULTS.merge(@env.merge(@config.merge(kwargs)))
25
+
26
+ super(options)
27
+ end
28
+
29
+ private
30
+
31
+ def build_config
32
+ AppStoreDevApi.config.dup
33
+ end
34
+
35
+ def build_env
36
+ {}.tap do |hash|
37
+ ENV.each do |key, value|
38
+ match = key.match(ENV_REGEXP)
39
+
40
+ next unless match
41
+
42
+ hash[match[:suffix].downcase.to_sym] = value
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'delegate'
4
+
5
+ module AppStoreDevApi
6
+ class Client
7
+ class Registry < SimpleDelegator
8
+ OPTIONS = %i[schema].freeze
9
+
10
+ def initialize(options = {})
11
+ super(options.fetch(:schema).web_service_endpoints.map { |s| [s.alias, s] }.to_h)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AppStoreDevApi
4
+ class Client
5
+ class Utils
6
+ def self.encode(hash)
7
+ hash
8
+ .deep_transform_keys { |s| s.to_s.camelize(:lower) }
9
+ .to_json
10
+ end
11
+
12
+ # Right now this only supports gzip and json responses.
13
+ # If you need to support a different type then add it.
14
+ def self.decode(string, content_type = 'application/json')
15
+ decoded_data = nil
16
+
17
+ case content_type
18
+ when 'application/a-gzip'
19
+ sio = StringIO.new string
20
+ gz = Zlib::GzipReader.new sio
21
+ decoded_data = gz.read
22
+ else # Assume JSON
23
+ decoded_data = JSON
24
+ .parse(string)
25
+ .deep_transform_keys { |k| k.underscore.to_sym }
26
+ end
27
+
28
+ decoded_data
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ # WARNING ABOUT GENERATED CODE
4
+ #
5
+ # This file is generated.
6
+ #
7
+ # WARNING ABOUT GENERATED CODE
8
+
9
+ module AppStoreDevApi
10
+ class Client < Base
11
+ #
12
+ # @see https://developer.apple.com/documentation/AppStoreDevApi
13
+ #
14
+ def create_certificate(**kwargs)
15
+ web_service_endpoint = Schema::WebServiceEndpoint.new(
16
+ { http_body_type: 'CertificateCreateRequest', http_method: 'post', url: 'https://api.appstoreconnect.apple.com/v1/certificates' }
17
+ )
18
+
19
+ call(web_service_endpoint, **kwargs)
20
+ end
21
+
22
+ #
23
+ # @see https://developer.apple.com/documentation/AppStoreDevApi
24
+ #
25
+ def delete_visible_app(**kwargs)
26
+ web_service_endpoint = Schema::WebServiceEndpoint.new(
27
+ { http_method: 'delete', url: 'https://api.appstoreconnect.apple.com/v1/users/{id}/relationships/visibleApps' }
28
+ )
29
+
30
+ call(web_service_endpoint, **kwargs)
31
+ end
32
+
33
+ #
34
+ # @see https://developer.apple.com/documentation/AppStoreDevApi/register_a_new_bundle_id
35
+ #
36
+ def create_bundle_id(**kwargs)
37
+ web_service_endpoint = Schema::WebServiceEndpoint.new(
38
+ { http_body_type: 'BundleIdCreateRequest', http_method: 'post', url: 'https://api.appstoreconnect.apple.com/v1/bundleIds' }
39
+ )
40
+
41
+ call(web_service_endpoint, **kwargs)
42
+ end
43
+
44
+ #
45
+ # @see https://developer.apple.com/documentation/AppStoreDevApi
46
+ #
47
+ def create_bundle_id_capability(**kwargs)
48
+ web_service_endpoint = Schema::WebServiceEndpoint.new(
49
+ { http_body_type: 'BundleIdCapabilityCreateRequest', http_method: 'post', url: 'https://api.appstoreconnect.apple.com/v1/bundleIdCapabilities' }
50
+ )
51
+
52
+ call(web_service_endpoint, **kwargs)
53
+ end
54
+
55
+ #
56
+ # @see https://developer.apple.com/documentation/AppStoreDevApi
57
+ #
58
+ def create_beta_build_localization(**kwargs)
59
+ web_service_endpoint = Schema::WebServiceEndpoint.new(
60
+ { http_body_type: 'BetaBuildLocalizationCreateRequest', http_method: 'post', url: 'https://api.appstoreconnect.apple.com/v1/betaBuildLocalizations' }
61
+ )
62
+
63
+ call(web_service_endpoint, **kwargs)
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AppStoreDevApi
4
+ class DeviceCreateRequest < Request::Body
5
+ data do
6
+ type 'devices'
7
+
8
+ attributes do
9
+ property :name, required: true
10
+ property :platform, required: true
11
+ property :udid, required: true
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern'
4
+
5
+ module AppStoreDevApi
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.send(: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.each_key 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 AppStoreDevApi
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
+ include Object::Id
17
+
18
+ data.send(:define_method, :initialize) do |**kwargs|
19
+ instance_variable_set('@relationships', kwargs.delete(:relationships).to_h)
20
+ instance_variable_set('@attributes', data::Attributes.new(**kwargs))
21
+ instance_variable_set('@id', kwargs[id_arg_name])
22
+ end
23
+
24
+ def to_h
25
+ props = {
26
+ relationships: @relationships,
27
+ attributes: attributes.to_h,
28
+ type: type
29
+ }
30
+ props[:id] = @id if id?
31
+ props.reject { |_k, v| v.blank? }
32
+ end
33
+ end
34
+
35
+ const_set('Data', klass)
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,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern'
4
+
5
+ module AppStoreDevApi
6
+ module Object
7
+ module Id
8
+ extend ActiveSupport::Concern
9
+
10
+ class_methods do
11
+ def id(arg_name = :id)
12
+ @include_id_in_body = true
13
+ @id_arg_name = arg_name
14
+ end
15
+ end
16
+
17
+ included do
18
+ def id?
19
+ self.class.instance_variable_get('@include_id_in_body')
20
+ end
21
+
22
+ def id_arg_name
23
+ self.class.instance_variable_get('@id_arg_name')
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern'
4
+
5
+ module AppStoreDevApi
6
+ module Object
7
+ module Included
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ attr_reader :included
12
+
13
+ klass = Class.new do |i|
14
+ i.send(:define_method, :initialize) do |objects|
15
+ instance_variable_set('@objects', [*objects])
16
+ end
17
+
18
+ def to_a
19
+ @objects
20
+ end
21
+ end
22
+
23
+ const_set('Included', klass)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern'
4
+
5
+ module AppStoreDevApi
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,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern'
4
+
5
+ module AppStoreDevApi
6
+ module Object
7
+ module Type
8
+ extend ActiveSupport::Concern
9
+
10
+ class_methods do
11
+ def type(type)
12
+ @type = type
13
+ end
14
+ end
15
+
16
+ included do
17
+ def type
18
+ self.class.instance_variable_get('@type')
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AppStoreDevApi
4
+ class ProfileCreateRequest < Request::Body
5
+ data do
6
+ type 'profiles'
7
+
8
+ attributes do
9
+ property :name, required: true
10
+ property :profile_type, required: true
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AppStoreDevApi
4
+ class Request
5
+ class Body
6
+ def self.inherited(klass)
7
+ super
8
+
9
+ klass.include(Object::Included)
10
+ klass.include(Object::Data)
11
+ end
12
+
13
+ def initialize(**kwargs)
14
+ @included = self.class::Included.new([*kwargs.delete(:included)])
15
+ @data = self.class::Data.new(**kwargs)
16
+ end
17
+
18
+ def to_h
19
+ {
20
+ data: data.to_h,
21
+ included: included.to_a
22
+ }
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/inflector'
4
+
5
+ module AppStoreDevApi
6
+ class Request
7
+ module Builder
8
+ class Create
9
+ TEMPLATE = <<~SOURCE
10
+ class <%= name %>CreateRequest < Request::Body
11
+ data do
12
+ type '<%= type %>'
13
+
14
+ <%- if properties.any? -%>
15
+ attributes do
16
+ <%- properties.each do |property| -%>
17
+ property :<%= property %>
18
+ <%- end -%>
19
+ end
20
+ <%- end -%>
21
+ end
22
+ end
23
+ SOURCE
24
+ private_constant :TEMPLATE
25
+
26
+ attr_reader :name, :type, :properties
27
+
28
+ def self.from(schema)
29
+ type = schema.properties['data']['properties']['type']['enum'][0]
30
+ properties = schema.properties['data']['properties']['attributes']['properties'].keys
31
+
32
+ new(type, properties)
33
+ end
34
+
35
+ def initialize(type, properties, version = 'v1')
36
+ @name = type.singularize.classify
37
+ @name = name
38
+ @type = type
39
+ @properties = properties
40
+ @version = version
41
+ end
42
+
43
+ def source
44
+ @source ||= begin
45
+ require 'erb'
46
+
47
+ erb = ERB.new(TEMPLATE, trim_mode: '%<>-')
48
+
49
+ erb.result(binding)
50
+ end
51
+
52
+ @source
53
+ end
54
+
55
+ def alias
56
+ "create_#{@type.underscore.singularize}"
57
+ end
58
+
59
+ def url
60
+ "https://api.appstoreconnect.apple.com/#{@version}/#{@type}"
61
+ end
62
+
63
+ def http_method
64
+ 'post'
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end