diff --git a/cli/data/flags.json b/cli/data/flags.json index 8c967b1..54fd880 100644 --- a/cli/data/flags.json +++ b/cli/data/flags.json @@ -50,6 +50,7 @@ "upload" ], "apple adhoc": [ + "archive", "csv", "method", "name", @@ -178,6 +179,7 @@ "version" ], "apple resubmit": [ + "build", "new-version", "no-submit", "platform", @@ -212,6 +214,7 @@ "wait-review" ], "apple submit": [ + "build", "new-version", "no-submit", "platform", @@ -359,7 +362,6 @@ "write" ], "check": [ - "achievements", "aso", "capacitor", "cordova", @@ -369,7 +371,6 @@ "flutter", "godot", "keychain", - "leaderboards", "name", "no-install", "react-native", @@ -453,6 +454,7 @@ "dir" ], "edit": [ + "ops", "show" ], "flow": [ @@ -461,9 +463,7 @@ "resume" ], "games status": [ - "achievements", "keychain", - "leaderboards", "no-install" ], "health": [ @@ -598,10 +598,7 @@ "csv", "force" ], - "play games": [ - "achievements", - "leaderboards" - ], + "play games": [], "play images": [ "include-drafts", "not-sent-for-review", @@ -703,6 +700,7 @@ "with-automatic" ], "privacy-manifest": [ + "ios", "propose", "sdk-dirs", "tracking-domains" @@ -867,7 +865,6 @@ "play" ], "validate": [ - "achievements", "add-for-review", "allow-price-changes", "apple", @@ -884,7 +881,6 @@ "jobs", "keychain", "lang", - "leaderboards", "no-health", "no-install", "no-local", @@ -926,7 +922,6 @@ "ws": [ "aab", "accounts", - "achievements", "add-for-review", "adgroup", "against", @@ -943,6 +938,7 @@ "apple", "apply", "apps", + "archive", "aso", "base", "base-url", @@ -1028,7 +1024,6 @@ "landing", "lang", "languages", - "leaderboards", "limit", "listing-text", "listings", @@ -1075,6 +1070,7 @@ "only-keywords", "only-missing", "only-terms", + "ops", "originality", "out", "param", diff --git a/cli/play/games.ts b/cli/play/games.ts index 2e5e906..3cebf46 100644 --- a/cli/play/games.ts +++ b/cli/play/games.ts @@ -41,7 +41,7 @@ export function gamesConfigClient(root: string) { return (t ? JSON.parse(t) : {}) as T; } } - async function list(kind: 'achievements' | 'leaderboards', appId: string): Promise { + async function listAll(kind: 'achievements' | 'leaderboards', appId: string): Promise { const out: PlayExisting[] = []; let page: string | undefined; do { @@ -51,13 +51,13 @@ export function gamesConfigClient(root: string) { } while (page); return out; } - return { call, list }; + return { call, listAll }; } export const playDefaultLocale = (config: Ctx['loaded']['config']): string => config.play?.defaultLanguage ?? 'en-US'; export async function readPlayGames(c: ReturnType, appId: string): Promise<{ leaderboards: PlayExisting[]; achievements: PlayExisting[] }> { - return { leaderboards: await c.list('leaderboards', appId), achievements: await c.list('achievements', appId) }; + return { leaderboards: await c.listAll('leaderboards', appId), achievements: await c.listAll('achievements', appId) }; } const pending = (plan: ItemPlan[]) => plan.filter(p => p.action !== 'keep'); @@ -92,7 +92,7 @@ export async function run(ctx: Ctx): Promise { if (p.action === 'create') { const r = await createOnce({ what: `${p.kind} ${p.id}`, tag: TAG, create: async () => (await c.call('POST', `/applications/${appId}/${kind}`, p.attributes)).id, - find: async () => (await c.list(kind, appId)).find(x => x.draft?.name?.translations.some(t => t.locale === locale && t.value === name))?.id ?? null }); + find: async () => (await c.listAll(kind, appId)).find(x => x.draft?.name?.translations.some(t => t.locale === locale && t.value === name))?.id ?? null }); log(TAG, `${p.kind} ${p.id}: created as ${r.value} (set playId: "${r.value}" in the config to match it by id)`); } else { await c.call('PUT', `/${kind}/${encodeURIComponent(p.storeId!)}`, p.attributes); diff --git a/tools/gen-flags.ts b/tools/gen-flags.ts index 35034bf..c98884a 100644 --- a/tools/gen-flags.ts +++ b/tools/gen-flags.ts @@ -2,7 +2,7 @@ // Writes cli/data/flags.json: the --flags every command accepts, so the dispatcher (cli/index.ts) can reject an // unknown flag (a typo like --dyr) with the usage before anything runs, also in the compiled sidecar (no sources). // For each command in cli/commands.ts it follows the command module and every local module it imports (static and -// dynamic), and collects the literal flag reads: .has('name'), .get, .str, .num, .list, .many. Reads with a computed +// dynamic), and collects the literal flag reads: .has('name'), .get, .str, .num, .list, .many, .required. Reads with a computed // name are listed in DYNAMIC below (the scan fails on a new one until it is added there). `ws` forwards its flags to the // command it runs, so it accepts every flag. GLOBAL flags work on every command. The usage lines of each module's // header comment (`// storebound ...`) go along, for `storebound --help`. @@ -31,9 +31,9 @@ const DYNAMIC: Record = { const FORWARDS = new Set(['ws']); // the receiver is captured so HTTP headers and URL search params (res.headers.get('content-type')) are not flags -const READ = /([\w$.)\]]*)\.(?:has|get|str|num|list|many)\(\s*(['"])([a-z][a-z0-9-]*)\2/g; +const READ = /([\w$.)\]]*)\.(?:has|get|str|num|list|many|required)\(\s*(['"])([a-z][a-z0-9-]*)\2/g; const NOT_ARGS = /(?:headers|searchParams|params|url|env)$/i; -const COMPUTED = /\b(?:args|a|ctx\.args)\.(?:has|get|str|num|list|many)\(\s*(?![\s'"])/g; +const COMPUTED = /\b(?:args|a|ctx\.args)\.(?:has|get|str|num|list|many|required)\(\s*(?![\s'"])/g; const IMPORT = /(?:\bfrom\s+|\bimport\s*\(\s*)'(\.{1,2}\/[^']+)'/g; function file(spec: string, from: string): string | null {