// Reads what `firstProductGaps` (cli/lib/review-submit.ts) needs: every in-app purchase and subscription, the app's // open review submission with its items, and the versions of the never-approved products (to see whether they are in // it). Used by apple status, validate and the release status / plan built on them (pitfall 70). Read-only. import { type FirstProductGap, firstProductGaps, type FirstProductInput, NEVER_SUBMITTED } from '../lib/review-submit'; import type { Asc, J } from './asc'; import { openSubmissions } from './submission'; export async function readFirstProducts(c: Asc, appId: string, o: { iaps?: J[]; only?: string[]; versionState?: string } = {}): Promise { const ids = (vs: J[]): string[] => vs.map(v => v.id as string); const iaps: FirstProductInput['iaps'] = []; for (const p of o.iaps ?? await c.all(`/v1/apps/${appId}/inAppPurchasesV2?limit=200`)) { const state = p.attributes.state as string; iaps.push({ productId: p.attributes.productId, type: p.attributes.inAppPurchaseType, state, versionIds: NEVER_SUBMITTED.has(state) ? ids(await c.all(`/v2/inAppPurchases/${p.id}/versions?limit=200`)) : [] }); } const subs: FirstProductInput['subs'] = []; for (const g of await c.all(`/v1/apps/${appId}/subscriptionGroups?limit=200`)) { for (const s of await c.all(`/v1/subscriptionGroups/${g.id}/subscriptions?limit=200`)) { const state = s.attributes.state as string; subs.push({ productId: s.attributes.productId, groupId: g.id, state, versionIds: NEVER_SUBMITTED.has(state) ? ids(await c.all(`/v1/subscriptions/${s.id}/versions?limit=200`)) : [] }); } } const open = await openSubmissions(c, appId); // the submission that matters: one in review, else one back from review, else a draft holding items const pick = open.find(x => x.state === 'WAITING_FOR_REVIEW' || x.state === 'IN_REVIEW') ?? open.find(x => x.state === 'UNRESOLVED_ISSUES') ?? open.find(x => x.items.length); const submission = pick ? { id: pick.id, state: pick.state, itemVersionIds: pick.items.map(i => i.versionId) } : null; return { iaps, subs, submission, versionState: o.versionState, only: o.only }; } export async function firstProductReport(c: Asc, appId: string, o: Parameters[2] = {}): Promise { return firstProductGaps(await readFirstProducts(c, appId, o)); }