apple: macOS (tvOS, visionOS) versions are no longer invisible: every version and review submission lookup is per platform; status, listing, listing pull, resubmit, submit, release and screenshots take --platform and otherwise pick the platform that has the version they need (refuse naming both when several do); status, validate, release status, the report and the desktop label versions with their platform; MCP and owner actions get platform; pitfall 77

This commit is contained in:
CRTkafa 2026-10-20 03:00:05 +07:00
parent 1736300784
commit 47dfd372fe
30 changed files with 423 additions and 127 deletions

View file

@ -18,7 +18,12 @@ export type SubmissionKind = 'waiting' | 'inReview' | 'unresolved' | 'draft' | '
export interface SubmissionItem { id: string; kind: string; label: string; state: string; rejected: boolean }
export interface SubmissionView { id: string; state: string; kind: SubmissionKind; date: string | null; items: SubmissionItem[] }
export interface BuildChoice { id: string; number: string; version: string | null; state: string; uploaded: string | null; valid: boolean; attachedTo: string | null }
export interface AppleVersion { id: string; version: string; state: string; build: string | null }
export interface AppleVersion { id: string; version: string; state: string; build: string | null; platform: string }
const PLATFORM_LABEL: Record<string, string> = { IOS: 'iOS', MAC_OS: 'macOS', TV_OS: 'tvOS', VISION_OS: 'visionOS' };
/** "iOS", "macOS", ... of an App Store platform (IOS when the data has none). */
export const platformLabel = (p: string | undefined): string => PLATFORM_LABEL[p || 'IOS'] ?? p ?? 'iOS';
/** The CLI's --platform value of an App Store platform. */
export const platformFlag = (p: string | undefined): string => platformLabel(p).toLowerCase();
export interface AppleSubmitState {
submissions: SubmissionView[];
/** The first submission back from App Review (UNRESOLVED_ISSUES), with its items. */
@ -40,11 +45,11 @@ export function appleSubmitState(raw: unknown): AppleSubmitState {
const d = obj(raw) as AppleStatusData & J;
const versions: AppleVersion[] = arr(d.versions).map(v => {
const o = obj(v), a = obj(o.attributes);
return { id: str(o.id), version: str(a.versionString), state: str(a.appVersionState) || str(a.appStoreState), build: str(obj(obj(obj(o.relationships).build).data).id) || null };
return { id: str(o.id), version: str(a.versionString), state: str(a.appVersionState) || str(a.appStoreState), build: str(obj(obj(obj(o.relationships).build).data).id) || null, platform: str(a.platform) || 'IOS' };
}).filter(v => v.id && v.version);
const label = (kind: string, versionId: string): string => {
const v = versions.find(x => x.id === versionId);
return v && kind === 'appStoreVersion' ? `app version ${v.version}` : `${ITEM_NAME[kind] ?? kind} ${versionId}`;
return v && kind === 'appStoreVersion' ? `app version ${v.version} (${platformLabel(v.platform)})` : `${ITEM_NAME[kind] ?? kind} ${versionId}`;
};
const empty = new Set(arr(d.emptyDrafts).map(str));
const unresolvedItems = new Map(arr(d.unresolved).map(u => [str(obj(u).id), arr(obj(u).items)] as const));
@ -67,7 +72,7 @@ export function appleSubmitState(raw: unknown): AppleSubmitState {
const unresolved = submissions.find(s => s.kind === 'unresolved') ?? null;
const busy = submissions.find(s => s.kind === 'waiting' || s.kind === 'inReview') ?? null;
const held = new Set(unresolved?.items.filter(i => i.kind === 'appStoreVersion').map(i => i.label) ?? []);
const editable = versions.find(v => held.has(`app version ${v.version}`)) ?? versions.find(v => SUBMITTABLE_APP.includes(v.state)) ?? null;
const editable = versions.find(v => held.has(`app version ${v.version} (${platformLabel(v.platform)})`)) ?? versions.find(v => SUBMITTABLE_APP.includes(v.state)) ?? null;
return { submissions, unresolved, busy, builds, editable, versions };
}