@onmyway133/asc-cli 1.0.2 → 1.0.3
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.
- package/README.md +12 -80
- package/dist/index.js +164 -156
- package/docs/DEVELOPMENT.md +112 -0
- package/package.json +1 -1
- package/src/commands/app-info.ts +32 -34
- package/src/commands/apps.ts +17 -14
- package/src/commands/availability.ts +17 -16
- package/src/commands/beta-review.ts +51 -61
- package/src/commands/builds.ts +37 -29
- package/src/commands/game-center.ts +56 -55
- package/src/commands/iap.ts +47 -53
- package/src/commands/localizations.ts +83 -0
- package/src/commands/metadata.ts +25 -18
- package/src/commands/phased-release.ts +85 -0
- package/src/commands/pricing.ts +34 -30
- package/src/commands/reports.ts +13 -10
- package/src/commands/review-details.ts +79 -0
- package/src/commands/review-submission.ts +143 -0
- package/src/commands/reviews.ts +36 -30
- package/src/commands/screenshots.ts +40 -51
- package/src/commands/signing.ts +80 -100
- package/src/commands/subscriptions.ts +55 -63
- package/src/commands/testflight.ts +34 -23
- package/src/commands/versions.ts +40 -18
- package/src/commands/xcode-cloud.ts +68 -65
- package/src/index.ts +313 -1
package/src/commands/signing.ts
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
certificatesGetCollection,
|
|
3
|
+
certificatesGetInstance,
|
|
4
|
+
certificatesDeleteInstance,
|
|
5
|
+
devicesGetCollection,
|
|
6
|
+
devicesCreateInstance,
|
|
7
|
+
bundleIdsGetCollection,
|
|
8
|
+
bundleIdsCreateInstance,
|
|
9
|
+
profilesGetCollection,
|
|
10
|
+
profilesDeleteInstance,
|
|
11
|
+
} from "../api/generated/sdk.gen.ts"
|
|
12
|
+
import { throwOnError } from "../api/client.ts"
|
|
2
13
|
import { detectFormat, formatDate, printJSON, printSuccess, printTable } from "../utils/output.ts"
|
|
3
14
|
|
|
4
15
|
// ---- Certificates ----
|
|
@@ -7,62 +18,45 @@ export async function certificatesList(opts: {
|
|
|
7
18
|
type?: string
|
|
8
19
|
output?: string
|
|
9
20
|
} = {}): Promise<void> {
|
|
10
|
-
const
|
|
11
|
-
"fields[certificates]": "certificateType,displayName,expirationDate,serialNumber,platform",
|
|
21
|
+
const query: Record<string, unknown> = {
|
|
22
|
+
"fields[certificates]": ["certificateType", "displayName", "expirationDate", "serialNumber", "platform"],
|
|
12
23
|
}
|
|
13
|
-
if (opts.type)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
displayName?: string
|
|
19
|
-
expirationDate?: string
|
|
20
|
-
serialNumber?: string
|
|
21
|
-
platform?: string
|
|
22
|
-
}
|
|
23
|
-
}>("/v1/certificates", { params })
|
|
24
|
+
if (opts.type) query["filter[certificateType]"] = [opts.type]
|
|
25
|
+
|
|
26
|
+
const result = await certificatesGetCollection({ query: query as never })
|
|
27
|
+
const data = throwOnError(result)
|
|
28
|
+
const items = data.data
|
|
24
29
|
const fmt = detectFormat(opts.output)
|
|
25
30
|
if (fmt === "json") { printJSON(items); return }
|
|
26
31
|
printTable(
|
|
27
32
|
["ID", "Name", "Type", "Expires", "Serial"],
|
|
28
33
|
items.map(c => [
|
|
29
34
|
c.id,
|
|
30
|
-
c.attributes
|
|
31
|
-
c.attributes
|
|
32
|
-
formatDate(c.attributes
|
|
33
|
-
c.attributes
|
|
35
|
+
c.attributes?.displayName ?? "-",
|
|
36
|
+
c.attributes?.certificateType ?? "-",
|
|
37
|
+
formatDate(c.attributes?.expirationDate ?? ""),
|
|
38
|
+
c.attributes?.serialNumber ?? "-",
|
|
34
39
|
]),
|
|
35
40
|
`Certificates (${items.length})`,
|
|
36
41
|
)
|
|
37
42
|
}
|
|
38
43
|
|
|
39
44
|
export async function certificateGet(certId: string, opts: { output?: string } = {}): Promise<void> {
|
|
40
|
-
const result = await
|
|
41
|
-
|
|
42
|
-
id: string
|
|
43
|
-
attributes: {
|
|
44
|
-
certificateType?: string
|
|
45
|
-
displayName?: string
|
|
46
|
-
expirationDate?: string
|
|
47
|
-
serialNumber?: string
|
|
48
|
-
platform?: string
|
|
49
|
-
certificateContent?: string
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}>(`/v1/certificates/${certId}`)
|
|
45
|
+
const result = await certificatesGetInstance({ path: { id: certId } })
|
|
46
|
+
const data = throwOnError(result)
|
|
53
47
|
const fmt = detectFormat(opts.output)
|
|
54
|
-
if (fmt === "json") { printJSON(
|
|
55
|
-
const a =
|
|
56
|
-
console.log(`ID: ${
|
|
57
|
-
console.log(`Name: ${a
|
|
58
|
-
console.log(`Type: ${a
|
|
59
|
-
console.log(`Expires: ${formatDate(a
|
|
60
|
-
console.log(`Serial: ${a
|
|
61
|
-
console.log(`Platform: ${a
|
|
48
|
+
if (fmt === "json") { printJSON(data.data); return }
|
|
49
|
+
const a = data.data.attributes
|
|
50
|
+
console.log(`ID: ${data.data.id}`)
|
|
51
|
+
console.log(`Name: ${a?.displayName ?? "-"}`)
|
|
52
|
+
console.log(`Type: ${a?.certificateType ?? "-"}`)
|
|
53
|
+
console.log(`Expires: ${formatDate(a?.expirationDate ?? "")}`)
|
|
54
|
+
console.log(`Serial: ${a?.serialNumber ?? "-"}`)
|
|
55
|
+
console.log(`Platform: ${a?.platform ?? "-"}`)
|
|
62
56
|
}
|
|
63
57
|
|
|
64
58
|
export async function certificateRevoke(certId: string): Promise<void> {
|
|
65
|
-
await
|
|
59
|
+
await certificatesDeleteInstance({ path: { id: certId } })
|
|
66
60
|
printSuccess(`Certificate ${certId} revoked`)
|
|
67
61
|
}
|
|
68
62
|
|
|
@@ -73,34 +67,26 @@ export async function devicesList(opts: {
|
|
|
73
67
|
status?: string
|
|
74
68
|
output?: string
|
|
75
69
|
} = {}): Promise<void> {
|
|
76
|
-
const
|
|
77
|
-
"fields[devices]": "name,deviceClass,model,udid,platform,status,addedDate",
|
|
70
|
+
const query: Record<string, unknown> = {
|
|
71
|
+
"fields[devices]": ["name", "deviceClass", "model", "udid", "platform", "status", "addedDate"],
|
|
78
72
|
}
|
|
79
|
-
if (opts.platform)
|
|
80
|
-
if (opts.status)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
deviceClass?: string
|
|
86
|
-
model?: string
|
|
87
|
-
udid?: string
|
|
88
|
-
platform?: string
|
|
89
|
-
status?: string
|
|
90
|
-
addedDate?: string
|
|
91
|
-
}
|
|
92
|
-
}>("/v1/devices", { params })
|
|
73
|
+
if (opts.platform) query["filter[platform]"] = [opts.platform]
|
|
74
|
+
if (opts.status) query["filter[status]"] = [opts.status]
|
|
75
|
+
|
|
76
|
+
const result = await devicesGetCollection({ query: query as never })
|
|
77
|
+
const data = throwOnError(result)
|
|
78
|
+
const items = data.data
|
|
93
79
|
const fmt = detectFormat(opts.output)
|
|
94
80
|
if (fmt === "json") { printJSON(items); return }
|
|
95
81
|
printTable(
|
|
96
82
|
["ID", "Name", "Model", "Platform", "Status", "UDID"],
|
|
97
83
|
items.map(d => [
|
|
98
84
|
d.id,
|
|
99
|
-
d.attributes
|
|
100
|
-
d.attributes
|
|
101
|
-
d.attributes
|
|
102
|
-
d.attributes
|
|
103
|
-
d.attributes
|
|
85
|
+
d.attributes?.name ?? "-",
|
|
86
|
+
d.attributes?.model ?? d.attributes?.deviceClass ?? "-",
|
|
87
|
+
d.attributes?.platform ?? "-",
|
|
88
|
+
d.attributes?.status ?? "-",
|
|
89
|
+
d.attributes?.udid ?? "-",
|
|
104
90
|
]),
|
|
105
91
|
`Devices (${items.length})`,
|
|
106
92
|
)
|
|
@@ -111,16 +97,16 @@ export async function deviceRegister(opts: {
|
|
|
111
97
|
udid: string
|
|
112
98
|
platform: string
|
|
113
99
|
}): Promise<void> {
|
|
114
|
-
const result = await
|
|
115
|
-
method: "POST",
|
|
100
|
+
const result = await devicesCreateInstance({
|
|
116
101
|
body: {
|
|
117
102
|
data: {
|
|
118
103
|
type: "devices",
|
|
119
|
-
attributes: { name: opts.name, udid: opts.udid, platform: opts.platform },
|
|
104
|
+
attributes: { name: opts.name, udid: opts.udid, platform: opts.platform as never },
|
|
120
105
|
},
|
|
121
106
|
},
|
|
122
107
|
})
|
|
123
|
-
|
|
108
|
+
const data = throwOnError(result)
|
|
109
|
+
printSuccess(`Device registered: ${data.data.id} (${opts.udid})`)
|
|
124
110
|
}
|
|
125
111
|
|
|
126
112
|
// ---- Bundle IDs ----
|
|
@@ -130,25 +116,25 @@ export async function bundleIdsList(opts: {
|
|
|
130
116
|
identifier?: string
|
|
131
117
|
output?: string
|
|
132
118
|
} = {}): Promise<void> {
|
|
133
|
-
const
|
|
134
|
-
"fields[bundleIds]": "name,identifier,platform,seedId",
|
|
119
|
+
const query: Record<string, unknown> = {
|
|
120
|
+
"fields[bundleIds]": ["name", "identifier", "platform", "seedId"],
|
|
135
121
|
}
|
|
136
|
-
if (opts.platform)
|
|
137
|
-
if (opts.identifier)
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
122
|
+
if (opts.platform) query["filter[platform]"] = [opts.platform]
|
|
123
|
+
if (opts.identifier) query["filter[identifier]"] = [opts.identifier]
|
|
124
|
+
|
|
125
|
+
const result = await bundleIdsGetCollection({ query: query as never })
|
|
126
|
+
const data = throwOnError(result)
|
|
127
|
+
const items = data.data
|
|
142
128
|
const fmt = detectFormat(opts.output)
|
|
143
129
|
if (fmt === "json") { printJSON(items); return }
|
|
144
130
|
printTable(
|
|
145
131
|
["ID", "Name", "Identifier", "Platform", "Seed ID"],
|
|
146
132
|
items.map(b => [
|
|
147
133
|
b.id,
|
|
148
|
-
b.attributes
|
|
149
|
-
b.attributes
|
|
150
|
-
b.attributes
|
|
151
|
-
b.attributes
|
|
134
|
+
b.attributes?.name ?? "-",
|
|
135
|
+
b.attributes?.identifier ?? "-",
|
|
136
|
+
b.attributes?.platform ?? "-",
|
|
137
|
+
b.attributes?.seedId ?? "-",
|
|
152
138
|
]),
|
|
153
139
|
`Bundle IDs (${items.length})`,
|
|
154
140
|
)
|
|
@@ -159,16 +145,16 @@ export async function bundleIdRegister(opts: {
|
|
|
159
145
|
identifier: string
|
|
160
146
|
platform: string
|
|
161
147
|
}): Promise<void> {
|
|
162
|
-
const result = await
|
|
163
|
-
method: "POST",
|
|
148
|
+
const result = await bundleIdsCreateInstance({
|
|
164
149
|
body: {
|
|
165
150
|
data: {
|
|
166
151
|
type: "bundleIds",
|
|
167
|
-
attributes: { name: opts.name, identifier: opts.identifier, platform: opts.platform },
|
|
152
|
+
attributes: { name: opts.name, identifier: opts.identifier, platform: opts.platform as never },
|
|
168
153
|
},
|
|
169
154
|
},
|
|
170
155
|
})
|
|
171
|
-
|
|
156
|
+
const data = throwOnError(result)
|
|
157
|
+
printSuccess(`Bundle ID registered: ${data.data.id} (${opts.identifier})`)
|
|
172
158
|
}
|
|
173
159
|
|
|
174
160
|
// ---- Provisioning Profiles ----
|
|
@@ -178,37 +164,31 @@ export async function profilesList(opts: {
|
|
|
178
164
|
name?: string
|
|
179
165
|
output?: string
|
|
180
166
|
} = {}): Promise<void> {
|
|
181
|
-
const
|
|
182
|
-
"fields[profiles]": "name,profileType,profileState,expirationDate,uuid",
|
|
167
|
+
const query: Record<string, unknown> = {
|
|
168
|
+
"fields[profiles]": ["name", "profileType", "profileState", "expirationDate", "uuid"],
|
|
183
169
|
}
|
|
184
|
-
if (opts.type)
|
|
185
|
-
if (opts.name)
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
profileType?: string
|
|
191
|
-
profileState?: string
|
|
192
|
-
expirationDate?: string
|
|
193
|
-
uuid?: string
|
|
194
|
-
}
|
|
195
|
-
}>("/v1/profiles", { params })
|
|
170
|
+
if (opts.type) query["filter[profileType]"] = [opts.type]
|
|
171
|
+
if (opts.name) query["filter[name]"] = [opts.name]
|
|
172
|
+
|
|
173
|
+
const result = await profilesGetCollection({ query: query as never })
|
|
174
|
+
const data = throwOnError(result)
|
|
175
|
+
const items = data.data
|
|
196
176
|
const fmt = detectFormat(opts.output)
|
|
197
177
|
if (fmt === "json") { printJSON(items); return }
|
|
198
178
|
printTable(
|
|
199
179
|
["ID", "Name", "Type", "State", "Expires"],
|
|
200
180
|
items.map(p => [
|
|
201
181
|
p.id,
|
|
202
|
-
p.attributes
|
|
203
|
-
p.attributes
|
|
204
|
-
p.attributes
|
|
205
|
-
formatDate(p.attributes
|
|
182
|
+
p.attributes?.name ?? "-",
|
|
183
|
+
p.attributes?.profileType ?? "-",
|
|
184
|
+
p.attributes?.profileState ?? "-",
|
|
185
|
+
formatDate(p.attributes?.expirationDate ?? ""),
|
|
206
186
|
]),
|
|
207
187
|
`Provisioning Profiles (${items.length})`,
|
|
208
188
|
)
|
|
209
189
|
}
|
|
210
190
|
|
|
211
191
|
export async function profileDelete(profileId: string): Promise<void> {
|
|
212
|
-
await
|
|
192
|
+
await profilesDeleteInstance({ path: { id: profileId } })
|
|
213
193
|
printSuccess(`Profile ${profileId} deleted`)
|
|
214
194
|
}
|
|
@@ -1,20 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
appsSubscriptionGroupsGetToManyRelated,
|
|
3
|
+
subscriptionGroupsCreateInstance,
|
|
4
|
+
subscriptionGroupsSubscriptionsGetToManyRelated,
|
|
5
|
+
subscriptionsGetInstance,
|
|
6
|
+
subscriptionsCreateInstance,
|
|
7
|
+
subscriptionsPricesGetToManyRelated,
|
|
8
|
+
} from "../api/generated/sdk.gen.ts"
|
|
9
|
+
import { throwOnError } from "../api/client.ts"
|
|
2
10
|
import { detectFormat, printJSON, printSuccess, printTable, truncate } from "../utils/output.ts"
|
|
3
11
|
|
|
4
12
|
// ---- Subscription Groups ----
|
|
5
13
|
|
|
6
14
|
export async function subscriptionGroupsList(opts: { appId: string; output?: string }): Promise<void> {
|
|
7
|
-
const
|
|
8
|
-
id:
|
|
9
|
-
|
|
10
|
-
}>(`/v1/apps/${opts.appId}/subscriptionGroups`, {
|
|
11
|
-
params: { "fields[subscriptionGroups]": "referenceName,subscriptions" },
|
|
15
|
+
const result = await appsSubscriptionGroupsGetToManyRelated({
|
|
16
|
+
path: { id: opts.appId },
|
|
17
|
+
query: { "fields[subscriptionGroups]": ["referenceName"] },
|
|
12
18
|
})
|
|
19
|
+
const data = throwOnError(result)
|
|
20
|
+
const items = data.data
|
|
13
21
|
const fmt = detectFormat(opts.output)
|
|
14
22
|
if (fmt === "json") { printJSON(items); return }
|
|
15
23
|
printTable(
|
|
16
24
|
["Group ID", "Reference Name"],
|
|
17
|
-
items.map(g => [g.id, g.attributes
|
|
25
|
+
items.map(g => [g.id, g.attributes?.referenceName ?? "-"]),
|
|
18
26
|
`Subscription Groups (${items.length})`,
|
|
19
27
|
)
|
|
20
28
|
}
|
|
@@ -23,8 +31,7 @@ export async function subscriptionGroupCreate(opts: {
|
|
|
23
31
|
appId: string
|
|
24
32
|
referenceName: string
|
|
25
33
|
}): Promise<void> {
|
|
26
|
-
const result = await
|
|
27
|
-
method: "POST",
|
|
34
|
+
const result = await subscriptionGroupsCreateInstance({
|
|
28
35
|
body: {
|
|
29
36
|
data: {
|
|
30
37
|
type: "subscriptionGroups",
|
|
@@ -33,66 +40,48 @@ export async function subscriptionGroupCreate(opts: {
|
|
|
33
40
|
},
|
|
34
41
|
},
|
|
35
42
|
})
|
|
36
|
-
|
|
43
|
+
const data = throwOnError(result)
|
|
44
|
+
printSuccess(`Created subscription group: ${data.data.id}`)
|
|
37
45
|
}
|
|
38
46
|
|
|
39
47
|
// ---- Subscriptions ----
|
|
40
48
|
|
|
41
49
|
export async function subscriptionsList(opts: { groupId: string; output?: string }): Promise<void> {
|
|
42
|
-
const
|
|
43
|
-
id:
|
|
44
|
-
|
|
45
|
-
name?: string
|
|
46
|
-
productId?: string
|
|
47
|
-
subscriptionPeriod?: string
|
|
48
|
-
state?: string
|
|
49
|
-
familySharable?: boolean
|
|
50
|
-
}
|
|
51
|
-
}>(`/v1/subscriptionGroups/${opts.groupId}/subscriptions`, {
|
|
52
|
-
params: { "fields[subscriptions]": "name,productId,subscriptionPeriod,state,familySharable" },
|
|
50
|
+
const result = await subscriptionGroupsSubscriptionsGetToManyRelated({
|
|
51
|
+
path: { id: opts.groupId },
|
|
52
|
+
query: { "fields[subscriptions]": ["name", "productId", "subscriptionPeriod", "state", "familySharable"] },
|
|
53
53
|
})
|
|
54
|
+
const data = throwOnError(result)
|
|
55
|
+
const items = data.data
|
|
54
56
|
const fmt = detectFormat(opts.output)
|
|
55
57
|
if (fmt === "json") { printJSON(items); return }
|
|
56
58
|
printTable(
|
|
57
59
|
["ID", "Name", "Product ID", "Period", "State"],
|
|
58
60
|
items.map(s => [
|
|
59
61
|
s.id,
|
|
60
|
-
truncate(s.attributes
|
|
61
|
-
s.attributes
|
|
62
|
-
s.attributes
|
|
63
|
-
s.attributes
|
|
62
|
+
truncate(s.attributes?.name ?? "-", 30),
|
|
63
|
+
s.attributes?.productId ?? "-",
|
|
64
|
+
s.attributes?.subscriptionPeriod ?? "-",
|
|
65
|
+
s.attributes?.state ?? "-",
|
|
64
66
|
]),
|
|
65
67
|
`Subscriptions (${items.length})`,
|
|
66
68
|
)
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
export async function subscriptionGet(subId: string, opts: { output?: string } = {}): Promise<void> {
|
|
70
|
-
const result = await
|
|
71
|
-
|
|
72
|
-
id: string
|
|
73
|
-
attributes: {
|
|
74
|
-
name?: string
|
|
75
|
-
productId?: string
|
|
76
|
-
subscriptionPeriod?: string
|
|
77
|
-
state?: string
|
|
78
|
-
familySharable?: boolean
|
|
79
|
-
reviewNote?: string
|
|
80
|
-
availableInAllTerritories?: boolean
|
|
81
|
-
groupLevel?: number
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}>(`/v1/subscriptions/${subId}`)
|
|
72
|
+
const result = await subscriptionsGetInstance({ path: { id: subId } })
|
|
73
|
+
const data = throwOnError(result)
|
|
85
74
|
const fmt = detectFormat(opts.output)
|
|
86
|
-
if (fmt === "json") { printJSON(
|
|
87
|
-
const a =
|
|
88
|
-
console.log(`ID: ${
|
|
89
|
-
console.log(`Name: ${a
|
|
90
|
-
console.log(`Product ID: ${a
|
|
91
|
-
console.log(`Period: ${a
|
|
92
|
-
console.log(`State: ${a
|
|
93
|
-
console.log(`Group Level: ${a
|
|
94
|
-
console.log(`Family Share: ${a
|
|
95
|
-
console.log(`All Territ.: ${a
|
|
75
|
+
if (fmt === "json") { printJSON(data.data); return }
|
|
76
|
+
const a = data.data.attributes
|
|
77
|
+
console.log(`ID: ${data.data.id}`)
|
|
78
|
+
console.log(`Name: ${a?.name ?? "-"}`)
|
|
79
|
+
console.log(`Product ID: ${a?.productId ?? "-"}`)
|
|
80
|
+
console.log(`Period: ${a?.subscriptionPeriod ?? "-"}`)
|
|
81
|
+
console.log(`State: ${a?.state ?? "-"}`)
|
|
82
|
+
console.log(`Group Level: ${a?.groupLevel ?? "-"}`)
|
|
83
|
+
console.log(`Family Share: ${a?.familySharable ?? false}`)
|
|
84
|
+
console.log(`All Territ.: ${(a as Record<string, unknown>)?.availableInAllTerritories ?? false}`)
|
|
96
85
|
}
|
|
97
86
|
|
|
98
87
|
export async function subscriptionCreate(opts: {
|
|
@@ -101,15 +90,14 @@ export async function subscriptionCreate(opts: {
|
|
|
101
90
|
productId: string
|
|
102
91
|
period: string
|
|
103
92
|
}): Promise<void> {
|
|
104
|
-
const result = await
|
|
105
|
-
method: "POST",
|
|
93
|
+
const result = await subscriptionsCreateInstance({
|
|
106
94
|
body: {
|
|
107
95
|
data: {
|
|
108
96
|
type: "subscriptions",
|
|
109
97
|
attributes: {
|
|
110
98
|
name: opts.name,
|
|
111
99
|
productId: opts.productId,
|
|
112
|
-
subscriptionPeriod: opts.period,
|
|
100
|
+
subscriptionPeriod: opts.period as never,
|
|
113
101
|
},
|
|
114
102
|
relationships: {
|
|
115
103
|
group: { data: { type: "subscriptionGroups", id: opts.groupId } },
|
|
@@ -117,7 +105,8 @@ export async function subscriptionCreate(opts: {
|
|
|
117
105
|
},
|
|
118
106
|
},
|
|
119
107
|
})
|
|
120
|
-
|
|
108
|
+
const data = throwOnError(result)
|
|
109
|
+
printSuccess(`Created subscription: ${data.data.id} (${opts.productId})`)
|
|
121
110
|
}
|
|
122
111
|
|
|
123
112
|
export async function subscriptionPricesList(opts: {
|
|
@@ -125,20 +114,23 @@ export async function subscriptionPricesList(opts: {
|
|
|
125
114
|
territory?: string
|
|
126
115
|
output?: string
|
|
127
116
|
}): Promise<void> {
|
|
128
|
-
const
|
|
129
|
-
"fields[subscriptionPrices]": "startDate,territory",
|
|
130
|
-
include: "subscriptionPricePoint",
|
|
117
|
+
const query: Record<string, unknown> = {
|
|
118
|
+
"fields[subscriptionPrices]": ["startDate", "territory"],
|
|
119
|
+
include: ["subscriptionPricePoint"],
|
|
131
120
|
}
|
|
132
|
-
if (opts.territory)
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
121
|
+
if (opts.territory) query["filter[territory]"] = [opts.territory]
|
|
122
|
+
|
|
123
|
+
const result = await subscriptionsPricesGetToManyRelated({
|
|
124
|
+
path: { id: opts.subId },
|
|
125
|
+
query: query as never,
|
|
126
|
+
})
|
|
127
|
+
const data = throwOnError(result)
|
|
128
|
+
const items = data.data
|
|
137
129
|
const fmt = detectFormat(opts.output)
|
|
138
130
|
if (fmt === "json") { printJSON(items); return }
|
|
139
131
|
printTable(
|
|
140
132
|
["Price ID", "Territory", "Start Date"],
|
|
141
|
-
items.map(p => [p.id, String(p.attributes
|
|
133
|
+
items.map(p => [p.id, String((p.attributes as Record<string, unknown>)?.territory ?? "-"), (p.attributes as Record<string, unknown>)?.startDate as string ?? "ongoing"]),
|
|
142
134
|
`Subscription Prices (${items.length})`,
|
|
143
135
|
)
|
|
144
136
|
}
|
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
import * as p from "@clack/prompts"
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import {
|
|
3
|
+
appsBetaGroupsGetToManyRelated,
|
|
4
|
+
betaGroupsGetCollection,
|
|
5
|
+
betaGroupsBetaTestersGetToManyRelated,
|
|
6
|
+
betaTestersCreateInstance,
|
|
7
|
+
betaGroupsBetaTestersDeleteToManyRelationship,
|
|
8
|
+
} from "../api/generated/sdk.gen.ts"
|
|
9
|
+
import { throwOnError } from "../api/client.ts"
|
|
10
|
+
import { detectFormat, formatDate, printJSON, printSuccess, printTable } from "../utils/output.ts"
|
|
5
11
|
|
|
6
12
|
export async function testflightGroupsList(opts: {
|
|
7
13
|
appId?: string
|
|
8
14
|
output?: string
|
|
9
15
|
} = {}): Promise<void> {
|
|
10
|
-
let groups:
|
|
16
|
+
let groups: Array<{ id: string; attributes?: { name?: string; isInternalGroup?: boolean; publicLink?: string | null } }>
|
|
17
|
+
|
|
11
18
|
if (opts.appId) {
|
|
12
|
-
|
|
19
|
+
const result = await appsBetaGroupsGetToManyRelated({ path: { id: opts.appId } })
|
|
20
|
+
const data = throwOnError(result)
|
|
21
|
+
groups = data.data
|
|
13
22
|
} else {
|
|
14
|
-
|
|
23
|
+
const result = await betaGroupsGetCollection()
|
|
24
|
+
const data = throwOnError(result)
|
|
25
|
+
groups = data.data
|
|
15
26
|
}
|
|
16
27
|
|
|
17
28
|
const fmt = detectFormat(opts.output)
|
|
@@ -24,9 +35,9 @@ export async function testflightGroupsList(opts: {
|
|
|
24
35
|
["ID", "Name", "Internal", "Public Link"],
|
|
25
36
|
groups.map((g) => [
|
|
26
37
|
g.id,
|
|
27
|
-
g.attributes
|
|
28
|
-
g.attributes
|
|
29
|
-
g.attributes
|
|
38
|
+
g.attributes?.name ?? "-",
|
|
39
|
+
g.attributes?.isInternalGroup ? "yes" : "no",
|
|
40
|
+
g.attributes?.publicLink ?? "-",
|
|
30
41
|
]),
|
|
31
42
|
`Beta Groups (${groups.length})`,
|
|
32
43
|
)
|
|
@@ -36,12 +47,12 @@ export async function testflightTestersList(opts: {
|
|
|
36
47
|
groupId: string
|
|
37
48
|
output?: string
|
|
38
49
|
}): Promise<void> {
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
{
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
50
|
+
const result = await betaGroupsBetaTestersGetToManyRelated({
|
|
51
|
+
path: { id: opts.groupId },
|
|
52
|
+
query: { "fields[betaTesters]": ["firstName", "lastName", "email", "inviteType", "state"] },
|
|
53
|
+
})
|
|
54
|
+
const data = throwOnError(result)
|
|
55
|
+
const testers = data.data
|
|
45
56
|
|
|
46
57
|
const fmt = detectFormat(opts.output)
|
|
47
58
|
if (fmt === "json") {
|
|
@@ -53,9 +64,9 @@ export async function testflightTestersList(opts: {
|
|
|
53
64
|
["ID", "Name", "Email", "State"],
|
|
54
65
|
testers.map((t) => [
|
|
55
66
|
t.id,
|
|
56
|
-
[t.attributes
|
|
57
|
-
t.attributes
|
|
58
|
-
t.attributes
|
|
67
|
+
[t.attributes?.firstName, t.attributes?.lastName].filter(Boolean).join(" ") || "-",
|
|
68
|
+
t.attributes?.email ?? "-",
|
|
69
|
+
t.attributes?.state ?? "-",
|
|
59
70
|
]),
|
|
60
71
|
`Testers (${testers.length})`,
|
|
61
72
|
)
|
|
@@ -75,8 +86,7 @@ export async function testflightTestersAdd(opts: {
|
|
|
75
86
|
}
|
|
76
87
|
|
|
77
88
|
// Create tester + add to group
|
|
78
|
-
const
|
|
79
|
-
method: "POST",
|
|
89
|
+
const result = await betaTestersCreateInstance({
|
|
80
90
|
body: {
|
|
81
91
|
data: {
|
|
82
92
|
type: "betaTesters",
|
|
@@ -93,15 +103,16 @@ export async function testflightTestersAdd(opts: {
|
|
|
93
103
|
},
|
|
94
104
|
},
|
|
95
105
|
})
|
|
96
|
-
|
|
106
|
+
const data = throwOnError(result)
|
|
107
|
+
printSuccess(`Tester ${email} added (ID: ${data.data.id})`)
|
|
97
108
|
}
|
|
98
109
|
|
|
99
110
|
export async function testflightTestersRemove(opts: {
|
|
100
111
|
groupId: string
|
|
101
112
|
testerId: string
|
|
102
113
|
}): Promise<void> {
|
|
103
|
-
await
|
|
104
|
-
|
|
114
|
+
await betaGroupsBetaTestersDeleteToManyRelationship({
|
|
115
|
+
path: { id: opts.groupId },
|
|
105
116
|
body: {
|
|
106
117
|
data: [{ type: "betaTesters", id: opts.testerId }],
|
|
107
118
|
},
|