44 lines
2.7 KiB
TypeScript
44 lines
2.7 KiB
TypeScript
#!/usr/bin/env bun
|
|
// Refreshes the bundled PPP dataset of `storebound prices ppp` from the World Bank API (read-only public API, no key).
|
|
// bun tools/update-ppp.ts fetch PA.NUS.PPP + PA.NUS.FCRF, rewrite cli/data/ppp-worldbank.json (retrieved = today)
|
|
// bun tools/update-ppp.ts --check print the bundled file's age and data year, write nothing
|
|
// bun tools/update-ppp.ts --bigmac [--project <dir>] [--dry]
|
|
// download The Economist Big Mac index into <dir>/.storebound/ppp-bigmac.json
|
|
// (not bundled: the repo's licence leaves third-party data out; same as
|
|
// `storebound prices ppp --update-bigmac`)
|
|
// Not run in CI (network). Sources: https://data.worldbank.org/indicator/PA.NUS.PPP,
|
|
// https://data.worldbank.org/indicator/PA.NUS.FCRF, https://github.com/TheEconomist/big-mac-data
|
|
import { readFileSync, writeFileSync } from 'node:fs';
|
|
import { join, resolve } from 'node:path';
|
|
import { parseArgs } from '../cli/lib/args';
|
|
import { datasetJson, datasetProblems, type PppDataset, WB, worldBankDataset } from '../cli/lib/ppp';
|
|
import { updateBigMac } from '../cli/prices-ppp';
|
|
|
|
const FILE = join(import.meta.dir, '..', 'cli', 'data', 'ppp-worldbank.json');
|
|
const a = parseArgs(process.argv.slice(2), ['check', 'bigmac']);
|
|
const today = new Date().toISOString().slice(0, 10);
|
|
|
|
async function json(url: string): Promise<never> {
|
|
const r = await fetch(url);
|
|
if (!r.ok) throw new Error(`${url} -> ${r.status}`);
|
|
return (await r.json()) as never;
|
|
}
|
|
|
|
if (a.has('check')) {
|
|
const ds = JSON.parse(readFileSync(FILE, 'utf8')) as PppDataset;
|
|
const days = Math.round((Date.parse(today) - Date.parse(ds.retrieved)) / 86_400_000);
|
|
console.log(`ppp-worldbank.json: retrieved ${ds.retrieved} (${days} days ago), data up to ${ds.year}, ${Object.keys(ds.countries).length} countries${days > 365 ? ' - older than a year: run bun tools/update-ppp.ts' : ''}`);
|
|
const p = datasetProblems(ds);
|
|
if (p.length) { console.error(p.join('\n')); process.exit(1); }
|
|
} else if (a.has('bigmac')) {
|
|
await updateBigMac(resolve(a.str('project', process.cwd())), a.has('dry'));
|
|
} else {
|
|
const to = new Date().getFullYear();
|
|
const [ppp, fx, countries] = await Promise.all([json(WB.api(WB.ppp, 2018, to)), json(WB.api(WB.fx, 2018, to)), json(WB.countries)]);
|
|
const ds = worldBankDataset(ppp, fx, countries, today);
|
|
const p = datasetProblems(ds);
|
|
if (p.length) throw new Error(p.join('; '));
|
|
writeFileSync(FILE, datasetJson(ds));
|
|
console.log(`wrote ${FILE}: ${Object.keys(ds.countries).length} countries, data up to ${ds.year}, retrieved ${today}`);
|
|
for (const n of ds.notes ?? []) console.log(` note: ${n}`);
|
|
}
|