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:
parent
f2b841d735
commit
e381bc2256
11 changed files with 206 additions and 10 deletions
|
|
@ -200,3 +200,41 @@ export const reviewItemReq = (submissionId: string, kind: 'appCustomProductPageV
|
|||
method: 'POST', path: '/v1/reviewSubmissionItems', note: label,
|
||||
body: { data: { type: 'reviewSubmissionItems', relationships: { reviewSubmission: one('reviewSubmissions', submissionId), [kind]: one(kind === 'appEvent' ? 'appEvents' : 'appCustomProductPageVersions', id) } } },
|
||||
});
|
||||
|
||||
/** Event attributes that differ from the config: `attrs` = the PATCH attributes (empty when nothing differs), `lines` = readable. Pure. */
|
||||
export function eventAttrDiff(ev: AppEventDef, now: { badge?: string; priority?: string; purpose?: string; deepLink?: string | null; territorySchedules?: { territories?: string[]; publishStart?: string; eventStart?: string; eventEnd?: string }[] }): { attrs: Record<string, unknown>; lines: string[] } {
|
||||
const attrs: Record<string, unknown> = {};
|
||||
const lines: string[] = [];
|
||||
const same = (a?: string, b?: string) => (a && b ? Date.parse(a) === Date.parse(b) : a === b);
|
||||
if (now.badge !== undefined && now.badge !== ev.badge) { attrs.badge = ev.badge; lines.push(`badge ${now.badge} -> ${ev.badge}`); }
|
||||
const pri = (ev.priority ?? 'normal').toUpperCase();
|
||||
if (now.priority !== undefined && now.priority !== pri) { attrs.priority = pri; lines.push(`priority ${now.priority} -> ${pri}`); }
|
||||
const purpose = ev.purpose ?? 'APPROPRIATE_FOR_ALL_USERS';
|
||||
if (now.purpose !== undefined && now.purpose !== purpose) { attrs.purpose = purpose; lines.push(`purpose ${now.purpose} -> ${purpose}`); }
|
||||
const s = now.territorySchedules?.[0];
|
||||
const sch: string[] = [];
|
||||
if (!same(s?.publishStart, ev.schedule.publishStart)) sch.push(`publishStart ${s?.publishStart ?? '(none)'} -> ${ev.schedule.publishStart}`);
|
||||
if (!same(s?.eventStart, ev.schedule.eventStart)) sch.push(`eventStart ${s?.eventStart ?? '(none)'} -> ${ev.schedule.eventStart}`);
|
||||
if (!same(s?.eventEnd, ev.schedule.eventEnd)) sch.push(`eventEnd ${s?.eventEnd ?? '(none)'} -> ${ev.schedule.eventEnd}`);
|
||||
const wt = ev.schedule.territories;
|
||||
if (wt && [...new Set(s?.territories ?? [])].sort().join() !== [...new Set(wt)].sort().join()) sch.push(`territories ${(s?.territories ?? []).length} -> ${wt.length}`);
|
||||
if (sch.length) {
|
||||
attrs.territorySchedules = [{ territories: wt ?? s?.territories ?? [], publishStart: ev.schedule.publishStart, eventStart: ev.schedule.eventStart, eventEnd: ev.schedule.eventEnd }];
|
||||
lines.push(...sch);
|
||||
}
|
||||
return { attrs, lines };
|
||||
}
|
||||
|
||||
/** PATCH /v1/appEvents/{id} with the changed attributes, null when none. */
|
||||
export const eventPatchReq = (eventId: string, name: string, attrs: Record<string, unknown>, lines: string[]): Req | null =>
|
||||
Object.keys(attrs).length ? { method: 'PATCH', path: `/v1/appEvents/${eventId}`, note: `event "${name}": ${lines.join('; ')}`, body: { data: { type: 'appEvents', id: eventId, attributes: attrs } } } : null;
|
||||
|
||||
/** PATCH of a page version's deep link: set, change, or clear (config has none, the page has one). Null when equal. Pure. */
|
||||
export function cppDeepLinkReq(versionId: string, name: string, want: string | undefined, have: string | null | undefined): Req | null {
|
||||
if ((want ?? null) === (have ?? null)) return null;
|
||||
return { method: 'PATCH', path: `/v1/appCustomProductPageVersions/${versionId}`, note: want ? `"${name}" deep link` : `"${name}" deep link removed`,
|
||||
body: { data: { type: 'appCustomProductPageVersions', id: versionId, attributes: { deepLink: want ?? null } } } };
|
||||
}
|
||||
|
||||
/** Locales on a page version that the config has no language for. Pure. */
|
||||
export const extraCppLocales = (have: string[], want: string[]): string[] => have.filter(l => !want.includes(l));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue