--json prints only JSON on stdout (withJsonOutput around every command: logs, tables and prompts to stderr; printJson everywhere; test runs every --json command against the fake stores and parses stdout); prices ppp compares like with like: par = the store's own US-equivalent price (Play convertRegionPrices, Apple equalizations; offline base x fx x (1 + VAT) rounded up) scaled by the PPP price level; defaults only lower, only price levels <= 0.5, World Bank high-income at par, CN at par on Apple and skipped on Play, never above par (--only-decreases, --max-ratio, --min-ratio, --max-level, --include-high-income; --floor / --ceiling kept), top-10 revenue market drops > 20 % warned (sales reports, else a static list), unchanged regions out of the sheet; price changes of existing products only with --allow-price-changes, TTY or not (a terminal yes covered them), then their own question listing each old -> new, held section in dry runs (play products, prices import, play / apple subscriptions); pitfalls 61-63; tests
This commit is contained in:
parent
bab3f63227
commit
357319a775
30 changed files with 865 additions and 209 deletions
|
|
@ -8,6 +8,28 @@ export const log = (tag: string, msg: string): void => console.log(`${stamp()} [
|
|||
export const warn = (tag: string, msg: string): void => console.warn(`${stamp()} [${tag}] WARN ${msg}`);
|
||||
export const done = (tag: string, msg: string): void => console.log(`${stamp()} [${tag}] ${msg} (${since()})`);
|
||||
|
||||
// The count lives on globalThis: the Node bundle (tools/build-node.ts) can carry this module twice (once for the
|
||||
// static imports, once inside a lazily initialised chunk), and both copies must see the same --json run.
|
||||
const JSON_RUNS = Symbol.for('storebound.jsonRuns');
|
||||
const runs = globalThis as unknown as Record<symbol, number>;
|
||||
/** Whether a `--json` run is going on: stdout carries only the JSON (printJson), everything else goes to stderr. */
|
||||
export const jsonOutput = (): boolean => (runs[JSON_RUNS] ?? 0) > 0;
|
||||
/** Where a question / prompt is written: stderr during a --json run, so stdout stays one JSON document. */
|
||||
export const promptOut = (): NodeJS.WriteStream => (jsonOutput() ? process.stderr : process.stdout);
|
||||
|
||||
/**
|
||||
* Runs a command with --json: stdout is only the JSON. console.log / console.info (log, done, step lines, tables and
|
||||
* every other line a command prints) go to stderr for the run; printJson writes the result to stdout itself. index.ts
|
||||
* wraps every command run with --json in this, so no command has to remember it.
|
||||
*/
|
||||
export async function withJsonOutput<T>(fn: () => Promise<T>): Promise<T> {
|
||||
const log = console.log, info = console.info;
|
||||
console.log = (...a: unknown[]) => console.error(...a);
|
||||
console.info = (...a: unknown[]) => console.error(...a);
|
||||
runs[JSON_RUNS] = (runs[JSON_RUNS] ?? 0) + 1;
|
||||
try { return await fn(); } finally { runs[JSON_RUNS] = runs[JSON_RUNS]! - 1; console.log = log; console.info = info; }
|
||||
}
|
||||
|
||||
/** "3/14 de-DE" style counters. */
|
||||
export const step = (i: number, n: number, what: string): string => `${String(i).padStart(String(n).length)}/${n} ${what}`;
|
||||
|
||||
|
|
@ -20,5 +42,7 @@ export const RESULT_MARK = '\u001estorebound-result ';
|
|||
*/
|
||||
export function printJson(data: unknown): void {
|
||||
if (process.env.STOREBOUND_MACHINE === '1') process.stdout.write(RESULT_MARK + JSON.stringify(data) + '\n');
|
||||
// during a --json run console.log goes to stderr, so the JSON goes to stdout itself
|
||||
else if (jsonOutput()) process.stdout.write(JSON.stringify(data, null, 2) + '\n');
|
||||
else console.log(JSON.stringify(data, null, 2));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue