apple.macos listing / review notes per platform + iOS-only claim warnings; apple upload of a .pkg: bounded pkgutil, macOS processing wait, heartbeats; release 409 pattern
This commit is contained in:
parent
53d57544bf
commit
1e47c2ee60
18 changed files with 417 additions and 63 deletions
|
|
@ -707,6 +707,15 @@ export interface ShipConfig {
|
|||
* 2560 x 1600, 1440 x 900, 1280 x 800). Landscape layout from <frames>/<lang>/landscape/ (shots.landscape). Uploaded
|
||||
* as APP_DESKTOP to the macOS version: `apple screenshots --platform macos`. */
|
||||
mac?: boolean;
|
||||
/**
|
||||
* macOS App Store overrides (not `mac`, which only switches Mac screenshots on). An app with an iOS and a macOS
|
||||
* version often needs different version texts and review notes (the Mac app may have no Game Center, in-app
|
||||
* purchases or ads). `listing`: an App Store listing file used instead of apple.listing for `apple listing
|
||||
* --platform macos`; `reviewNotes`: used instead of apple.info.reviewNotes by `apple review-details --platform macos`.
|
||||
* `gameCenter: true`: the Mac app has Game Center (silences the Game Center check of `validate --platform macos`).
|
||||
* `noIap: true`: the Mac app sells nothing (validate then flags in-app purchase lines in the Mac texts).
|
||||
*/
|
||||
macos?: { listing?: string; reviewNotes?: string; gameCenter?: boolean; noIap?: boolean };
|
||||
/** "Header and Search Results" creative assets (`storebound apple creative-assets`, iOS / iPadOS 27+). Files under
|
||||
* <renders>/<lang>/creative/: header.{png,jpg,mov,m4v,mp4} (3840x1646, 21:9), search.{...} (3:2, 1920x1280 to
|
||||
* 3840x2560) or universal.png (5244x2950) for both. `header` / `search` false skip that slot; `universal` is a
|
||||
|
|
@ -1036,6 +1045,14 @@ export function validateExtras(cfg: Partial<ShipConfig>): string[] {
|
|||
e.push('play.developerAccount: the developer account name as Play Console shows it (1-100 characters)');
|
||||
if (cfg.play?.name !== undefined && !(typeof cfg.play.name === 'string' && cfg.play.name.trim() && [...cfg.play.name].length <= 30)) e.push('play.name: 1-30 characters (Play app name)');
|
||||
if (cfg.play?.free !== undefined && typeof cfg.play.free !== 'boolean') e.push('play.free: true (free) | false (paid)');
|
||||
const mo = cfg.apple?.macos;
|
||||
if (mo !== undefined) {
|
||||
if (typeof mo !== 'object' || mo === null || Array.isArray(mo)) e.push('apple.macos: { listing?: "store/appstore-macos.md", reviewNotes?: "...", gameCenter?: true, noIap?: true }');
|
||||
else {
|
||||
for (const k of ['listing', 'reviewNotes'] as const) if (mo[k] !== undefined && (typeof mo[k] !== 'string' || !mo[k]!.trim())) e.push(`apple.macos.${k}: a non-empty string${k === 'listing' ? ' (path of the macOS App Store listing file)' : ''}`);
|
||||
for (const k of ['gameCenter', 'noIap'] as const) if (mo[k] !== undefined && typeof mo[k] !== 'boolean') e.push(`apple.macos.${k}: true | false`);
|
||||
}
|
||||
}
|
||||
const ad = cfg.apple?.adhoc;
|
||||
if (ad?.method !== undefined && ad.method !== 'release-testing' && ad.method !== 'ad-hoc') e.push('apple.adhoc.method: release-testing | ad-hoc');
|
||||
const ppp = cfg.prices?.ppp;
|
||||
|
|
@ -1114,6 +1131,23 @@ function validateIarcDetails(d: IarcDetails | undefined): string[] {
|
|||
}
|
||||
|
||||
/** Platforms of the app (app identity): app.platforms, else from the store sections. */
|
||||
/** True for the macOS platform in any spelling: "macos", "mac_os" (API name MAC_OS), "mac". Pure. */
|
||||
export const isMacosPlatform = (p: string | undefined | null): boolean => !!p && /^mac(_?os)?$/i.test(p.replace(/[\s-]/g, ''));
|
||||
|
||||
/** The App Store listing file (as written in the config, relative) for a platform: apple.macos.listing for macOS when
|
||||
* set, else apple.listing, else store/appstore.md. Pure. */
|
||||
export function listingPathFor(config: Pick<ShipConfig, 'apple'>, platform?: string | null): string {
|
||||
const mac = isMacosPlatform(platform) ? config.apple?.macos?.listing?.trim() : '';
|
||||
return mac || config.apple?.listing || 'store/appstore.md';
|
||||
}
|
||||
|
||||
/** The App Review notes text of the config for a platform: apple.macos.reviewNotes for macOS when set, else
|
||||
* apple.info.reviewNotes. Pure; reviewAccess and account deletion lines are added by reviewNotes() in lib/review-details. */
|
||||
export function reviewNotesFor(config: Pick<ShipConfig, 'apple'>, platform?: string | null): string | undefined {
|
||||
const mac = isMacosPlatform(platform) ? config.apple?.macos?.reviewNotes : undefined;
|
||||
return mac?.trim() ? mac : config.apple?.info?.reviewNotes;
|
||||
}
|
||||
|
||||
/** App Store name limit (characters). */
|
||||
export const APPLE_NAME_MAX = 30;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue