Drift on existing items: offer-code and win-back campaigns that differ are named (Apple cannot edit them), in-app event attributes patched on drafts, a removed custom page deep link cleared, config languages without a version localization named, data safety dry run says Play has no read API; appinfo reads /v1/appPriceSchedules/{id}/manualPrices; a new Play language without an icon warns instead of stopping; fake store lists for the new reads

This commit is contained in:
CRTkafa 2026-10-22 20:38:54 +08:00
parent f2b841d735
commit e381bc2256
11 changed files with 206 additions and 10 deletions

View file

@ -9,7 +9,7 @@
import { existsSync, readFileSync } from 'node:fs';
import type { Ctx } from '../lib/ctx';
import { confirm, need } from '../lib/ctx';
import { type AppEventDef, checkEventMedia, EVENT_EDITABLE, EVENT_LIMITS, eventCreateBody, planEventLocales, reviewItemReq } from '../lib/cpp-events';
import { type AppEventDef, checkEventMedia, EVENT_EDITABLE, EVENT_LIMITS, eventAttrDiff, eventCreateBody, eventPatchReq, planEventLocales, reviewItemReq } from '../lib/cpp-events';
import { done, log, printJson, warn } from '../lib/log';
import { textTable } from '../lib/table';
import { imageInfo } from '../shots/spec';
@ -59,7 +59,14 @@ export async function run(ctx: Ctx): Promise<void> {
const primary = localeOf(d.primaryLanguage ?? '') ?? want[0]?.locale ?? 'en-US';
const ev = events.find((e: J) => e.attributes.referenceName === d.referenceName);
if (!ev) { created.push({ def: d, index: reqs.length }); reqs.push({ method: 'POST', path: '/v1/appEvents', note: `event "${d.referenceName}" (${d.badge}, ${d.schedule.eventStart} to ${d.schedule.eventEnd})`, body: eventCreateBody(appId, d, primary, d.schedule.territories ?? territories) }); continue; }
if (!EVENT_EDITABLE.has(ev.attributes.eventState)) { log(TAG, `"${d.referenceName}": ${ev.attributes.eventState}, not editable`); continue; }
const drift = eventAttrDiff(d, ev.attributes);
if (!EVENT_EDITABLE.has(ev.attributes.eventState)) {
if (drift.lines.length) warn(TAG, `"${d.referenceName}" is ${ev.attributes.eventState} and differs from the config: ${drift.lines.join('; ')} (not editable: change it in App Store Connect)`);
else log(TAG, `"${d.referenceName}": ${ev.attributes.eventState}, not editable`);
continue;
}
const patch = eventPatchReq(ev.id, d.referenceName, drift.attrs, drift.lines);
if (patch) reqs.push(patch);
const have = (await c.all(`/v1/appEvents/${ev.id}/localizations?limit=200`)).map((l: J) => ({ id: l.id, ...l.attributes }));
reqs.push(...planEventLocales(ev.id, have, want));
}