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

@ -14,7 +14,8 @@
// Live apps: crash / ANR vitals (Play Reporting API) and App Store diagnostics, as in `storebound health`: over a Play
// bad behavior threshold is a blocker, near it a warning; a store without vitals access is only noted. --no-health skips.
import { templateBlockers } from './lib/template-answers';
import { ascClient, type J } from './apple/asc';
import { ascClient, EDITABLE as APPLE_EDITABLE, type J } from './apple/asc';
import { allVersions, type AscPlatform, parsePlatform, platformOf, stateOf, versionsPath } from './apple/platform';
import { capabilityReport } from './apple/signing';
import { firstProductReport } from './apple/first-products';
import { requiredDisplayTypes } from './apple/screenshots';
@ -55,8 +56,14 @@ export async function collectApple(ctx: Ctx): Promise<AppleSnapshot> {
const c = await ascClient(root, config.apple!.bundleId, config.apple?.appId);
const appId = await c.app();
log('validate', 'apple: reading version, build, localizations');
const versions = await c.all(`/v1/apps/${appId}/appStoreVersions?filter[platform]=IOS&limit=10`);
const v: J = (await c.editableVersion()) ?? versions[0] ?? null;
// the platform: --platform, else the one with an editable version (several: iOS, and the others are named)
const every = await allVersions(c, appId);
const editableOf = (x: J) => APPLE_EDITABLE.has(stateOf(x));
const withEditable = [...new Set(every.filter(editableOf).map(platformOf))];
const platform: AscPlatform = parsePlatform(ctx.args.get('platform')) ?? (withEditable.length === 1 ? withEditable[0]! : withEditable.includes('IOS') || !every.length ? 'IOS' : platformOf(every[0]));
const versions = await c.all(versionsPath(appId, platform, 10));
const v: J = (await c.editableVersion(platform)) ?? versions[0] ?? null;
const otherPlatformVersions = every.filter(x => platformOf(x) !== platform && editableOf(x)).map(x => ({ versionString: String(x.attributes.versionString), state: stateOf(x), platform: platformOf(x) }));
let build: AppleSnapshot['build'] = null;
const locales: AppleSnapshot['locales'] = [];
let reviewDetail: AppleSnapshot['reviewDetail'] = null;
@ -109,7 +116,8 @@ export async function collectApple(ctx: Ctx): Promise<AppleSnapshot> {
subscriptions, expectedSubscriptions: wantSubs.map(({ group, sub }) => ({ id: sub.id, group: group.name,
locales: Object.keys(sub.listings).map(id => appleLocale.get(id)).filter((x): x is string => !!x) })),
profile: await collectProfile(ctx.loaded),
version: v ? { versionString: v.attributes.versionString, state: v.attributes.appVersionState ?? v.attributes.appStoreState, copyright: v.attributes.copyright ?? null } : null,
version: v ? { versionString: v.attributes.versionString, state: v.attributes.appVersionState ?? v.attributes.appStoreState, copyright: v.attributes.copyright ?? null, platform } : null,
otherPlatformVersions,
configCopyright: config.app.copyright,
build, locales, reviewDetail, ageRating,
expectedLocales: config.languages.map(l => l.apple).filter((x): x is string => !!x),