@onmyway133/asc-cli 1.0.1 → 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 +7 -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/versions.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
appsAppStoreVersionsGetToManyRelated,
|
|
3
|
+
appStoreVersionsCreateInstance,
|
|
4
|
+
appStoreVersionReleaseRequestsCreateInstance,
|
|
5
|
+
} from "../api/generated/sdk.gen.ts"
|
|
6
|
+
import type { Platform } from "../api/generated/types.gen.ts"
|
|
7
|
+
import { throwOnError, ascFetch } from "../api/client.ts"
|
|
3
8
|
import { detectFormat, formatDate, printJSON, printSuccess, printTable } from "../utils/output.ts"
|
|
4
9
|
|
|
5
10
|
export async function versionsList(opts: {
|
|
@@ -7,15 +12,15 @@ export async function versionsList(opts: {
|
|
|
7
12
|
platform?: string
|
|
8
13
|
output?: string
|
|
9
14
|
}): Promise<void> {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
const result = await appsAppStoreVersionsGetToManyRelated({
|
|
16
|
+
path: { id: opts.appId },
|
|
17
|
+
query: {
|
|
18
|
+
"fields[appStoreVersions]": ["platform", "versionString", "appStoreState", "createdDate"],
|
|
19
|
+
...(opts.platform ? { "filter[platform]": [opts.platform.toUpperCase() as Platform] } : {}),
|
|
20
|
+
},
|
|
21
|
+
})
|
|
22
|
+
const data = throwOnError(result)
|
|
23
|
+
const versions = data.data
|
|
19
24
|
|
|
20
25
|
const fmt = detectFormat(opts.output)
|
|
21
26
|
if (fmt === "json") {
|
|
@@ -27,10 +32,10 @@ export async function versionsList(opts: {
|
|
|
27
32
|
["ID", "Version", "Platform", "State", "Created"],
|
|
28
33
|
versions.map((v) => [
|
|
29
34
|
v.id,
|
|
30
|
-
v.attributes
|
|
31
|
-
v.attributes
|
|
32
|
-
v.attributes
|
|
33
|
-
formatDate(v.attributes
|
|
35
|
+
v.attributes?.versionString ?? "-",
|
|
36
|
+
v.attributes?.platform ?? "-",
|
|
37
|
+
v.attributes?.appStoreState ?? "-",
|
|
38
|
+
formatDate(v.attributes?.createdDate),
|
|
34
39
|
]),
|
|
35
40
|
`Versions (${versions.length})`,
|
|
36
41
|
)
|
|
@@ -42,8 +47,7 @@ export async function versionsCreate(opts: {
|
|
|
42
47
|
platform: string
|
|
43
48
|
}): Promise<void> {
|
|
44
49
|
const platform = opts.platform.toUpperCase() as Platform
|
|
45
|
-
const
|
|
46
|
-
method: "POST",
|
|
50
|
+
const result = await appStoreVersionsCreateInstance({
|
|
47
51
|
body: {
|
|
48
52
|
data: {
|
|
49
53
|
type: "appStoreVersions",
|
|
@@ -57,9 +61,12 @@ export async function versionsCreate(opts: {
|
|
|
57
61
|
},
|
|
58
62
|
},
|
|
59
63
|
})
|
|
60
|
-
|
|
64
|
+
const data = throwOnError(result)
|
|
65
|
+
printSuccess(`Created version ${opts.version} (${platform}) — ID: ${data.data.id}`)
|
|
61
66
|
}
|
|
62
67
|
|
|
68
|
+
// versionsSubmit uses the deprecated appStoreVersionSubmissions API which has no
|
|
69
|
+
// generated create SDK function (only delete). Keep using ascFetch.
|
|
63
70
|
export async function versionsSubmit(versionId: string): Promise<void> {
|
|
64
71
|
await ascFetch("/v1/appStoreVersionSubmissions", {
|
|
65
72
|
method: "POST",
|
|
@@ -74,3 +81,18 @@ export async function versionsSubmit(versionId: string): Promise<void> {
|
|
|
74
81
|
})
|
|
75
82
|
printSuccess(`Version ${versionId} submitted for review`)
|
|
76
83
|
}
|
|
84
|
+
|
|
85
|
+
export async function releaseRequestCreate(versionId: string): Promise<void> {
|
|
86
|
+
const result = await appStoreVersionReleaseRequestsCreateInstance({
|
|
87
|
+
body: {
|
|
88
|
+
data: {
|
|
89
|
+
type: "appStoreVersionReleaseRequests",
|
|
90
|
+
relationships: {
|
|
91
|
+
appStoreVersion: { data: { type: "appStoreVersions", id: versionId } },
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
})
|
|
96
|
+
throwOnError(result)
|
|
97
|
+
printSuccess(`Release request created for version ${versionId}`)
|
|
98
|
+
}
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
appsCiProductGetToOneRelated,
|
|
3
|
+
ciProductsGetCollection,
|
|
4
|
+
ciProductsWorkflowsGetToManyRelated,
|
|
5
|
+
ciWorkflowsGetInstance,
|
|
6
|
+
ciWorkflowsBuildRunsGetToManyRelated,
|
|
7
|
+
ciProductsBuildRunsGetToManyRelated,
|
|
8
|
+
ciBuildRunsCreateInstance,
|
|
9
|
+
} from "../api/generated/sdk.gen.ts"
|
|
10
|
+
import { throwOnError, ascFetchAll } from "../api/client.ts"
|
|
2
11
|
import { detectFormat, formatDate, printJSON, printSuccess, printTable, truncate } from "../utils/output.ts"
|
|
3
12
|
|
|
4
13
|
// ---- Xcode Cloud Products ----
|
|
@@ -7,22 +16,27 @@ export async function xcodeCloudProductsList(opts: {
|
|
|
7
16
|
appId?: string
|
|
8
17
|
output?: string
|
|
9
18
|
} = {}): Promise<void> {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
19
|
+
let items: Array<{ id: string; attributes?: { name?: string; createdDate?: string; productType?: string } }>
|
|
20
|
+
|
|
21
|
+
if (opts.appId) {
|
|
22
|
+
const result = await appsCiProductGetToOneRelated({ path: { id: opts.appId } })
|
|
23
|
+
const data = throwOnError(result)
|
|
24
|
+
items = [data.data]
|
|
25
|
+
} else {
|
|
26
|
+
const result = await ciProductsGetCollection()
|
|
27
|
+
const data = throwOnError(result)
|
|
28
|
+
items = data.data
|
|
29
|
+
}
|
|
30
|
+
|
|
17
31
|
const fmt = detectFormat(opts.output)
|
|
18
32
|
if (fmt === "json") { printJSON(items); return }
|
|
19
33
|
printTable(
|
|
20
34
|
["Product ID", "Name", "Type", "Created"],
|
|
21
35
|
items.map(p => [
|
|
22
36
|
p.id,
|
|
23
|
-
p.attributes
|
|
24
|
-
p.attributes
|
|
25
|
-
formatDate(p.attributes
|
|
37
|
+
p.attributes?.name ?? "-",
|
|
38
|
+
p.attributes?.productType ?? "-",
|
|
39
|
+
formatDate(p.attributes?.createdDate ?? ""),
|
|
26
40
|
]),
|
|
27
41
|
`Xcode Cloud Products (${items.length})`,
|
|
28
42
|
)
|
|
@@ -34,55 +48,34 @@ export async function workflowsList(opts: {
|
|
|
34
48
|
productId: string
|
|
35
49
|
output?: string
|
|
36
50
|
}): Promise<void> {
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
name?: string
|
|
41
|
-
description?: string
|
|
42
|
-
isEnabled?: boolean
|
|
43
|
-
isLockedForEditing?: boolean
|
|
44
|
-
lastModifiedDate?: string
|
|
45
|
-
}
|
|
46
|
-
}>(`/v1/ciProducts/${opts.productId}/workflows`)
|
|
51
|
+
const result = await ciProductsWorkflowsGetToManyRelated({ path: { id: opts.productId } })
|
|
52
|
+
const data = throwOnError(result)
|
|
53
|
+
const items = data.data
|
|
47
54
|
const fmt = detectFormat(opts.output)
|
|
48
55
|
if (fmt === "json") { printJSON(items); return }
|
|
49
56
|
printTable(
|
|
50
57
|
["Workflow ID", "Name", "Enabled", "Last Modified"],
|
|
51
58
|
items.map(w => [
|
|
52
59
|
w.id,
|
|
53
|
-
truncate(w.attributes
|
|
54
|
-
String(w.attributes
|
|
55
|
-
formatDate(w.attributes
|
|
60
|
+
truncate(w.attributes?.name ?? "-", 40),
|
|
61
|
+
String(w.attributes?.isEnabled ?? "-"),
|
|
62
|
+
formatDate(w.attributes?.lastModifiedDate ?? ""),
|
|
56
63
|
]),
|
|
57
64
|
`Workflows (${items.length})`,
|
|
58
65
|
)
|
|
59
66
|
}
|
|
60
67
|
|
|
61
68
|
export async function workflowGet(workflowId: string, opts: { output?: string } = {}): Promise<void> {
|
|
62
|
-
const result = await
|
|
63
|
-
|
|
64
|
-
id: string
|
|
65
|
-
attributes: {
|
|
66
|
-
name?: string
|
|
67
|
-
description?: string
|
|
68
|
-
isEnabled?: boolean
|
|
69
|
-
isLockedForEditing?: boolean
|
|
70
|
-
lastModifiedDate?: string
|
|
71
|
-
branchStartCondition?: unknown
|
|
72
|
-
pullRequestStartCondition?: unknown
|
|
73
|
-
scheduledStartCondition?: unknown
|
|
74
|
-
tagStartCondition?: unknown
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}>(`/v1/ciWorkflows/${workflowId}`)
|
|
69
|
+
const result = await ciWorkflowsGetInstance({ path: { id: workflowId } })
|
|
70
|
+
const data = throwOnError(result)
|
|
78
71
|
const fmt = detectFormat(opts.output)
|
|
79
|
-
if (fmt === "json") { printJSON(
|
|
80
|
-
const a =
|
|
81
|
-
console.log(`ID: ${
|
|
82
|
-
console.log(`Name: ${a
|
|
83
|
-
console.log(`Description: ${a
|
|
84
|
-
console.log(`Enabled: ${a
|
|
85
|
-
console.log(`Last Modified: ${formatDate(a
|
|
72
|
+
if (fmt === "json") { printJSON(data.data); return }
|
|
73
|
+
const a = data.data.attributes
|
|
74
|
+
console.log(`ID: ${data.data.id}`)
|
|
75
|
+
console.log(`Name: ${a?.name ?? "-"}`)
|
|
76
|
+
console.log(`Description: ${a?.description ?? "-"}`)
|
|
77
|
+
console.log(`Enabled: ${a?.isEnabled ?? "-"}`)
|
|
78
|
+
console.log(`Last Modified: ${formatDate(a?.lastModifiedDate ?? "")}`)
|
|
86
79
|
}
|
|
87
80
|
|
|
88
81
|
// ---- Builds ----
|
|
@@ -92,33 +85,41 @@ export async function xcodeCloudBuildsList(opts: {
|
|
|
92
85
|
productId?: string
|
|
93
86
|
output?: string
|
|
94
87
|
} = {}): Promise<void> {
|
|
95
|
-
|
|
96
|
-
? `/v1/ciWorkflows/${opts.workflowId}/buildRuns`
|
|
97
|
-
: opts.productId
|
|
98
|
-
? `/v1/ciProducts/${opts.productId}/buildRuns`
|
|
99
|
-
: "/v1/ciBuildRuns"
|
|
100
|
-
const items = await ascFetchAll<{
|
|
88
|
+
let items: Array<{
|
|
101
89
|
id: string
|
|
102
|
-
attributes
|
|
90
|
+
attributes?: {
|
|
103
91
|
number?: number
|
|
104
92
|
createdDate?: string
|
|
105
93
|
startedDate?: string
|
|
106
94
|
finishedDate?: string
|
|
107
|
-
sourceCommit?: { commitSha?: string; message?: string }
|
|
108
95
|
executionProgress?: string
|
|
109
96
|
completionStatus?: string
|
|
110
97
|
}
|
|
111
|
-
}>
|
|
98
|
+
}>
|
|
99
|
+
|
|
100
|
+
if (opts.workflowId) {
|
|
101
|
+
const result = await ciWorkflowsBuildRunsGetToManyRelated({ path: { id: opts.workflowId } })
|
|
102
|
+
const data = throwOnError(result)
|
|
103
|
+
items = data.data
|
|
104
|
+
} else if (opts.productId) {
|
|
105
|
+
const result = await ciProductsBuildRunsGetToManyRelated({ path: { id: opts.productId } })
|
|
106
|
+
const data = throwOnError(result)
|
|
107
|
+
items = data.data
|
|
108
|
+
} else {
|
|
109
|
+
// No SDK collection for ciBuildRuns without filter — fall back to ascFetchAll
|
|
110
|
+
items = await ascFetchAll("/v1/ciBuildRuns")
|
|
111
|
+
}
|
|
112
|
+
|
|
112
113
|
const fmt = detectFormat(opts.output)
|
|
113
114
|
if (fmt === "json") { printJSON(items); return }
|
|
114
115
|
printTable(
|
|
115
116
|
["Build ID", "#", "Status", "Progress", "Started"],
|
|
116
117
|
items.map(b => [
|
|
117
118
|
b.id,
|
|
118
|
-
String(b.attributes
|
|
119
|
-
b.attributes
|
|
120
|
-
b.attributes
|
|
121
|
-
formatDate(b.attributes
|
|
119
|
+
String(b.attributes?.number ?? "-"),
|
|
120
|
+
b.attributes?.completionStatus ?? "RUNNING",
|
|
121
|
+
b.attributes?.executionProgress ?? "-",
|
|
122
|
+
formatDate(b.attributes?.startedDate ?? b.attributes?.createdDate ?? ""),
|
|
122
123
|
]),
|
|
123
124
|
`Xcode Cloud Builds (${items.length})`,
|
|
124
125
|
)
|
|
@@ -131,20 +132,20 @@ export async function xcodeCloudBuildRun(opts: {
|
|
|
131
132
|
}): Promise<void> {
|
|
132
133
|
const attributes: Record<string, unknown> = { isPullRequestBuild: false }
|
|
133
134
|
if (opts.branch) attributes["sourceCommit"] = { branch: opts.branch }
|
|
134
|
-
const result = await
|
|
135
|
-
method: "POST",
|
|
135
|
+
const result = await ciBuildRunsCreateInstance({
|
|
136
136
|
body: {
|
|
137
137
|
data: {
|
|
138
138
|
type: "ciBuildRuns",
|
|
139
|
-
attributes,
|
|
139
|
+
attributes: attributes as never,
|
|
140
140
|
relationships: {
|
|
141
141
|
workflow: { data: { type: "ciWorkflows", id: opts.workflowId } },
|
|
142
142
|
},
|
|
143
143
|
},
|
|
144
144
|
},
|
|
145
145
|
})
|
|
146
|
-
const
|
|
147
|
-
|
|
146
|
+
const data = throwOnError(result)
|
|
147
|
+
const num = data.data.attributes?.number
|
|
148
|
+
printSuccess(`Build run started: ${data.data.id}${num ? ` (#${num})` : ""}`)
|
|
148
149
|
}
|
|
149
150
|
|
|
150
151
|
// ---- Artifacts ----
|
|
@@ -153,6 +154,7 @@ export async function xcodeCloudArtifactsList(opts: {
|
|
|
153
154
|
buildRunId: string
|
|
154
155
|
output?: string
|
|
155
156
|
}): Promise<void> {
|
|
157
|
+
// No SDK function for /v1/ciBuildRuns/{id}/artifacts — keep ascFetchAll
|
|
156
158
|
const items = await ascFetchAll<{
|
|
157
159
|
id: string
|
|
158
160
|
attributes: {
|
|
@@ -182,6 +184,7 @@ export async function xcodeCloudTestResultsList(opts: {
|
|
|
182
184
|
buildRunId: string
|
|
183
185
|
output?: string
|
|
184
186
|
}): Promise<void> {
|
|
187
|
+
// No SDK function for /v1/ciBuildRuns/{id}/testResults — keep ascFetchAll
|
|
185
188
|
const items = await ascFetchAll<{
|
|
186
189
|
id: string
|
|
187
190
|
attributes: {
|
package/src/index.ts
CHANGED
|
@@ -25,6 +25,9 @@ import { printError } from "./utils/output.ts"
|
|
|
25
25
|
import { buildHelpDocument } from "./utils/help-spec.ts"
|
|
26
26
|
import pkg from "../package.json"
|
|
27
27
|
|
|
28
|
+
// ---- hey-api generated client (sets JWT auth interceptor) ----
|
|
29
|
+
import "./api/hey-api-client.ts"
|
|
30
|
+
|
|
28
31
|
// ---- Auth commands ----
|
|
29
32
|
import { authLogin, authList, authLogout, authStatus, authUse, profileView, profileUpdate, profileDelete as authProfileDelete } from "./commands/auth.ts"
|
|
30
33
|
|
|
@@ -35,7 +38,7 @@ import { appsList, appsGet } from "./commands/apps.ts"
|
|
|
35
38
|
import { buildsList, buildsGet, buildsUpdateBetaNotes } from "./commands/builds.ts"
|
|
36
39
|
|
|
37
40
|
// ---- Versions ----
|
|
38
|
-
import { versionsList, versionsCreate, versionsSubmit } from "./commands/versions.ts"
|
|
41
|
+
import { versionsList, versionsCreate, versionsSubmit, releaseRequestCreate } from "./commands/versions.ts"
|
|
39
42
|
|
|
40
43
|
// ---- TestFlight ----
|
|
41
44
|
import {
|
|
@@ -48,6 +51,27 @@ import {
|
|
|
48
51
|
// ---- Metadata ----
|
|
49
52
|
import { metadataList, metadataUpdate } from "./commands/metadata.ts"
|
|
50
53
|
|
|
54
|
+
// ---- Localizations ----
|
|
55
|
+
import { localizationsList, localizationsGet, localizationsCreate, localizationsDelete } from "./commands/localizations.ts"
|
|
56
|
+
|
|
57
|
+
// ---- Review Details ----
|
|
58
|
+
import { reviewDetailsGet, reviewDetailsUpdate } from "./commands/review-details.ts"
|
|
59
|
+
|
|
60
|
+
// ---- Review Submission ----
|
|
61
|
+
import {
|
|
62
|
+
reviewSubmissionList,
|
|
63
|
+
reviewSubmissionCreate,
|
|
64
|
+
reviewSubmissionGet,
|
|
65
|
+
reviewSubmissionSubmit,
|
|
66
|
+
reviewSubmissionCancel,
|
|
67
|
+
reviewSubmissionItemsList,
|
|
68
|
+
reviewSubmissionItemAdd,
|
|
69
|
+
reviewSubmissionItemDelete,
|
|
70
|
+
} from "./commands/review-submission.ts"
|
|
71
|
+
|
|
72
|
+
// ---- Phased Release ----
|
|
73
|
+
import { phasedReleaseGet, phasedReleaseCreate, phasedReleaseUpdate, phasedReleaseDelete } from "./commands/phased-release.ts"
|
|
74
|
+
|
|
51
75
|
// ---- Reviews ----
|
|
52
76
|
import { reviewsList, reviewsGet, reviewsRespond } from "./commands/reviews.ts"
|
|
53
77
|
|
|
@@ -439,6 +463,25 @@ const versionsSubmitCmd = defineCommand({
|
|
|
439
463
|
async run({ args }) { await versionsSubmit(args["version-id"]) },
|
|
440
464
|
})
|
|
441
465
|
|
|
466
|
+
const releaseRequestCreateCmd = defineCommand({
|
|
467
|
+
meta: {
|
|
468
|
+
name: "create",
|
|
469
|
+
description: "Manually trigger release of an approved version. Use when auto-release is disabled. Requires the version to be in PENDING_DEVELOPER_RELEASE state.",
|
|
470
|
+
},
|
|
471
|
+
args: {
|
|
472
|
+
"version-id": { type: "string", alias: "v", required: true, description: "Version ID (get from: asc versions list)" },
|
|
473
|
+
},
|
|
474
|
+
async run({ args }) { await releaseRequestCreate(args["version-id"]) },
|
|
475
|
+
})
|
|
476
|
+
|
|
477
|
+
const releaseRequestCmd = defineCommand({
|
|
478
|
+
meta: {
|
|
479
|
+
name: "release-request",
|
|
480
|
+
description: "Manually release an approved version. Use after Apple approves the build and auto-release is off.",
|
|
481
|
+
},
|
|
482
|
+
subCommands: { create: releaseRequestCreateCmd },
|
|
483
|
+
})
|
|
484
|
+
|
|
442
485
|
const versionsCmd = defineCommand({
|
|
443
486
|
meta: {
|
|
444
487
|
name: "versions",
|
|
@@ -579,6 +622,270 @@ const metadataCmd = defineCommand({
|
|
|
579
622
|
subCommands: { list: metadataListCmd, update: metadataUpdateCmd },
|
|
580
623
|
})
|
|
581
624
|
|
|
625
|
+
// =============================================================================
|
|
626
|
+
// LOCALIZATIONS
|
|
627
|
+
// =============================================================================
|
|
628
|
+
|
|
629
|
+
const localizationsListCmd = defineCommand({
|
|
630
|
+
meta: { name: "list", description: "List all localizations for a version. Returns localization IDs needed for screenshots and metadata updates." },
|
|
631
|
+
args: {
|
|
632
|
+
"version-id": { type: "string", alias: "v", required: true, description: "Version ID. Use: asc versions list --app-id <id>" },
|
|
633
|
+
output: { type: "string", alias: "o", description: "Output format: table | json" },
|
|
634
|
+
},
|
|
635
|
+
async run({ args }) { await localizationsList({ versionId: args["version-id"], output: args.output }) },
|
|
636
|
+
})
|
|
637
|
+
|
|
638
|
+
const localizationsGetCmd = defineCommand({
|
|
639
|
+
meta: { name: "get", description: "Get full details of a localization including all text fields and screenshot set IDs." },
|
|
640
|
+
args: {
|
|
641
|
+
id: { type: "positional", required: true, description: "Localization ID. Use: asc localizations list --version-id <id>" },
|
|
642
|
+
output: { type: "string", alias: "o", description: "Output format: table | json" },
|
|
643
|
+
},
|
|
644
|
+
async run({ args }) { await localizationsGet(args.id, args.output) },
|
|
645
|
+
})
|
|
646
|
+
|
|
647
|
+
const localizationsCreateCmd = defineCommand({
|
|
648
|
+
meta: { name: "create", description: "Add a new locale to a version. Use to support additional languages." },
|
|
649
|
+
args: {
|
|
650
|
+
"version-id": { type: "string", alias: "v", required: true, description: "Version ID. Use: asc versions list" },
|
|
651
|
+
locale: { type: "string", alias: "l", required: true, description: "Locale code, e.g. en-US, fr-FR, ja" },
|
|
652
|
+
description: { type: "string", description: "App description for this locale" },
|
|
653
|
+
"whats-new": { type: "string", description: "What's new text for this locale" },
|
|
654
|
+
keywords: { type: "string", description: "Comma-separated keywords" },
|
|
655
|
+
},
|
|
656
|
+
async run({ args }) {
|
|
657
|
+
await localizationsCreate({
|
|
658
|
+
versionId: args["version-id"],
|
|
659
|
+
locale: args.locale,
|
|
660
|
+
description: args.description,
|
|
661
|
+
whatsNew: args["whats-new"],
|
|
662
|
+
keywords: args.keywords,
|
|
663
|
+
})
|
|
664
|
+
},
|
|
665
|
+
})
|
|
666
|
+
|
|
667
|
+
const localizationsDeleteCmd = defineCommand({
|
|
668
|
+
meta: { name: "delete", description: "Remove a localization from a version." },
|
|
669
|
+
args: {
|
|
670
|
+
id: { type: "positional", required: true, description: "Localization ID. Use: asc localizations list" },
|
|
671
|
+
},
|
|
672
|
+
async run({ args }) { await localizationsDelete(args.id) },
|
|
673
|
+
})
|
|
674
|
+
|
|
675
|
+
const localizationsCmd = defineCommand({
|
|
676
|
+
meta: {
|
|
677
|
+
name: "localizations",
|
|
678
|
+
description: [
|
|
679
|
+
"Manage App Store version localizations.",
|
|
680
|
+
"Each locale has its own metadata and screenshot sets.",
|
|
681
|
+
"Get localization IDs first: asc localizations list --version-id <id>",
|
|
682
|
+
].join("\n"),
|
|
683
|
+
},
|
|
684
|
+
subCommands: { list: localizationsListCmd, get: localizationsGetCmd, create: localizationsCreateCmd, delete: localizationsDeleteCmd },
|
|
685
|
+
})
|
|
686
|
+
|
|
687
|
+
// =============================================================================
|
|
688
|
+
// REVIEW DETAILS
|
|
689
|
+
// =============================================================================
|
|
690
|
+
|
|
691
|
+
const reviewDetailsGetCmd = defineCommand({
|
|
692
|
+
meta: { name: "get", description: "Show current review contact info, demo account, and reviewer notes for a version." },
|
|
693
|
+
args: {
|
|
694
|
+
"version-id": { type: "string", alias: "v", required: true, description: "Version ID. Use: asc versions list" },
|
|
695
|
+
output: { type: "string", alias: "o", description: "Output format: table | json" },
|
|
696
|
+
},
|
|
697
|
+
async run({ args }) { await reviewDetailsGet(args["version-id"], args.output) },
|
|
698
|
+
})
|
|
699
|
+
|
|
700
|
+
const reviewDetailsUpdateCmd = defineCommand({
|
|
701
|
+
meta: {
|
|
702
|
+
name: "update",
|
|
703
|
+
description: [
|
|
704
|
+
"Set reviewer contact info, demo account credentials, and notes for this version.",
|
|
705
|
+
"Required before submitting for review.",
|
|
706
|
+
"Creates review details if they don't exist yet.",
|
|
707
|
+
].join("\n"),
|
|
708
|
+
},
|
|
709
|
+
args: {
|
|
710
|
+
"version-id": { type: "string", alias: "v", required: true, description: "Version ID. Use: asc versions list" },
|
|
711
|
+
"contact-first-name": { type: "string", description: "Reviewer contact first name" },
|
|
712
|
+
"contact-last-name": { type: "string", description: "Reviewer contact last name" },
|
|
713
|
+
"contact-email": { type: "string", description: "Reviewer contact email" },
|
|
714
|
+
"contact-phone": { type: "string", description: "Reviewer contact phone" },
|
|
715
|
+
"demo-account-name": { type: "string", description: "Demo account username" },
|
|
716
|
+
"demo-account-password": { type: "string", description: "Demo account password" },
|
|
717
|
+
"demo-account-required": { type: "boolean", description: "Whether a demo account is required" },
|
|
718
|
+
notes: { type: "string", description: "Additional notes for the reviewer (up to 4000 characters)" },
|
|
719
|
+
},
|
|
720
|
+
async run({ args }) {
|
|
721
|
+
await reviewDetailsUpdate({
|
|
722
|
+
versionId: args["version-id"],
|
|
723
|
+
contactFirstName: args["contact-first-name"],
|
|
724
|
+
contactLastName: args["contact-last-name"],
|
|
725
|
+
contactEmail: args["contact-email"],
|
|
726
|
+
contactPhone: args["contact-phone"],
|
|
727
|
+
demoAccountName: args["demo-account-name"],
|
|
728
|
+
demoAccountPassword: args["demo-account-password"],
|
|
729
|
+
demoAccountRequired: args["demo-account-required"],
|
|
730
|
+
notes: args.notes,
|
|
731
|
+
})
|
|
732
|
+
},
|
|
733
|
+
})
|
|
734
|
+
|
|
735
|
+
const reviewDetailsCmd = defineCommand({
|
|
736
|
+
meta: {
|
|
737
|
+
name: "review-details",
|
|
738
|
+
description: "Manage App Store review contact info, demo account, and reviewer notes. Must be set before submission.",
|
|
739
|
+
},
|
|
740
|
+
subCommands: { get: reviewDetailsGetCmd, update: reviewDetailsUpdateCmd },
|
|
741
|
+
})
|
|
742
|
+
|
|
743
|
+
// =============================================================================
|
|
744
|
+
// REVIEW SUBMISSION
|
|
745
|
+
// =============================================================================
|
|
746
|
+
|
|
747
|
+
const reviewSubmissionListCmd = defineCommand({
|
|
748
|
+
meta: { name: "list", description: "List all review submissions for an app." },
|
|
749
|
+
args: {
|
|
750
|
+
"app-id": { type: "string", required: true, description: "App ID. Use: asc apps list" },
|
|
751
|
+
output: { type: "string", alias: "o", description: "Output format: table | json" },
|
|
752
|
+
},
|
|
753
|
+
async run({ args }) { await reviewSubmissionList({ appId: args["app-id"], output: args.output }) },
|
|
754
|
+
})
|
|
755
|
+
|
|
756
|
+
const reviewSubmissionCreateCmd = defineCommand({
|
|
757
|
+
meta: { name: "create", description: "Create a new review submission. Add items (versions) then call submit to trigger review." },
|
|
758
|
+
args: {
|
|
759
|
+
"app-id": { type: "string", required: true, description: "App ID. Use: asc apps list" },
|
|
760
|
+
platform: { type: "string", description: "Platform: IOS (default) | MAC_OS | TV_OS | VISION_OS" },
|
|
761
|
+
},
|
|
762
|
+
async run({ args }) { await reviewSubmissionCreate({ appId: args["app-id"], platform: args.platform }) },
|
|
763
|
+
})
|
|
764
|
+
|
|
765
|
+
const reviewSubmissionGetCmd = defineCommand({
|
|
766
|
+
meta: { name: "get", description: "Get status and details of a review submission." },
|
|
767
|
+
args: {
|
|
768
|
+
id: { type: "positional", required: true, description: "Submission ID. Use: asc review-submission list" },
|
|
769
|
+
output: { type: "string", alias: "o", description: "Output format: table | json" },
|
|
770
|
+
},
|
|
771
|
+
async run({ args }) { await reviewSubmissionGet(args.id, args.output) },
|
|
772
|
+
})
|
|
773
|
+
|
|
774
|
+
const reviewSubmissionSubmitCmd = defineCommand({
|
|
775
|
+
meta: { name: "submit", description: "Submit for review. Sets submitted=true — triggers Apple review. Ensure metadata and screenshots are complete first." },
|
|
776
|
+
args: {
|
|
777
|
+
"submission-id": { type: "string", required: true, description: "Submission ID. Use: asc review-submission create" },
|
|
778
|
+
},
|
|
779
|
+
async run({ args }) { await reviewSubmissionSubmit(args["submission-id"]) },
|
|
780
|
+
})
|
|
781
|
+
|
|
782
|
+
const reviewSubmissionCancelCmd = defineCommand({
|
|
783
|
+
meta: { name: "cancel", description: "Cancel a pending review submission." },
|
|
784
|
+
args: {
|
|
785
|
+
"submission-id": { type: "string", required: true, description: "Submission ID" },
|
|
786
|
+
},
|
|
787
|
+
async run({ args }) { await reviewSubmissionCancel(args["submission-id"]) },
|
|
788
|
+
})
|
|
789
|
+
|
|
790
|
+
const reviewSubmissionItemsListCmd = defineCommand({
|
|
791
|
+
meta: { name: "list", description: "List items (versions) attached to a review submission." },
|
|
792
|
+
args: {
|
|
793
|
+
"submission-id": { type: "string", required: true, description: "Submission ID" },
|
|
794
|
+
output: { type: "string", alias: "o", description: "Output format: table | json" },
|
|
795
|
+
},
|
|
796
|
+
async run({ args }) { await reviewSubmissionItemsList({ submissionId: args["submission-id"], output: args.output }) },
|
|
797
|
+
})
|
|
798
|
+
|
|
799
|
+
const reviewSubmissionItemAddCmd = defineCommand({
|
|
800
|
+
meta: { name: "add", description: "Add an app store version to a review submission." },
|
|
801
|
+
args: {
|
|
802
|
+
"submission-id": { type: "string", required: true, description: "Submission ID" },
|
|
803
|
+
"app-store-version-id": { type: "string", required: true, description: "Version ID. Use: asc versions list" },
|
|
804
|
+
},
|
|
805
|
+
async run({ args }) {
|
|
806
|
+
await reviewSubmissionItemAdd({ submissionId: args["submission-id"], appStoreVersionId: args["app-store-version-id"] })
|
|
807
|
+
},
|
|
808
|
+
})
|
|
809
|
+
|
|
810
|
+
const reviewSubmissionItemDeleteCmd = defineCommand({
|
|
811
|
+
meta: { name: "delete", description: "Remove an item from a review submission." },
|
|
812
|
+
args: {
|
|
813
|
+
id: { type: "positional", required: true, description: "Item ID. Use: asc review-submission items list" },
|
|
814
|
+
},
|
|
815
|
+
async run({ args }) { await reviewSubmissionItemDelete(args.id) },
|
|
816
|
+
})
|
|
817
|
+
|
|
818
|
+
const reviewSubmissionCmd = defineCommand({
|
|
819
|
+
meta: {
|
|
820
|
+
name: "review-submission",
|
|
821
|
+
description: [
|
|
822
|
+
"Manage App Store review submissions (modern API).",
|
|
823
|
+
"Workflow: create → items add → submit",
|
|
824
|
+
" asc review-submission create --app-id <id>",
|
|
825
|
+
" asc review-submission items add --submission-id <id> --app-store-version-id <id>",
|
|
826
|
+
" asc review-submission submit --submission-id <id>",
|
|
827
|
+
].join("\n"),
|
|
828
|
+
},
|
|
829
|
+
subCommands: {
|
|
830
|
+
list: reviewSubmissionListCmd,
|
|
831
|
+
create: reviewSubmissionCreateCmd,
|
|
832
|
+
get: reviewSubmissionGetCmd,
|
|
833
|
+
submit: reviewSubmissionSubmitCmd,
|
|
834
|
+
cancel: reviewSubmissionCancelCmd,
|
|
835
|
+
items: defineCommand({
|
|
836
|
+
meta: { name: "items", description: "Manage items (versions) in a review submission" },
|
|
837
|
+
subCommands: { list: reviewSubmissionItemsListCmd, add: reviewSubmissionItemAddCmd, delete: reviewSubmissionItemDeleteCmd },
|
|
838
|
+
}),
|
|
839
|
+
},
|
|
840
|
+
})
|
|
841
|
+
|
|
842
|
+
// =============================================================================
|
|
843
|
+
// PHASED RELEASE
|
|
844
|
+
// =============================================================================
|
|
845
|
+
|
|
846
|
+
const phasedReleaseGetCmd = defineCommand({
|
|
847
|
+
meta: { name: "get", description: "Get phased release status for a version. Shows current rollout day and state." },
|
|
848
|
+
args: {
|
|
849
|
+
"version-id": { type: "string", alias: "v", required: true, description: "Version ID. Use: asc versions list" },
|
|
850
|
+
output: { type: "string", alias: "o", description: "Output format: table | json" },
|
|
851
|
+
},
|
|
852
|
+
async run({ args }) { await phasedReleaseGet(args["version-id"], args.output) },
|
|
853
|
+
})
|
|
854
|
+
|
|
855
|
+
const phasedReleaseCreateCmd = defineCommand({
|
|
856
|
+
meta: { name: "create", description: "Enable phased (gradual) rollout for a version. Rolls out over 7 days: 1% → 2% → 5% → 10% → 20% → 50% → 100%." },
|
|
857
|
+
args: {
|
|
858
|
+
"version-id": { type: "string", alias: "v", required: true, description: "Version ID. Use: asc versions list" },
|
|
859
|
+
state: { type: "string", description: "Initial state: INACTIVE (default) | ACTIVE | PAUSED" },
|
|
860
|
+
},
|
|
861
|
+
async run({ args }) { await phasedReleaseCreate({ versionId: args["version-id"], state: args.state }) },
|
|
862
|
+
})
|
|
863
|
+
|
|
864
|
+
const phasedReleaseUpdateCmd = defineCommand({
|
|
865
|
+
meta: { name: "update", description: "Change phased release state. PAUSED halts rollout, ACTIVE resumes, COMPLETE skips to 100%." },
|
|
866
|
+
args: {
|
|
867
|
+
id: { type: "positional", required: true, description: "Phased release ID. Use: asc phased-release get --version-id <id>" },
|
|
868
|
+
state: { type: "string", required: true, description: "New state: INACTIVE | ACTIVE | PAUSED | COMPLETE" },
|
|
869
|
+
},
|
|
870
|
+
async run({ args }) { await phasedReleaseUpdate({ phasedReleaseId: args.id, state: args.state }) },
|
|
871
|
+
})
|
|
872
|
+
|
|
873
|
+
const phasedReleaseDeleteCmd = defineCommand({
|
|
874
|
+
meta: { name: "delete", description: "Remove phased release configuration from a version." },
|
|
875
|
+
args: {
|
|
876
|
+
id: { type: "positional", required: true, description: "Phased release ID. Use: asc phased-release get --version-id <id>" },
|
|
877
|
+
},
|
|
878
|
+
async run({ args }) { await phasedReleaseDelete(args.id) },
|
|
879
|
+
})
|
|
880
|
+
|
|
881
|
+
const phasedReleaseCmd = defineCommand({
|
|
882
|
+
meta: {
|
|
883
|
+
name: "phased-release",
|
|
884
|
+
description: "Manage phased (gradual) rollout for App Store versions. Rolls out over 7 days to increasing percentages of users.",
|
|
885
|
+
},
|
|
886
|
+
subCommands: { get: phasedReleaseGetCmd, create: phasedReleaseCreateCmd, update: phasedReleaseUpdateCmd, delete: phasedReleaseDeleteCmd },
|
|
887
|
+
})
|
|
888
|
+
|
|
582
889
|
// =============================================================================
|
|
583
890
|
// REVIEWS (Customer Reviews)
|
|
584
891
|
// =============================================================================
|
|
@@ -1594,8 +1901,13 @@ const main = defineCommand({
|
|
|
1594
1901
|
apps: appsCmd,
|
|
1595
1902
|
builds: buildsCmd,
|
|
1596
1903
|
versions: versionsCmd,
|
|
1904
|
+
"release-request": releaseRequestCmd,
|
|
1597
1905
|
testflight: testflightCmd,
|
|
1598
1906
|
metadata: metadataCmd,
|
|
1907
|
+
localizations: localizationsCmd,
|
|
1908
|
+
"review-details": reviewDetailsCmd,
|
|
1909
|
+
"review-submission": reviewSubmissionCmd,
|
|
1910
|
+
"phased-release": phasedReleaseCmd,
|
|
1599
1911
|
reviews: reviewsCmd,
|
|
1600
1912
|
pricing: pricingCmd,
|
|
1601
1913
|
availability: availabilityCmd,
|