1use crate::{profile_api::ProfilesResponse, AppStoreConnectClient, Result};
8use serde::{Deserialize, Serialize};
9
10const APPLE_BUNDLE_IDS_URL: &str = "https://api.appstoreconnect.apple.com/v1/bundleIds";
11const APPLE_BUNDLE_CAPABILITIES_URL: &str =
12 "https://api.appstoreconnect.apple.com/v1/bundleIdCapabilities";
13
14impl AppStoreConnectClient {
15 pub fn register_bundle_id(&self, identifier: &str, name: &str) -> Result<BundleIdResponse> {
16 let token = self.get_token()?;
17 let body = BundleIdCreateRequest {
18 data: BundleIdCreateRequestData {
19 attributes: BundleIdCreateRequestAttributes {
20 identifier: identifier.into(),
21 name: name.into(),
22 platform: "UNIVERSAL".into(),
23 },
24 r#type: "bundleIds".into(),
25 },
26 };
27 let req = self
28 .client
29 .post(APPLE_BUNDLE_IDS_URL)
30 .bearer_auth(token)
31 .header("Accept", "application/json")
32 .header("Content-Type", "application/json")
33 .json(&body);
34 Ok(self.send_request(req)?.json()?)
35 }
36
37 pub fn list_bundle_ids(&self) -> Result<BundleIdsResponse> {
38 let token = self.get_token()?;
39 let req = self
40 .client
41 .get(APPLE_BUNDLE_IDS_URL)
42 .bearer_auth(token)
43 .header("Accept", "application/json");
44 Ok(self.send_request(req)?.json()?)
45 }
46
47 pub fn get_bundle_id(&self, id: &str) -> Result<BundleIdResponse> {
48 let token = self.get_token()?;
49 let req = self
50 .client
51 .get(format!("{APPLE_BUNDLE_IDS_URL}/{id}"))
52 .bearer_auth(token)
53 .header("Accept", "application/json");
54 Ok(self.send_request(req)?.json()?)
55 }
56
57 pub fn list_bundle_profiles(&self, id: &str) -> Result<ProfilesResponse> {
58 let token = self.get_token()?;
59 let req = self
60 .client
61 .get(format!("{APPLE_BUNDLE_IDS_URL}/{id}/profiles"))
62 .bearer_auth(token)
63 .header("Accept", "application/json");
64 Ok(self.send_request(req)?.json()?)
65 }
66
67 pub fn list_bundle_capabilities(&self, id: &str) -> Result<BundleCapabilitiesResponse> {
68 let token = self.get_token()?;
69 let req = self
70 .client
71 .get(format!("{APPLE_BUNDLE_IDS_URL}/{id}/bundleIdCapabilities"))
72 .bearer_auth(token)
73 .header("Accept", "application/json");
74 Ok(self.send_request(req)?.json()?)
75 }
76
77 pub fn enable_bundle_id_capability(
78 &self,
79 id: &str,
80 capability: BundleIdCapabilityCreateRequestDataAttributes,
81 ) -> Result<()> {
82 let token = self.get_token()?;
83
84 let body = BundleIdCapabilityCreateRequest {
85 data: BundleIdCapabilityCreateRequestData {
86 attributes: capability,
87 relationships: BundleIdCapabilityCreateRequestDataRelationships {
88 bundle_id: BundleIdCapabilityCreateRequestDataRelationshipBundleId {
89 data: BundleIdCapabilityCreateRequestDataRelationshipBundleIdData {
90 id: id.to_string(),
91 r#type: "bundleIds".to_string(),
92 },
93 },
94 },
95 r#type: "bundleIdCapabilities".to_string(),
96 },
97 };
98
99 let req = self
100 .client
101 .post(APPLE_BUNDLE_CAPABILITIES_URL)
102 .bearer_auth(token)
103 .header("Accept", "application/json")
104 .json(&body);
105 self.send_request(req)?;
106 Ok(())
107 }
108
109 pub fn delete_bundle_id(&self, id: &str) -> Result<()> {
110 let token = self.get_token()?;
111 let req = self
112 .client
113 .delete(format!("{APPLE_BUNDLE_IDS_URL}/{id}"))
114 .bearer_auth(token);
115 self.send_request(req)?;
116 Ok(())
117 }
118}
119
120#[derive(Debug, Serialize)]
121#[serde(rename_all = "camelCase")]
122pub struct BundleIdCreateRequest {
123 pub data: BundleIdCreateRequestData,
124}
125
126#[derive(Debug, Serialize)]
127#[serde(rename_all = "camelCase")]
128pub struct BundleIdCreateRequestData {
129 pub attributes: BundleIdCreateRequestAttributes,
130 pub r#type: String,
131}
132
133#[derive(Debug, Serialize)]
134#[serde(rename_all = "camelCase")]
135pub struct BundleIdCreateRequestAttributes {
136 pub identifier: String,
137 pub name: String,
138 pub platform: String,
139}
140
141#[derive(Clone, Copy, Debug, Eq, PartialEq, clap::ValueEnum)]
142pub enum BundleIdPlatform {
143 Ios,
144 MacOs,
145}
146
147impl std::fmt::Display for BundleIdPlatform {
148 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
149 let s = match self {
150 Self::Ios => "IOS",
151 Self::MacOs => "MAC_OS",
152 };
153 write!(f, "{s}")
154 }
155}
156
157#[derive(Debug, Deserialize)]
158#[serde(rename_all = "camelCase")]
159pub struct BundleIdResponse {
160 pub data: BundleId,
161}
162
163#[derive(Debug, Deserialize)]
164#[serde(rename_all = "camelCase")]
165pub struct BundleIdsResponse {
166 pub data: Vec<BundleId>,
167}
168
169#[derive(Debug, Deserialize)]
170#[serde(rename_all = "camelCase")]
171pub struct BundleId {
172 pub attributes: BundleIdAttributes,
173 pub id: String,
174}
175
176#[derive(Debug, Deserialize)]
177#[serde(rename_all = "camelCase")]
178pub struct BundleIdAttributes {
179 pub identifier: String,
180 pub name: String,
181 pub platform: String,
182 pub seed_id: String,
183}
184
185#[derive(Debug, Deserialize)]
186pub struct BundleCapabilitiesResponse {
187 pub data: Vec<BundleCapability>,
188}
189
190#[derive(Debug, Deserialize)]
191pub struct BundleCapability {
192 pub attributes: BundleCapabilityAttributes,
193 pub id: String,
194}
195
196#[derive(Debug, Deserialize, Serialize)]
197#[serde(rename_all = "camelCase")]
198pub struct BundleCapabilityAttributes {
199 pub capability_type: String,
200}
201
202#[derive(Debug, Serialize)]
203#[serde(rename_all = "camelCase")]
204pub struct BundleIdCapabilityCreateRequest {
205 data: BundleIdCapabilityCreateRequestData,
206}
207
208#[derive(Debug, Serialize)]
209#[serde(rename_all = "camelCase")]
210pub struct BundleIdCapabilityCreateRequestData {
211 attributes: BundleIdCapabilityCreateRequestDataAttributes,
212 relationships: BundleIdCapabilityCreateRequestDataRelationships,
213 r#type: String,
214}
215
216#[derive(Debug, Serialize)]
217#[serde(rename_all = "camelCase")]
218pub struct BundleIdCapabilityCreateRequestDataAttributes {
219 pub capability_type: String,
220}
221
222#[derive(Debug, Serialize)]
223#[serde(rename_all = "camelCase")]
224pub struct BundleIdCapabilityCreateRequestDataRelationships {
225 bundle_id: BundleIdCapabilityCreateRequestDataRelationshipBundleId,
226}
227
228#[derive(Debug, Serialize)]
229#[serde(rename_all = "camelCase")]
230pub struct BundleIdCapabilityCreateRequestDataRelationshipBundleId {
231 data: BundleIdCapabilityCreateRequestDataRelationshipBundleIdData,
232}
233
234#[derive(Debug, Serialize)]
235#[serde(rename_all = "camelCase")]
236pub struct BundleIdCapabilityCreateRequestDataRelationshipBundleIdData {
237 id: String,
238 r#type: String,
239}