@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.
@@ -1,22 +1,25 @@
1
- import { ascFetch, ascFetchAll } from "../api/client.ts"
1
+ import {
2
+ appsAppPriceScheduleGetToOneRelated,
3
+ appPriceSchedulesCreateInstance,
4
+ appsAppPricePointsGetToManyRelated,
5
+ territoriesGetCollection,
6
+ } from "../api/generated/sdk.gen.ts"
7
+ import { throwOnError } from "../api/client.ts"
2
8
  import { detectFormat, formatDate, printJSON, printSuccess, printTable } from "../utils/output.ts"
3
9
 
4
10
  export async function pricingScheduleGet(appId: string, opts: { output?: string } = {}): Promise<void> {
5
- // Fetch price schedule with related resources included
6
- const result = await ascFetch<{
7
- data: { id: string; type: string }
8
- included?: Array<{ type: string; id: string; attributes?: Record<string, unknown> }>
9
- }>(`/v1/apps/${appId}/appPriceSchedule`, {
10
- params: {
11
- include: "manualPrices,automaticPrices,baseTerritory",
12
- "fields[territories]": "currency,name",
11
+ const result = await appsAppPriceScheduleGetToOneRelated({
12
+ path: { id: appId },
13
+ query: {
14
+ include: ["manualPrices", "automaticPrices", "baseTerritory"],
15
+ "fields[territories]": ["currency"],
13
16
  },
14
17
  })
15
- const body = result.data
18
+ const body = throwOnError(result)
16
19
  const fmt = detectFormat(opts.output)
17
20
  if (fmt === "json") { printJSON(body); return }
18
21
  console.log(`Schedule ID: ${body.data.id}`)
19
- const included = body.included ?? []
22
+ const included = (body as { data: unknown; included?: Array<{ type: string; id: string; attributes?: Record<string, unknown> }> }).included ?? []
20
23
  const base = included.find(r => r.type === "territories")
21
24
  if (base) {
22
25
  const attrs = base.attributes as { currency?: string; name?: string } | undefined
@@ -40,8 +43,7 @@ export async function pricingScheduleSet(opts: {
40
43
  baseTerritory: string
41
44
  pricePointId: string
42
45
  }): Promise<void> {
43
- await ascFetch("/v1/appPriceSchedules", {
44
- method: "POST",
46
+ await appPriceSchedulesCreateInstance({
45
47
  body: {
46
48
  data: {
47
49
  type: "appPriceSchedules",
@@ -60,7 +62,7 @@ export async function pricingScheduleSet(opts: {
60
62
  appPricePoint: { data: { type: "appPricePoints", id: opts.pricePointId } },
61
63
  territory: { data: { type: "territories", id: opts.baseTerritory } },
62
64
  },
63
- },
65
+ } as never,
64
66
  ],
65
67
  },
66
68
  })
@@ -72,39 +74,41 @@ export async function pricingPointsList(opts: {
72
74
  territory?: string
73
75
  output?: string
74
76
  }): Promise<void> {
75
- const params: Record<string, string> = {
76
- "fields[appPricePoints]": "customerPrice,proceeds,territory",
77
- limit: "200",
77
+ const query: Record<string, unknown> = {
78
+ "fields[appPricePoints]": ["customerPrice", "proceeds", "territory"],
79
+ limit: 200,
78
80
  }
79
- if (opts.territory) params["filter[territory]"] = opts.territory
80
- const items = await ascFetchAll<{
81
- id: string
82
- attributes: { customerPrice?: string; proceeds?: string; territory?: unknown }
83
- }>(`/v1/apps/${opts.appId}/appPricePoints`, { params })
81
+ if (opts.territory) query["filter[territory]"] = [opts.territory]
82
+
83
+ const result = await appsAppPricePointsGetToManyRelated({
84
+ path: { id: opts.appId },
85
+ query: query as never,
86
+ })
87
+ const data = throwOnError(result)
88
+ const items = data.data
84
89
  const fmt = detectFormat(opts.output)
85
90
  if (fmt === "json") { printJSON(items); return }
86
91
  printTable(
87
92
  ["ID", "Customer Price", "Proceeds", "Territory"],
88
93
  items.map(p => [
89
94
  p.id,
90
- p.attributes.customerPrice ?? "-",
91
- p.attributes.proceeds ?? "-",
92
- String(p.attributes.territory ?? "-"),
95
+ (p.attributes as Record<string, unknown>)?.customerPrice as string ?? "-",
96
+ (p.attributes as Record<string, unknown>)?.proceeds as string ?? "-",
97
+ String((p.attributes as Record<string, unknown>)?.territory ?? "-"),
93
98
  ]),
94
99
  `Price Points (${items.length})`,
95
100
  )
96
101
  }
97
102
 
98
103
  export async function territoriesList(opts: { output?: string } = {}): Promise<void> {
99
- const items = await ascFetchAll<{
100
- id: string
101
- attributes: { currency?: string; name?: string }
102
- }>("/v1/territories")
104
+ const result = await territoriesGetCollection()
105
+ const data = throwOnError(result)
106
+ const items = data.data
103
107
  const fmt = detectFormat(opts.output)
104
108
  if (fmt === "json") { printJSON(items); return }
105
109
  printTable(
106
110
  ["Territory Code", "Name", "Currency"],
107
- items.map(t => [t.id, t.attributes.name ?? "-", t.attributes.currency ?? "-"]),
111
+ items.map(t => [t.id, (t.attributes as { currency?: string })?.currency ?? "-", ""]),
108
112
  `Territories (${items.length})`,
109
113
  )
110
114
  }
@@ -1,4 +1,8 @@
1
- import { ascFetch, ascFetchAll } from "../api/client.ts"
1
+ import {
2
+ appsAnalyticsReportRequestsGetToManyRelated,
3
+ analyticsReportRequestsCreateInstance,
4
+ } from "../api/generated/sdk.gen.ts"
5
+ import { throwOnError } from "../api/client.ts"
2
6
  import { detectFormat, formatDate, printJSON, printTable } from "../utils/output.ts"
3
7
 
4
8
  // ---- Sales and Finance Reports ----
@@ -84,15 +88,14 @@ export async function analyticsReportsList(opts: {
84
88
  appId: string
85
89
  output?: string
86
90
  }): Promise<void> {
87
- const items = await ascFetchAll<{
88
- id: string
89
- attributes: { name?: string; category?: string }
90
- }>(`/v1/apps/${opts.appId}/analyticsReportRequests`)
91
+ const result = await appsAnalyticsReportRequestsGetToManyRelated({ path: { id: opts.appId } })
92
+ const data = throwOnError(result)
93
+ const items = data.data
91
94
  const fmt = detectFormat(opts.output)
92
95
  if (fmt === "json") { printJSON(items); return }
93
96
  printTable(
94
97
  ["Request ID", "State"],
95
- items.map(r => [r.id, String(r.attributes.name ?? r.id)]),
98
+ items.map(r => [r.id, String(r.attributes?.accessType ?? r.id)]),
96
99
  `Analytics Report Requests (${items.length})`,
97
100
  )
98
101
  }
@@ -101,16 +104,16 @@ export async function analyticsReportRequest(opts: {
101
104
  appId: string
102
105
  category: string
103
106
  }): Promise<void> {
104
- const result = await ascFetch<{ data: { id: string } }>("/v1/analyticsReportRequests", {
105
- method: "POST",
107
+ const result = await analyticsReportRequestsCreateInstance({
106
108
  body: {
107
109
  data: {
108
110
  type: "analyticsReportRequests",
109
- attributes: { accessType: opts.category },
111
+ attributes: { accessType: opts.category as never },
110
112
  relationships: { app: { data: { type: "apps", id: opts.appId } } },
111
113
  },
112
114
  },
113
115
  })
114
- console.log(`Analytics report request created: ${result.data.data.id}`)
116
+ const data = throwOnError(result)
117
+ console.log(`Analytics report request created: ${data.data.id}`)
115
118
  console.log("Check back later with: asc reports analytics-list --app-id <id>")
116
119
  }
@@ -0,0 +1,79 @@
1
+ import {
2
+ appStoreVersionsAppStoreReviewDetailGetToOneRelated,
3
+ appStoreReviewDetailsCreateInstance,
4
+ appStoreReviewDetailsUpdateInstance,
5
+ } from "../api/generated/sdk.gen.ts"
6
+ import { throwOnError, ASCError } from "../api/client.ts"
7
+ import { detectFormat, printJSON, printSuccess } from "../utils/output.ts"
8
+
9
+ export async function reviewDetailsGet(versionId: string, output?: string): Promise<void> {
10
+ const result = await appStoreVersionsAppStoreReviewDetailGetToOneRelated({ path: { id: versionId } })
11
+ const data = throwOnError(result)
12
+ const d = data.data
13
+
14
+ const fmt = detectFormat(output)
15
+ if (fmt === "json") { printJSON({ id: d.id, ...d.attributes }); return }
16
+ console.log(`ID: ${d.id}`)
17
+ console.log(`Contact: ${[d.attributes?.contactFirstName, d.attributes?.contactLastName].filter(Boolean).join(" ") || "-"}`)
18
+ console.log(`Contact Email: ${d.attributes?.contactEmail ?? "-"}`)
19
+ console.log(`Contact Phone: ${d.attributes?.contactPhone ?? "-"}`)
20
+ console.log(`Demo Account: ${d.attributes?.demoAccountName ?? "-"}`)
21
+ console.log(`Demo Account Required:${d.attributes?.demoAccountRequired ? " yes" : " no"}`)
22
+ console.log(`Notes: ${d.attributes?.notes ?? "-"}`)
23
+ }
24
+
25
+ export async function reviewDetailsUpdate(opts: {
26
+ versionId: string
27
+ contactFirstName?: string
28
+ contactLastName?: string
29
+ contactEmail?: string
30
+ contactPhone?: string
31
+ demoAccountName?: string
32
+ demoAccountPassword?: string
33
+ demoAccountRequired?: boolean
34
+ notes?: string
35
+ }): Promise<void> {
36
+ // Try to get existing review detail ID
37
+ let existingId: string | undefined
38
+ try {
39
+ const existing = await appStoreVersionsAppStoreReviewDetailGetToOneRelated({ path: { id: opts.versionId } })
40
+ const data = throwOnError(existing)
41
+ existingId = data.data.id
42
+ } catch (err) {
43
+ if (!(err instanceof ASCError) || err.status !== 404) throw err
44
+ }
45
+
46
+ const attributes = {
47
+ contactFirstName: opts.contactFirstName,
48
+ contactLastName: opts.contactLastName,
49
+ contactEmail: opts.contactEmail,
50
+ contactPhone: opts.contactPhone,
51
+ demoAccountName: opts.demoAccountName,
52
+ demoAccountPassword: opts.demoAccountPassword,
53
+ demoAccountRequired: opts.demoAccountRequired,
54
+ notes: opts.notes,
55
+ }
56
+
57
+ if (existingId) {
58
+ const result = await appStoreReviewDetailsUpdateInstance({
59
+ path: { id: existingId },
60
+ body: { data: { type: "appStoreReviewDetails", id: existingId, attributes } },
61
+ })
62
+ throwOnError(result)
63
+ printSuccess("Review details updated")
64
+ } else {
65
+ const result = await appStoreReviewDetailsCreateInstance({
66
+ body: {
67
+ data: {
68
+ type: "appStoreReviewDetails",
69
+ attributes,
70
+ relationships: {
71
+ appStoreVersion: { data: { type: "appStoreVersions", id: opts.versionId } },
72
+ },
73
+ },
74
+ },
75
+ })
76
+ throwOnError(result)
77
+ printSuccess("Review details created")
78
+ }
79
+ }
@@ -0,0 +1,143 @@
1
+ import {
2
+ reviewSubmissionsGetCollection,
3
+ reviewSubmissionsCreateInstance,
4
+ reviewSubmissionsGetInstance,
5
+ reviewSubmissionsUpdateInstance,
6
+ reviewSubmissionsItemsGetToManyRelated,
7
+ reviewSubmissionItemsCreateInstance,
8
+ reviewSubmissionItemsDeleteInstance,
9
+ } from "../api/generated/sdk.gen.ts"
10
+ import { throwOnError } from "../api/client.ts"
11
+ import { detectFormat, formatDate, printJSON, printSuccess, printTable } from "../utils/output.ts"
12
+
13
+ export async function reviewSubmissionList(opts: {
14
+ appId: string
15
+ output?: string
16
+ }): Promise<void> {
17
+ const result = await reviewSubmissionsGetCollection({
18
+ query: { "filter[app]": [opts.appId] },
19
+ })
20
+ const data = throwOnError(result)
21
+ const items = data.data
22
+
23
+ const fmt = detectFormat(opts.output)
24
+ if (fmt === "json") { printJSON(items.map(s => ({ id: s.id, ...s.attributes }))); return }
25
+ printTable(
26
+ ["ID", "Platform", "State", "Date"],
27
+ items.map(s => [
28
+ s.id,
29
+ s.attributes?.platform ?? "-",
30
+ s.attributes?.state ?? "-",
31
+ formatDate(s.attributes?.submittedDate),
32
+ ]),
33
+ `Review Submissions (${items.length})`,
34
+ )
35
+ }
36
+
37
+ export async function reviewSubmissionCreate(opts: {
38
+ appId: string
39
+ platform?: string
40
+ }): Promise<void> {
41
+ const platform = (opts.platform ?? "IOS").toUpperCase() as "IOS" | "MAC_OS" | "TV_OS" | "VISION_OS"
42
+ const result = await reviewSubmissionsCreateInstance({
43
+ body: {
44
+ data: {
45
+ type: "reviewSubmissions",
46
+ attributes: { platform },
47
+ relationships: {
48
+ app: { data: { type: "apps", id: opts.appId } },
49
+ },
50
+ },
51
+ },
52
+ })
53
+ const data = throwOnError(result)
54
+ const s = data.data
55
+ printSuccess(`Review submission created — ID: ${s.id}`)
56
+ console.log(` State: ${s.attributes?.state ?? "-"}`)
57
+ console.log(` Platform: ${platform}`)
58
+ }
59
+
60
+ export async function reviewSubmissionGet(submissionId: string, output?: string): Promise<void> {
61
+ const result = await reviewSubmissionsGetInstance({ path: { id: submissionId } })
62
+ const data = throwOnError(result)
63
+ const s = data.data
64
+
65
+ const fmt = detectFormat(output)
66
+ if (fmt === "json") { printJSON({ id: s.id, ...s.attributes }); return }
67
+ console.log(`ID: ${s.id}`)
68
+ console.log(`Platform: ${s.attributes?.platform ?? "-"}`)
69
+ console.log(`State: ${s.attributes?.state ?? "-"}`)
70
+ console.log(`Date: ${formatDate(s.attributes?.submittedDate)}`)
71
+ }
72
+
73
+ export async function reviewSubmissionSubmit(submissionId: string): Promise<void> {
74
+ const result = await reviewSubmissionsUpdateInstance({
75
+ path: { id: submissionId },
76
+ body: {
77
+ data: {
78
+ type: "reviewSubmissions",
79
+ id: submissionId,
80
+ attributes: { submitted: true },
81
+ },
82
+ },
83
+ })
84
+ throwOnError(result)
85
+ printSuccess(`Submission ${submissionId} submitted for review`)
86
+ }
87
+
88
+ export async function reviewSubmissionCancel(submissionId: string): Promise<void> {
89
+ const result = await reviewSubmissionsUpdateInstance({
90
+ path: { id: submissionId },
91
+ body: {
92
+ data: {
93
+ type: "reviewSubmissions",
94
+ id: submissionId,
95
+ attributes: { canceled: true },
96
+ },
97
+ },
98
+ })
99
+ throwOnError(result)
100
+ printSuccess(`Submission ${submissionId} cancelled`)
101
+ }
102
+
103
+ export async function reviewSubmissionItemsList(opts: {
104
+ submissionId: string
105
+ output?: string
106
+ }): Promise<void> {
107
+ const result = await reviewSubmissionsItemsGetToManyRelated({ path: { id: opts.submissionId } })
108
+ const data = throwOnError(result)
109
+ const items = data.data
110
+
111
+ const fmt = detectFormat(opts.output)
112
+ if (fmt === "json") { printJSON(items.map(i => ({ id: i.id, ...i.attributes }))); return }
113
+ printTable(
114
+ ["Item ID", "State"],
115
+ items.map(i => [i.id, i.attributes?.state ?? "-"]),
116
+ `Submission Items (${items.length})`,
117
+ )
118
+ }
119
+
120
+ export async function reviewSubmissionItemAdd(opts: {
121
+ submissionId: string
122
+ appStoreVersionId: string
123
+ }): Promise<void> {
124
+ const result = await reviewSubmissionItemsCreateInstance({
125
+ body: {
126
+ data: {
127
+ type: "reviewSubmissionItems",
128
+ relationships: {
129
+ reviewSubmission: { data: { type: "reviewSubmissions", id: opts.submissionId } },
130
+ appStoreVersion: { data: { type: "appStoreVersions", id: opts.appStoreVersionId } },
131
+ },
132
+ },
133
+ },
134
+ })
135
+ const data = throwOnError(result)
136
+ printSuccess(`Item added — ID: ${data.data.id}`)
137
+ }
138
+
139
+ export async function reviewSubmissionItemDelete(itemId: string): Promise<void> {
140
+ const result = await reviewSubmissionItemsDeleteInstance({ path: { id: itemId } })
141
+ throwOnError(result)
142
+ printSuccess(`Submission item ${itemId} removed`)
143
+ }
@@ -1,20 +1,26 @@
1
- import { ascFetch, ascFetchAll } from "../api/client.ts"
2
- import type { CustomerReview, CustomerReviewResponse } from "../api/types.ts"
1
+ import {
2
+ appsCustomerReviewsGetToManyRelated,
3
+ customerReviewsGetInstance,
4
+ customerReviewsResponseGetToOneRelated,
5
+ customerReviewResponsesCreateInstance,
6
+ customerReviewResponsesDeleteInstance,
7
+ } from "../api/generated/sdk.gen.ts"
8
+ import { throwOnError, ascFetch } from "../api/client.ts"
3
9
  import { detectFormat, formatDate, printJSON, printSuccess, printTable, truncate } from "../utils/output.ts"
4
10
 
5
11
  export async function reviewsList(opts: {
6
12
  appId: string
7
13
  output?: string
8
14
  }): Promise<void> {
9
- const reviews = await ascFetchAll<CustomerReview>(
10
- `/v1/apps/${opts.appId}/customerReviews`,
11
- {
12
- params: {
13
- "fields[customerReviews]": "rating,title,body,reviewerNickname,createdDate,territory",
14
- "sort": "-createdDate",
15
- },
15
+ const result = await appsCustomerReviewsGetToManyRelated({
16
+ path: { id: opts.appId },
17
+ query: {
18
+ "fields[customerReviews]": ["rating", "title", "body", "reviewerNickname", "createdDate", "territory"],
19
+ sort: ["-createdDate"],
16
20
  },
17
- )
21
+ })
22
+ const data = throwOnError(result)
23
+ const reviews = data.data
18
24
 
19
25
  const fmt = detectFormat(opts.output)
20
26
  if (fmt === "json") {
@@ -26,18 +32,19 @@ export async function reviewsList(opts: {
26
32
  ["ID", "Rating", "Title", "Body", "Date"],
27
33
  reviews.map((r) => [
28
34
  r.id,
29
- "★".repeat(r.attributes.rating) + "☆".repeat(5 - r.attributes.rating),
30
- truncate(r.attributes.title ?? "-", 30),
31
- truncate(r.attributes.body ?? "-", 50),
32
- formatDate(r.attributes.createdDate),
35
+ "★".repeat(r.attributes?.rating ?? 0) + "☆".repeat(5 - (r.attributes?.rating ?? 0)),
36
+ truncate(r.attributes?.title ?? "-", 30),
37
+ truncate(r.attributes?.body ?? "-", 50),
38
+ formatDate(r.attributes?.createdDate ?? ""),
33
39
  ]),
34
40
  `Reviews (${reviews.length})`,
35
41
  )
36
42
  }
37
43
 
38
44
  export async function reviewsGet(reviewId: string, opts: { output?: string } = {}): Promise<void> {
39
- const res = await ascFetch<CustomerReview>(`/v1/customerReviews/${reviewId}`)
40
- const r = res.data
45
+ const result = await customerReviewsGetInstance({ path: { id: reviewId } })
46
+ const data = throwOnError(result)
47
+ const r = data.data
41
48
 
42
49
  const fmt = detectFormat(opts.output)
43
50
  if (fmt === "json") {
@@ -46,12 +53,12 @@ export async function reviewsGet(reviewId: string, opts: { output?: string } = {
46
53
  }
47
54
 
48
55
  console.log(`ID: ${r.id}`)
49
- console.log(`Rating: ${"★".repeat(r.attributes.rating)}${"☆".repeat(5 - r.attributes.rating)}`)
50
- console.log(`Title: ${r.attributes.title ?? "-"}`)
51
- console.log(`Body: ${r.attributes.body ?? "-"}`)
52
- console.log(`Author: ${r.attributes.reviewerNickname ?? "-"}`)
53
- console.log(`Date: ${formatDate(r.attributes.createdDate)}`)
54
- console.log(`Territory:${r.attributes.territory ?? "-"}`)
56
+ console.log(`Rating: ${"★".repeat(r.attributes?.rating ?? 0)}${"☆".repeat(5 - (r.attributes?.rating ?? 0))}`)
57
+ console.log(`Title: ${r.attributes?.title ?? "-"}`)
58
+ console.log(`Body: ${r.attributes?.body ?? "-"}`)
59
+ console.log(`Author: ${r.attributes?.reviewerNickname ?? "-"}`)
60
+ console.log(`Date: ${formatDate(r.attributes?.createdDate ?? "")}`)
61
+ console.log(`Territory:${r.attributes?.territory ?? "-"}`)
55
62
  }
56
63
 
57
64
  export async function reviewsRespond(opts: {
@@ -59,25 +66,24 @@ export async function reviewsRespond(opts: {
59
66
  message: string
60
67
  }): Promise<void> {
61
68
  // Check if a response already exists
62
- const existingRes = await ascFetch<CustomerReviewResponse | null>(
63
- `/v1/customerReviews/${opts.reviewId}/response`,
64
- ).catch(() => null)
69
+ const existingRes = await customerReviewsResponseGetToOneRelated({ path: { id: opts.reviewId } }).catch(() => null)
70
+ const existingData = existingRes ? throwOnError(existingRes) : null
65
71
 
66
- if (existingRes?.data) {
67
- await ascFetch(`/v1/customerReviewResponses/${existingRes.data.id}`, {
72
+ if (existingData?.data) {
73
+ // No SDK update function for customerReviewResponses — use ascFetch for PATCH
74
+ await ascFetch(`/v1/customerReviewResponses/${existingData.data.id}`, {
68
75
  method: "PATCH",
69
76
  body: {
70
77
  data: {
71
78
  type: "customerReviewResponses",
72
- id: existingRes.data.id,
79
+ id: existingData.data.id,
73
80
  attributes: { responseBody: opts.message },
74
81
  },
75
82
  },
76
83
  })
77
84
  printSuccess("Review response updated")
78
85
  } else {
79
- await ascFetch("/v1/customerReviewResponses", {
80
- method: "POST",
86
+ await customerReviewResponsesCreateInstance({
81
87
  body: {
82
88
  data: {
83
89
  type: "customerReviewResponses",
@@ -1,4 +1,12 @@
1
- import { ascFetch, ascFetchAll } from "../api/client.ts"
1
+ import {
2
+ appStoreVersionLocalizationsAppScreenshotSetsGetToManyRelated,
3
+ appScreenshotSetsAppScreenshotsGetToManyRelated,
4
+ appScreenshotsCreateInstance,
5
+ appScreenshotsUpdateInstance,
6
+ appScreenshotsDeleteInstance,
7
+ appStoreVersionLocalizationsAppPreviewSetsGetToManyRelated,
8
+ } from "../api/generated/sdk.gen.ts"
9
+ import { throwOnError } from "../api/client.ts"
2
10
  import { readFileSync } from "fs"
3
11
  import { detectFormat, printJSON, printSuccess, printTable } from "../utils/output.ts"
4
12
 
@@ -8,20 +16,17 @@ export async function screenshotSetsList(opts: {
8
16
  versionLocalizationId: string
9
17
  output?: string
10
18
  }): Promise<void> {
11
- const items = await ascFetchAll<{
12
- id: string
13
- attributes: {
14
- screenshotDisplayType?: string
15
- appScreenshots?: { meta?: { total?: number } }
16
- }
17
- }>(`/v1/appStoreVersionLocalizations/${opts.versionLocalizationId}/appScreenshotSets`, {
18
- params: { "fields[appScreenshotSets]": "screenshotDisplayType,appScreenshots" },
19
+ const result = await appStoreVersionLocalizationsAppScreenshotSetsGetToManyRelated({
20
+ path: { id: opts.versionLocalizationId },
21
+ query: { "fields[appScreenshotSets]": ["screenshotDisplayType", "appScreenshots"] },
19
22
  })
23
+ const data = throwOnError(result)
24
+ const items = data.data
20
25
  const fmt = detectFormat(opts.output)
21
26
  if (fmt === "json") { printJSON(items); return }
22
27
  printTable(
23
28
  ["Set ID", "Display Type"],
24
- items.map(s => [s.id, s.attributes.screenshotDisplayType ?? "-"]),
29
+ items.map(s => [s.id, s.attributes?.screenshotDisplayType ?? "-"]),
25
30
  `Screenshot Sets (${items.length})`,
26
31
  )
27
32
  }
@@ -30,24 +35,19 @@ export async function screenshotsList(opts: {
30
35
  setId: string
31
36
  output?: string
32
37
  }): Promise<void> {
33
- const items = await ascFetchAll<{
34
- id: string
35
- attributes: {
36
- fileName?: string
37
- fileSize?: number
38
- sourceFileChecksum?: string
39
- assetDeliveryState?: { state?: string }
40
- imageAsset?: { templateUrl?: string; width?: number; height?: number }
41
- }
42
- }>(`/v1/appScreenshotSets/${opts.setId}/appScreenshots`)
38
+ const result = await appScreenshotSetsAppScreenshotsGetToManyRelated({
39
+ path: { id: opts.setId },
40
+ })
41
+ const data = throwOnError(result)
42
+ const items = data.data
43
43
  const fmt = detectFormat(opts.output)
44
44
  if (fmt === "json") { printJSON(items); return }
45
45
  printTable(
46
46
  ["ID", "File Name", "State"],
47
47
  items.map(s => [
48
48
  s.id,
49
- s.attributes.fileName ?? "-",
50
- s.attributes.assetDeliveryState?.state ?? "-",
49
+ s.attributes?.fileName ?? "-",
50
+ s.attributes?.assetDeliveryState?.state ?? "-",
51
51
  ]),
52
52
  `Screenshots (${items.length})`,
53
53
  )
@@ -62,21 +62,7 @@ export async function screenshotCreate(opts: {
62
62
  const fileSize = fileData.length
63
63
 
64
64
  // Step 1: Reserve asset
65
- const reserve = await ascFetch<{
66
- data: {
67
- id: string
68
- attributes: {
69
- uploadOperations?: Array<{
70
- url: string
71
- method: string
72
- offset: number
73
- length: number
74
- requestHeaders?: Array<{ name: string; value: string }>
75
- }>
76
- }
77
- }
78
- }>("/v1/appScreenshots", {
79
- method: "POST",
65
+ const reserve = await appScreenshotsCreateInstance({
80
66
  body: {
81
67
  data: {
82
68
  type: "appScreenshots",
@@ -87,21 +73,23 @@ export async function screenshotCreate(opts: {
87
73
  },
88
74
  },
89
75
  })
90
-
91
- const screenshotId = reserve.data.data.id
92
- const uploads = reserve.data.data.attributes.uploadOperations ?? []
76
+ const reserveData = throwOnError(reserve)
77
+ const screenshotId = reserveData.data.id
78
+ const uploads = reserveData.data.attributes?.uploadOperations ?? []
93
79
 
94
80
  // Step 2: Upload parts
95
81
  for (const op of uploads) {
96
- const chunk = fileData.subarray(op.offset, op.offset + op.length)
82
+ const chunk = fileData.subarray(op.offset ?? 0, (op.offset ?? 0) + (op.length ?? 0))
97
83
  const headers: Record<string, string> = { "Content-Type": "image/png" }
98
- for (const h of op.requestHeaders ?? []) headers[h.name] = h.value
99
- await fetch(op.url, { method: op.method, headers, body: chunk })
84
+ for (const h of op.requestHeaders ?? []) {
85
+ if (h.name && h.value) headers[h.name] = h.value
86
+ }
87
+ await fetch(op.url ?? "", { method: op.method ?? "PUT", headers, body: chunk })
100
88
  }
101
89
 
102
90
  // Step 3: Commit
103
- await ascFetch(`/v1/appScreenshots/${screenshotId}`, {
104
- method: "PATCH",
91
+ await appScreenshotsUpdateInstance({
92
+ path: { id: screenshotId },
105
93
  body: {
106
94
  data: {
107
95
  type: "appScreenshots",
@@ -115,7 +103,7 @@ export async function screenshotCreate(opts: {
115
103
  }
116
104
 
117
105
  export async function screenshotDelete(screenshotId: string): Promise<void> {
118
- await ascFetch(`/v1/appScreenshots/${screenshotId}`, { method: "DELETE" })
106
+ await appScreenshotsDeleteInstance({ path: { id: screenshotId } })
119
107
  printSuccess(`Screenshot ${screenshotId} deleted`)
120
108
  }
121
109
 
@@ -125,15 +113,16 @@ export async function previewSetsList(opts: {
125
113
  versionLocalizationId: string
126
114
  output?: string
127
115
  }): Promise<void> {
128
- const items = await ascFetchAll<{
129
- id: string
130
- attributes: { previewType?: string }
131
- }>(`/v1/appStoreVersionLocalizations/${opts.versionLocalizationId}/appPreviewSets`)
116
+ const result = await appStoreVersionLocalizationsAppPreviewSetsGetToManyRelated({
117
+ path: { id: opts.versionLocalizationId },
118
+ })
119
+ const data = throwOnError(result)
120
+ const items = data.data
132
121
  const fmt = detectFormat(opts.output)
133
122
  if (fmt === "json") { printJSON(items); return }
134
123
  printTable(
135
124
  ["Set ID", "Preview Type"],
136
- items.map(s => [s.id, s.attributes.previewType ?? "-"]),
125
+ items.map(s => [s.id, s.attributes?.previewType ?? "-"]),
137
126
  `Preview Sets (${items.length})`,
138
127
  )
139
128
  }