apple testflight distribute: a build's groups read per group (GET /v1/betaGroups/{id}/relationships/builds) instead of GET /v1/betaGroups?filter[builds]=, which App Store Connect refuses with 400 although the spec declares it; internal all-builds groups reported as already available and never sent the build; a re-run adds nothing; configured groups missing on App Store Connect point at groups sync, unknown ones list what exists; APPLE_LIVE_REJECTED (refused by storebound api too), tests/asc-query-guard.test.ts checks every App Store Connect GET with a query in cli/ against the spec's declared parameters, and the fake App Store Connect answers 400 to undeclared or live-refused parameters (pitfall 42)
This commit is contained in:
parent
f741c15829
commit
bba46b5c7f
13 changed files with 354 additions and 14 deletions
|
|
@ -33,6 +33,15 @@ export interface Op {
|
|||
shapes: Record<string, string>;
|
||||
}
|
||||
|
||||
/**
|
||||
* App Store Connect query parameters the spec declares but the live API answers 400 to, per operation id, with what to
|
||||
* use instead. `storebound api` refuses them, and tests/asc-query-guard.test.ts fails when storebound's own code uses one.
|
||||
*/
|
||||
export const APPLE_LIVE_REJECTED: Record<string, Record<string, string>> = {
|
||||
// seen live 2026-10-13 (apple testflight distribute): GET /v1/betaGroups?filter[app]=..&filter[builds]=.. -> 400
|
||||
betaGroups_getCollection: { 'filter[builds]': 'seen live: 400; read the builds of each group with GET /v1/betaGroups/{id}/relationships/builds' },
|
||||
};
|
||||
|
||||
/** Query parameters every Google API accepts on top of a method's own. */
|
||||
export const GOOGLE_GLOBAL = ['fields', 'prettyPrint', 'quotaUser'];
|
||||
|
||||
|
|
@ -136,6 +145,8 @@ export function buildRequest(op: Op, params: Record<string, ParamValue | undefin
|
|||
const names = op.query.map(x => x.name);
|
||||
throw new Error(`${op.id}: unknown parameter "${k}"${names.length ? ` (takes: ${names.slice(0, 30).join(', ')}${names.length > 30 ? ', …' : ''})` : ' (takes no query parameters)'}`);
|
||||
}
|
||||
const refused = op.store === 'apple' ? APPLE_LIVE_REJECTED[op.id]?.[k] : undefined;
|
||||
if (refused) throw new Error(`${op.id}: App Store Connect refuses "${k}" although the spec declares it (${refused})`);
|
||||
const values = Array.isArray(v) ? v.map(str) : [str(v as string)];
|
||||
if (q?.repeated) for (const x of values) parts.push(`${encName(k)}=${encVal(x)}`);
|
||||
else parts.push(`${encName(k)}=${encVal(values.join(','))}`);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue