app_store_dev_api 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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