@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,60 +1,61 @@
1
- import { ascFetch, ascFetchAll } from "../api/client.ts"
1
+ import {
2
+ appsGameCenterDetailGetToOneRelated,
3
+ gameCenterDetailsGameCenterAchievementsGetToManyRelated,
4
+ gameCenterAchievementsGetInstance,
5
+ gameCenterDetailsGameCenterLeaderboardsGetToManyRelated,
6
+ gameCenterDetailsGameCenterLeaderboardSetsGetToManyRelated,
7
+ appsGameCenterEnabledVersionsGetToManyRelated,
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
 
12
+ async function getGameCenterDetailId(appId: string): Promise<string> {
13
+ const result = await appsGameCenterDetailGetToOneRelated({ path: { id: appId } })
14
+ const data = throwOnError(result)
15
+ return data.data.id
16
+ }
17
+
4
18
  // ---- Achievements ----
5
19
 
6
20
  export async function achievementsList(opts: {
7
21
  appId: string
8
22
  output?: string
9
23
  }): Promise<void> {
10
- const items = await ascFetchAll<{
11
- id: string
12
- attributes: {
13
- referenceName?: string
14
- points?: number
15
- showBeforeEarned?: boolean
16
- repeatable?: boolean
17
- archived?: boolean
18
- }
19
- }>(`/v1/apps/${opts.appId}/gameCenterAchievements`, {
20
- params: { "fields[gameCenterAchievements]": "referenceName,points,showBeforeEarned,repeatable,archived" },
24
+ const detailId = await getGameCenterDetailId(opts.appId)
25
+ const result = await gameCenterDetailsGameCenterAchievementsGetToManyRelated({
26
+ path: { id: detailId },
27
+ query: {
28
+ "fields[gameCenterAchievements]": ["referenceName", "points", "showBeforeEarned", "repeatable", "archived"],
29
+ },
21
30
  })
31
+ const data = throwOnError(result)
32
+ const items = data.data
22
33
  const fmt = detectFormat(opts.output)
23
34
  if (fmt === "json") { printJSON(items); return }
24
35
  printTable(
25
36
  ["ID", "Reference Name", "Points", "Repeatable"],
26
37
  items.map(a => [
27
38
  a.id,
28
- a.attributes.referenceName ?? "-",
29
- String(a.attributes.points ?? "-"),
30
- String(a.attributes.repeatable ?? "-"),
39
+ a.attributes?.referenceName ?? "-",
40
+ String(a.attributes?.points ?? "-"),
41
+ String(a.attributes?.repeatable ?? "-"),
31
42
  ]),
32
43
  `Game Center Achievements (${items.length})`,
33
44
  )
34
45
  }
35
46
 
36
47
  export async function achievementGet(achievementId: string, opts: { output?: string } = {}): Promise<void> {
37
- const result = await ascFetch<{
38
- data: {
39
- id: string
40
- attributes: {
41
- referenceName?: string
42
- points?: number
43
- showBeforeEarned?: boolean
44
- repeatable?: boolean
45
- archived?: boolean
46
- }
47
- }
48
- }>(`/v1/gameCenterAchievements/${achievementId}`)
48
+ const result = await gameCenterAchievementsGetInstance({ path: { id: achievementId } })
49
+ const data = throwOnError(result)
49
50
  const fmt = detectFormat(opts.output)
50
- if (fmt === "json") { printJSON(result.data.data); return }
51
- const a = result.data.data.attributes
52
- console.log(`ID: ${result.data.data.id}`)
53
- console.log(`Reference Name: ${a.referenceName ?? "-"}`)
54
- console.log(`Points: ${a.points ?? "-"}`)
55
- console.log(`Repeatable: ${a.repeatable ?? false}`)
56
- console.log(`Show Before Earn:${a.showBeforeEarned ?? false}`)
57
- console.log(`Archived: ${a.archived ?? false}`)
51
+ if (fmt === "json") { printJSON(data.data); return }
52
+ const a = data.data.attributes
53
+ console.log(`ID: ${data.data.id}`)
54
+ console.log(`Reference Name: ${a?.referenceName ?? "-"}`)
55
+ console.log(`Points: ${a?.points ?? "-"}`)
56
+ console.log(`Repeatable: ${a?.repeatable ?? false}`)
57
+ console.log(`Show Before Earn:${a?.showBeforeEarned ?? false}`)
58
+ console.log(`Archived: ${a?.archived ?? false}`)
58
59
  }
59
60
 
60
61
  // ---- Leaderboards ----
@@ -63,21 +64,20 @@ export async function leaderboardsList(opts: {
63
64
  appId: string
64
65
  output?: string
65
66
  }): Promise<void> {
66
- const items = await ascFetchAll<{
67
- id: string
68
- attributes: {
69
- referenceName?: string
70
- defaultFormatter?: unknown
71
- archived?: boolean
72
- }
73
- }>(`/v1/apps/${opts.appId}/gameCenterLeaderboards`, {
74
- params: { "fields[gameCenterLeaderboards]": "referenceName,defaultFormatter,archived" },
67
+ const detailId = await getGameCenterDetailId(opts.appId)
68
+ const result = await gameCenterDetailsGameCenterLeaderboardsGetToManyRelated({
69
+ path: { id: detailId },
70
+ query: {
71
+ "fields[gameCenterLeaderboards]": ["referenceName", "defaultFormatter", "archived"],
72
+ },
75
73
  })
74
+ const data = throwOnError(result)
75
+ const items = data.data
76
76
  const fmt = detectFormat(opts.output)
77
77
  if (fmt === "json") { printJSON(items); return }
78
78
  printTable(
79
79
  ["ID", "Reference Name", "Archived"],
80
- items.map(l => [l.id, l.attributes.referenceName ?? "-", String(l.attributes.archived ?? false)]),
80
+ items.map(l => [l.id, l.attributes?.referenceName ?? "-", String(l.attributes?.archived ?? false)]),
81
81
  `Leaderboards (${items.length})`,
82
82
  )
83
83
  }
@@ -88,15 +88,17 @@ export async function leaderboardSetsList(opts: {
88
88
  appId: string
89
89
  output?: string
90
90
  }): Promise<void> {
91
- const items = await ascFetchAll<{
92
- id: string
93
- attributes: { referenceName?: string; archived?: boolean }
94
- }>(`/v1/apps/${opts.appId}/gameCenterLeaderboardSets`)
91
+ const detailId = await getGameCenterDetailId(opts.appId)
92
+ const result = await gameCenterDetailsGameCenterLeaderboardSetsGetToManyRelated({
93
+ path: { id: detailId },
94
+ })
95
+ const data = throwOnError(result)
96
+ const items = data.data
95
97
  const fmt = detectFormat(opts.output)
96
98
  if (fmt === "json") { printJSON(items); return }
97
99
  printTable(
98
100
  ["ID", "Reference Name", "Archived"],
99
- items.map(s => [s.id, s.attributes.referenceName ?? "-", String(s.attributes.archived ?? false)]),
101
+ items.map(s => [s.id, s.attributes?.referenceName ?? "-", "-"]),
100
102
  `Leaderboard Sets (${items.length})`,
101
103
  )
102
104
  }
@@ -104,11 +106,10 @@ export async function leaderboardSetsList(opts: {
104
106
  // ---- Game Center Enable ----
105
107
 
106
108
  export async function gameCenterEnableCheck(appId: string, opts: { output?: string } = {}): Promise<void> {
107
- const result = await ascFetch<{
108
- data: { id: string; attributes: Record<string, unknown> }
109
- }>(`/v1/apps/${appId}/gameCenterEnabledVersions`)
109
+ const result = await appsGameCenterEnabledVersionsGetToManyRelated({ path: { id: appId } })
110
+ const data = throwOnError(result)
110
111
  const fmt = detectFormat(opts.output)
111
- if (fmt === "json") { printJSON(result.data); return }
112
+ if (fmt === "json") { printJSON(data); return }
112
113
  console.log(`Game Center status for app ${appId}:`)
113
- console.log(JSON.stringify(result.data.data, null, 2))
114
+ console.log(JSON.stringify(data.data, null, 2))
114
115
  }
@@ -1,61 +1,49 @@
1
- import { ascFetch, ascFetchAll } from "../api/client.ts"
1
+ import {
2
+ appsInAppPurchasesV2GetToManyRelated,
3
+ inAppPurchasesV2GetInstance,
4
+ inAppPurchasesV2CreateInstance,
5
+ inAppPurchasesV2DeleteInstance,
6
+ } from "../api/generated/sdk.gen.ts"
7
+ import { throwOnError } from "../api/client.ts"
2
8
  import { detectFormat, printJSON, printSuccess, printTable, truncate } from "../utils/output.ts"
3
9
 
4
10
  // ---- In-App Purchases (non-subscription consumables, non-consumables, non-renewing subscriptions) ----
5
11
 
6
12
  export async function iapList(opts: { appId: string; output?: string }): Promise<void> {
7
- const items = await ascFetchAll<{
8
- id: string
9
- attributes: {
10
- name?: string
11
- productId?: string
12
- inAppPurchaseType?: string
13
- state?: string
14
- }
15
- }>(`/v1/apps/${opts.appId}/inAppPurchasesV2`, {
16
- params: { "fields[inAppPurchasesV2]": "name,productId,inAppPurchaseType,state" },
13
+ const result = await appsInAppPurchasesV2GetToManyRelated({
14
+ path: { id: opts.appId },
15
+ query: { "fields[inAppPurchases]": ["name", "productId", "inAppPurchaseType", "state"] },
17
16
  })
17
+ const data = throwOnError(result)
18
+ const items = data.data
18
19
  const fmt = detectFormat(opts.output)
19
20
  if (fmt === "json") { printJSON(items); return }
20
21
  printTable(
21
22
  ["ID", "Name", "Product ID", "Type", "State"],
22
23
  items.map(i => [
23
24
  i.id,
24
- truncate(i.attributes.name ?? "-", 30),
25
- i.attributes.productId ?? "-",
26
- i.attributes.inAppPurchaseType ?? "-",
27
- i.attributes.state ?? "-",
25
+ truncate(i.attributes?.name ?? "-", 30),
26
+ i.attributes?.productId ?? "-",
27
+ i.attributes?.inAppPurchaseType ?? "-",
28
+ i.attributes?.state ?? "-",
28
29
  ]),
29
30
  `In-App Purchases (${items.length})`,
30
31
  )
31
32
  }
32
33
 
33
34
  export async function iapGet(iapId: string, opts: { output?: string } = {}): Promise<void> {
34
- const result = await ascFetch<{
35
- data: {
36
- id: string
37
- attributes: {
38
- name?: string
39
- productId?: string
40
- inAppPurchaseType?: string
41
- state?: string
42
- reviewNote?: string
43
- familySharable?: boolean
44
- contentHosting?: boolean
45
- availableInAllTerritories?: boolean
46
- }
47
- }
48
- }>(`/v1/inAppPurchasesV2/${iapId}`)
35
+ const result = await inAppPurchasesV2GetInstance({ path: { id: iapId } })
36
+ const data = throwOnError(result)
49
37
  const fmt = detectFormat(opts.output)
50
- if (fmt === "json") { printJSON(result.data); return }
51
- const a = result.data.data.attributes
52
- console.log(`ID: ${result.data.data.id}`)
53
- console.log(`Name: ${a.name ?? "-"}`)
54
- console.log(`Product ID: ${a.productId ?? "-"}`)
55
- console.log(`Type: ${a.inAppPurchaseType ?? "-"}`)
56
- console.log(`State: ${a.state ?? "-"}`)
57
- console.log(`Reviewable: ${a.reviewNote ?? "(no review note)"}`)
58
- console.log(`Family Share: ${a.familySharable ?? false}`)
38
+ if (fmt === "json") { printJSON(data.data); return }
39
+ const a = data.data.attributes
40
+ console.log(`ID: ${data.data.id}`)
41
+ console.log(`Name: ${a?.name ?? "-"}`)
42
+ console.log(`Product ID: ${a?.productId ?? "-"}`)
43
+ console.log(`Type: ${a?.inAppPurchaseType ?? "-"}`)
44
+ console.log(`State: ${a?.state ?? "-"}`)
45
+ console.log(`Reviewable: ${a?.reviewNote ?? "(no review note)"}`)
46
+ console.log(`Family Share: ${a?.familySharable ?? false}`)
59
47
  }
60
48
 
61
49
  export async function iapCreate(opts: {
@@ -64,15 +52,14 @@ export async function iapCreate(opts: {
64
52
  productId: string
65
53
  type: string
66
54
  }): Promise<void> {
67
- const result = await ascFetch<{ data: { id: string } }>("/v1/inAppPurchasesV2", {
68
- method: "POST",
55
+ const result = await inAppPurchasesV2CreateInstance({
69
56
  body: {
70
57
  data: {
71
- type: "inAppPurchasesV2",
58
+ type: "inAppPurchases",
72
59
  attributes: {
73
60
  name: opts.name,
74
61
  productId: opts.productId,
75
- inAppPurchaseType: opts.type,
62
+ inAppPurchaseType: opts.type as never,
76
63
  },
77
64
  relationships: {
78
65
  app: { data: { type: "apps", id: opts.appId } },
@@ -80,26 +67,33 @@ export async function iapCreate(opts: {
80
67
  },
81
68
  },
82
69
  })
83
- printSuccess(`Created IAP: ${result.data.data.id} (${opts.productId})`)
70
+ const data = throwOnError(result)
71
+ printSuccess(`Created IAP: ${data.data.id} (${opts.productId})`)
84
72
  }
85
73
 
86
74
  export async function iapDelete(iapId: string): Promise<void> {
87
- await ascFetch(`/v1/inAppPurchasesV2/${iapId}`, { method: "DELETE" })
75
+ await inAppPurchasesV2DeleteInstance({ path: { id: iapId } })
88
76
  printSuccess(`Deleted IAP ${iapId}`)
89
77
  }
90
78
 
91
79
  export async function iapLocalesList(iapId: string, opts: { output?: string } = {}): Promise<void> {
92
- const items = await ascFetchAll<{
93
- id: string
94
- attributes: { locale?: string; name?: string; description?: string }
95
- }>(`/v1/inAppPurchasesV2/${iapId}/iapPriceSchedule`, {
96
- params: { "fields[inAppPurchaseLocalizations]": "locale,name,description" },
80
+ // No direct SDK function for /v1/inAppPurchasesV2/{id}/iapPriceSchedule with localization fields
81
+ // Use the get instance with include
82
+ const result = await inAppPurchasesV2GetInstance({
83
+ path: { id: iapId },
84
+ query: {
85
+ include: ["iapPriceSchedule"],
86
+ "fields[inAppPurchaseLocalizations]": ["locale", "name", "description"],
87
+ },
97
88
  })
89
+ const data = throwOnError(result)
90
+ const included = (data as { data: unknown; included?: Array<{ id: string; type: string; attributes?: { locale?: string; name?: string; description?: string } }> }).included ?? []
91
+ const locs = included.filter(r => r.type === "inAppPurchaseLocalizations")
98
92
  const fmt = detectFormat(opts.output)
99
- if (fmt === "json") { printJSON(items); return }
93
+ if (fmt === "json") { printJSON(locs); return }
100
94
  printTable(
101
95
  ["Locale", "Name", "Description"],
102
- items.map(l => [l.attributes.locale ?? l.id, l.attributes.name ?? "-", truncate(l.attributes.description ?? "-", 40)]),
103
- `IAP Localizations (${items.length})`,
96
+ locs.map(l => [l.attributes?.locale ?? l.id, l.attributes?.name ?? "-", truncate(l.attributes?.description ?? "-", 40)]),
97
+ `IAP Localizations (${locs.length})`,
104
98
  )
105
99
  }
@@ -0,0 +1,83 @@
1
+ import {
2
+ appStoreVersionsAppStoreVersionLocalizationsGetToManyRelated,
3
+ appStoreVersionLocalizationsGetInstance,
4
+ appStoreVersionLocalizationsCreateInstance,
5
+ appStoreVersionLocalizationsDeleteInstance,
6
+ } from "../api/generated/sdk.gen.ts"
7
+ import { throwOnError } from "../api/client.ts"
8
+ import { detectFormat, printJSON, printSuccess, printTable, truncate } from "../utils/output.ts"
9
+
10
+ export async function localizationsList(opts: {
11
+ versionId: string
12
+ output?: string
13
+ }): Promise<void> {
14
+ const result = await appStoreVersionsAppStoreVersionLocalizationsGetToManyRelated({
15
+ path: { id: opts.versionId },
16
+ query: { "fields[appStoreVersionLocalizations]": ["locale", "description", "whatsNew", "keywords"] },
17
+ })
18
+ const data = throwOnError(result)
19
+ const items = data.data
20
+
21
+ const fmt = detectFormat(opts.output)
22
+ if (fmt === "json") { printJSON(items.map(l => ({ id: l.id, ...l.attributes }))); return }
23
+ printTable(
24
+ ["ID", "Locale", "What's New", "Description"],
25
+ items.map(l => [
26
+ l.id,
27
+ l.attributes?.locale ?? "-",
28
+ truncate(l.attributes?.whatsNew ?? "-", 40),
29
+ truncate(l.attributes?.description ?? "-", 40),
30
+ ]),
31
+ `Localizations (${items.length})`,
32
+ )
33
+ }
34
+
35
+ export async function localizationsGet(localizationId: string, output?: string): Promise<void> {
36
+ const result = await appStoreVersionLocalizationsGetInstance({ path: { id: localizationId } })
37
+ const data = throwOnError(result)
38
+ const l = data.data
39
+
40
+ const fmt = detectFormat(output)
41
+ if (fmt === "json") { printJSON({ id: l.id, ...l.attributes }); return }
42
+ console.log(`ID: ${l.id}`)
43
+ console.log(`Locale: ${l.attributes?.locale ?? "-"}`)
44
+ console.log(`What's New: ${l.attributes?.whatsNew ?? "-"}`)
45
+ console.log(`Description: ${truncate(l.attributes?.description ?? "-", 80)}`)
46
+ console.log(`Keywords: ${l.attributes?.keywords ?? "-"}`)
47
+ console.log(`Promotional Text: ${l.attributes?.promotionalText ?? "-"}`)
48
+ console.log(`Marketing URL: ${l.attributes?.marketingUrl ?? "-"}`)
49
+ console.log(`Support URL: ${l.attributes?.supportUrl ?? "-"}`)
50
+ }
51
+
52
+ export async function localizationsCreate(opts: {
53
+ versionId: string
54
+ locale: string
55
+ description?: string
56
+ whatsNew?: string
57
+ keywords?: string
58
+ }): Promise<void> {
59
+ const result = await appStoreVersionLocalizationsCreateInstance({
60
+ body: {
61
+ data: {
62
+ type: "appStoreVersionLocalizations",
63
+ attributes: {
64
+ locale: opts.locale,
65
+ description: opts.description,
66
+ whatsNew: opts.whatsNew,
67
+ keywords: opts.keywords,
68
+ },
69
+ relationships: {
70
+ appStoreVersion: { data: { type: "appStoreVersions", id: opts.versionId } },
71
+ },
72
+ },
73
+ },
74
+ })
75
+ const data = throwOnError(result)
76
+ printSuccess(`Localization created for locale "${opts.locale}" — ID: ${data.data.id}`)
77
+ }
78
+
79
+ export async function localizationsDelete(localizationId: string): Promise<void> {
80
+ const result = await appStoreVersionLocalizationsDeleteInstance({ path: { id: localizationId } })
81
+ throwOnError(result)
82
+ printSuccess(`Localization ${localizationId} deleted`)
83
+ }
@@ -1,14 +1,20 @@
1
- import { ascFetch, ascFetchAll } from "../api/client.ts"
2
- import type { AppStoreVersionLocalization } from "../api/types.ts"
1
+ import {
2
+ appStoreVersionsAppStoreVersionLocalizationsGetToManyRelated,
3
+ appStoreVersionLocalizationsUpdateInstance,
4
+ appStoreVersionLocalizationsCreateInstance,
5
+ } from "../api/generated/sdk.gen.ts"
6
+ import { throwOnError } from "../api/client.ts"
3
7
  import { detectFormat, printJSON, printSuccess, printTable, truncate } from "../utils/output.ts"
4
8
 
5
9
  export async function metadataList(opts: {
6
10
  versionId: string
7
11
  output?: string
8
12
  }): Promise<void> {
9
- const locs = await ascFetchAll<AppStoreVersionLocalization>(
10
- `/v1/appStoreVersions/${opts.versionId}/appStoreVersionLocalizations`,
11
- )
13
+ const result = await appStoreVersionsAppStoreVersionLocalizationsGetToManyRelated({
14
+ path: { id: opts.versionId },
15
+ })
16
+ const data = throwOnError(result)
17
+ const locs = data.data
12
18
 
13
19
  const fmt = detectFormat(opts.output)
14
20
  if (fmt === "json") {
@@ -20,9 +26,9 @@ export async function metadataList(opts: {
20
26
  ["ID", "Locale", "What's New", "Description"],
21
27
  locs.map((l) => [
22
28
  l.id,
23
- l.attributes.locale,
24
- truncate(l.attributes.whatsNew ?? "-", 50),
25
- truncate(l.attributes.description ?? "-", 50),
29
+ l.attributes?.locale ?? "-",
30
+ truncate(l.attributes?.whatsNew ?? "-", 50),
31
+ truncate(l.attributes?.description ?? "-", 50),
26
32
  ]),
27
33
  `Localizations (${locs.length})`,
28
34
  )
@@ -37,10 +43,12 @@ export async function metadataUpdate(opts: {
37
43
  promotionalText?: string
38
44
  }): Promise<void> {
39
45
  // Find existing localization for this locale
40
- const locs = await ascFetchAll<AppStoreVersionLocalization>(
41
- `/v1/appStoreVersions/${opts.versionId}/appStoreVersionLocalizations`,
42
- { params: { "filter[locale]": opts.locale } },
43
- )
46
+ const result = await appStoreVersionsAppStoreVersionLocalizationsGetToManyRelated({
47
+ path: { id: opts.versionId },
48
+ query: { "filter[locale]": [opts.locale] as never },
49
+ })
50
+ const data = throwOnError(result)
51
+ const locs = data.data
44
52
 
45
53
  const attributes: Record<string, string> = {}
46
54
  if (opts.whatsNew !== undefined) attributes["whatsNew"] = opts.whatsNew
@@ -49,25 +57,24 @@ export async function metadataUpdate(opts: {
49
57
  if (opts.promotionalText !== undefined) attributes["promotionalText"] = opts.promotionalText
50
58
 
51
59
  if (locs.length > 0 && locs[0]) {
52
- await ascFetch(`/v1/appStoreVersionLocalizations/${locs[0].id}`, {
53
- method: "PATCH",
60
+ await appStoreVersionLocalizationsUpdateInstance({
61
+ path: { id: locs[0].id },
54
62
  body: {
55
63
  data: {
56
64
  type: "appStoreVersionLocalizations",
57
65
  id: locs[0].id,
58
- attributes,
66
+ attributes: attributes as never,
59
67
  },
60
68
  },
61
69
  })
62
70
  printSuccess(`Metadata updated for locale "${opts.locale}"`)
63
71
  } else {
64
72
  // Create new localization
65
- await ascFetch("/v1/appStoreVersionLocalizations", {
66
- method: "POST",
73
+ await appStoreVersionLocalizationsCreateInstance({
67
74
  body: {
68
75
  data: {
69
76
  type: "appStoreVersionLocalizations",
70
- attributes: { locale: opts.locale, ...attributes },
77
+ attributes: { locale: opts.locale, ...attributes } as never,
71
78
  relationships: {
72
79
  appStoreVersion: {
73
80
  data: { type: "appStoreVersions", id: opts.versionId },
@@ -0,0 +1,85 @@
1
+ import {
2
+ appStoreVersionsAppStoreVersionPhasedReleaseGetToOneRelated,
3
+ appStoreVersionPhasedReleasesCreateInstance,
4
+ appStoreVersionPhasedReleasesUpdateInstance,
5
+ appStoreVersionPhasedReleasesDeleteInstance,
6
+ } from "../api/generated/sdk.gen.ts"
7
+ import type { PhasedReleaseState } from "../api/generated/types.gen.ts"
8
+ import { throwOnError, ASCError } from "../api/client.ts"
9
+ import { detectFormat, printJSON, printSuccess } from "../utils/output.ts"
10
+
11
+ const VALID_STATES: PhasedReleaseState[] = ["INACTIVE", "ACTIVE", "PAUSED", "COMPLETE"]
12
+
13
+ export async function phasedReleaseGet(versionId: string, output?: string): Promise<void> {
14
+ let pr: Awaited<ReturnType<typeof appStoreVersionsAppStoreVersionPhasedReleaseGetToOneRelated>>
15
+ try {
16
+ pr = await appStoreVersionsAppStoreVersionPhasedReleaseGetToOneRelated({ path: { id: versionId } })
17
+ } catch (err) {
18
+ if (err instanceof ASCError && err.status === 404) {
19
+ console.log("No phased release configured for this version.")
20
+ return
21
+ }
22
+ throw err
23
+ }
24
+ const data = throwOnError(pr)
25
+ const d = data.data
26
+
27
+ const fmt = detectFormat(output)
28
+ if (fmt === "json") { printJSON({ id: d.id, ...d.attributes }); return }
29
+ console.log(`ID: ${d.id}`)
30
+ console.log(`State: ${d.attributes?.phasedReleaseState ?? "-"}`)
31
+ console.log(`Start Date: ${d.attributes?.startDate ?? "-"}`)
32
+ console.log(`Current Day: ${d.attributes?.currentDayNumber ?? "-"} / 7`)
33
+ console.log(`Total Pause Days: ${d.attributes?.totalPauseDuration ?? 0}`)
34
+ }
35
+
36
+ export async function phasedReleaseCreate(opts: {
37
+ versionId: string
38
+ state?: string
39
+ }): Promise<void> {
40
+ const state = (opts.state ?? "INACTIVE").toUpperCase() as PhasedReleaseState
41
+ if (!VALID_STATES.includes(state)) {
42
+ throw new Error(`Invalid state "${state}". Valid values: ${VALID_STATES.join(", ")}`)
43
+ }
44
+ const result = await appStoreVersionPhasedReleasesCreateInstance({
45
+ body: {
46
+ data: {
47
+ type: "appStoreVersionPhasedReleases",
48
+ attributes: { phasedReleaseState: state },
49
+ relationships: {
50
+ appStoreVersion: { data: { type: "appStoreVersions", id: opts.versionId } },
51
+ },
52
+ },
53
+ },
54
+ })
55
+ const data = throwOnError(result)
56
+ printSuccess(`Phased release created — ID: ${data.data.id} State: ${state}`)
57
+ }
58
+
59
+ export async function phasedReleaseUpdate(opts: {
60
+ phasedReleaseId: string
61
+ state: string
62
+ }): Promise<void> {
63
+ const state = opts.state.toUpperCase() as PhasedReleaseState
64
+ if (!VALID_STATES.includes(state)) {
65
+ throw new Error(`Invalid state "${state}". Valid values: ${VALID_STATES.join(", ")}`)
66
+ }
67
+ const result = await appStoreVersionPhasedReleasesUpdateInstance({
68
+ path: { id: opts.phasedReleaseId },
69
+ body: {
70
+ data: {
71
+ type: "appStoreVersionPhasedReleases",
72
+ id: opts.phasedReleaseId,
73
+ attributes: { phasedReleaseState: state },
74
+ },
75
+ },
76
+ })
77
+ throwOnError(result)
78
+ printSuccess(`Phased release updated — State: ${state}`)
79
+ }
80
+
81
+ export async function phasedReleaseDelete(phasedReleaseId: string): Promise<void> {
82
+ const result = await appStoreVersionPhasedReleasesDeleteInstance({ path: { id: phasedReleaseId } })
83
+ throwOnError(result)
84
+ printSuccess(`Phased release ${phasedReleaseId} deleted`)
85
+ }