onboard reads review access from the live App Store version (READY_FOR_SALE / READY_FOR_DISTRIBUTION, newest live first; the newest version only when nothing is live): a newer draft's empty review detail no longer hides the live demo account or turns signInRequired off; reviewVersion in cli/lib/onboard.ts, tests with a live version holding a demo account and a newer draft without
This commit is contained in:
parent
0c4689a81b
commit
21fa91afd1
3 changed files with 41 additions and 5 deletions
|
|
@ -211,6 +211,17 @@ export function maskContact(c: ReviewContact): string {
|
|||
return `${c.firstName ? c.firstName[0] + '.' : ''}${c.lastName ? ` ${c.lastName[0]}.` : ''} ${maskUser(c.email)}${digits ? `, phone ***${digits.slice(-2)}` : ''}`.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* The App Store version whose review detail tells the truth about review access: the LIVE one (READY_FOR_SALE /
|
||||
* READY_FOR_DISTRIBUTION; the newest live one when several report it), else the newest version. A newer draft's empty
|
||||
* review detail must never hide the demo account the live version was reviewed with.
|
||||
*/
|
||||
export function reviewVersion<T extends { attributes?: { appStoreState?: string | null; appVersionState?: string | null; createdDate?: string | null } }>(versions: T[]): T | null {
|
||||
const LIVE = new Set(['READY_FOR_SALE', 'READY_FOR_DISTRIBUTION']);
|
||||
const newest = [...versions].sort((a, b) => (b.attributes?.createdDate ?? '').localeCompare(a.attributes?.createdDate ?? ''));
|
||||
return newest.find(v => LIVE.has(v.attributes?.appVersionState ?? '') || LIVE.has(v.attributes?.appStoreState ?? '')) ?? newest[0] ?? null;
|
||||
}
|
||||
|
||||
// ---- sign-in for review ----
|
||||
|
||||
export interface SignInDecision {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import type { StoreItem } from './lib/catalog';
|
|||
import { reviewContact, reviewDemoAccount } from './lib/credentials';
|
||||
import type { Ctx } from './lib/ctx';
|
||||
import { done, log, printJson, warn } from './lib/log';
|
||||
import { type AppleReviewDetail, contactProposal, type DeletionResult, findDeletionUrl, importCatalog, maskContact, type PageGet, reviewContactOf, signInDecision, type StoreContact } from './lib/onboard';
|
||||
import { type AppleReviewDetail, contactProposal, type DeletionResult, findDeletionUrl, importCatalog, maskContact, type PageGet, reviewContactOf, reviewVersion, signInDecision, type StoreContact } from './lib/onboard';
|
||||
import { authEvidence } from './lib/project-signals';
|
||||
import { detectProject } from './lib/scan/project';
|
||||
import { upsertBlock, upsertNestedString } from './lib/scan/config-edit';
|
||||
|
|
@ -57,8 +57,10 @@ async function appleFacts(ctx: Ctx): Promise<NonNullable<StoreContact['apple']>>
|
|||
const l = locs.find((x: J) => x.attributes.locale === primary) ?? locs[0];
|
||||
supportUrl = l?.attributes?.supportUrl ?? undefined;
|
||||
marketingUrl = l?.attributes?.marketingUrl ?? undefined;
|
||||
review = (await c.maybe(`/v1/appStoreVersions/${v.id}/appStoreReviewDetail`))?.data?.attributes ?? null;
|
||||
}
|
||||
// review access comes from the live version's review detail (a newer draft's empty one must not hide its demo account)
|
||||
const rv = reviewVersion(versions);
|
||||
if (rv) review = (await c.maybe(`/v1/appStoreVersions/${rv.id}/appStoreReviewDetail`))?.data?.attributes ?? null;
|
||||
const info = await c.editableAppInfo();
|
||||
const infoLocs = info ? await c.all(`/v1/appInfos/${info.id}/appInfoLocalizations?limit=50`) : [];
|
||||
const il = infoLocs.find((x: J) => x.attributes.locale === primary) ?? infoLocs[0];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue