|
| 1 | +#!/usr/bin/env node |
| 2 | +// Copyright (c) 2026 The Linux Foundation and each contributor. |
| 3 | +// SPDX-License-Identifier: MIT |
| 4 | +// |
| 5 | +// Reads mledoze_countries_snapshot.json, a checked-in snapshot of countries.json |
| 6 | +// pinned at https://github.com/mledoze/countries/blob/09b28e3d03e6ca3fbbac996d716a50d929781e8c/countries.json |
| 7 | +// so re-running this script later doesn't depend on network access or pick up upstream drift. |
| 8 | + |
| 9 | +const fs = require('fs'); |
| 10 | +const path = require('path'); |
| 11 | + |
| 12 | +const PIPE_PATH = path.join(__dirname, '../pipes/country_mapping.pipe'); |
| 13 | +const FIXTURES_DIR = path.join(__dirname, '../datasources/fixtures'); |
| 14 | +const MLEDOZE_SNAPSHOT_PATH = path.join(__dirname, 'mledoze_countries_snapshot.json'); |
| 15 | + |
| 16 | +const UNKNOWN = 'Unknown'; |
| 17 | + |
| 18 | +// Extracts the ('Country', 'flag', 'CODE', offset) tuples from the arrayJoin([...]) literal |
| 19 | +// in country_mapping.pipe. |
| 20 | +function parsePipeCountries(pipeContent) { |
| 21 | + const tupleRegex = /\(\s*'((?:[^'\\]|\\.|'')*)'\s*,\s*'((?:[^'\\]|\\.|'')*)'\s*,\s*'([A-Z]{2})'\s*,\s*(-?\d+)\s*\)/g; |
| 22 | + const countries = []; |
| 23 | + let match; |
| 24 | + while ((match = tupleRegex.exec(pipeContent)) !== null) { |
| 25 | + const unescape = (s) => s.replace(/''/g, "'"); |
| 26 | + countries.push({ |
| 27 | + country: unescape(match[1]), |
| 28 | + flag: unescape(match[2]), |
| 29 | + country_code: match[3], |
| 30 | + timezone_offset: parseInt(match[4], 10), |
| 31 | + }); |
| 32 | + } |
| 33 | + return countries; |
| 34 | +} |
| 35 | + |
| 36 | +function main() { |
| 37 | + const pipeContent = fs.readFileSync(PIPE_PATH, 'utf8'); |
| 38 | + const countries = parsePipeCountries(pipeContent); |
| 39 | + console.error(`Parsed ${countries.length} countries from country_mapping.pipe`); |
| 40 | + |
| 41 | + const mledoze = JSON.parse(fs.readFileSync(MLEDOZE_SNAPSHOT_PATH, 'utf8')); |
| 42 | + |
| 43 | + const byCca2 = new Map(); |
| 44 | + for (const entry of mledoze) { |
| 45 | + if (entry.cca2) byCca2.set(entry.cca2, entry); |
| 46 | + } |
| 47 | + |
| 48 | + const rows = countries.map(({ country, flag, country_code, timezone_offset }) => { |
| 49 | + const match = byCca2.get(country_code); |
| 50 | + let region = UNKNOWN; |
| 51 | + let subregion = UNKNOWN; |
| 52 | + if (match) { |
| 53 | + region = match.region || UNKNOWN; |
| 54 | + subregion = match.subregion || UNKNOWN; |
| 55 | + } else { |
| 56 | + console.error(`WARNING: no mledoze match for country_code=${country_code} (${country}) — defaulting region/subregion to "${UNKNOWN}"`); |
| 57 | + } |
| 58 | + return { country, flag, country_code, timezone_offset, region, subregion }; |
| 59 | + }); |
| 60 | + |
| 61 | + fs.mkdirSync(FIXTURES_DIR, { recursive: true }); |
| 62 | + |
| 63 | + const withFlags = rows.map((row) => JSON.stringify(row)); |
| 64 | + fs.writeFileSync(path.join(FIXTURES_DIR, 'country_mapping_ds.ndjson'), withFlags.join('\n') + '\n'); |
| 65 | + |
| 66 | + const noFlags = rows.map(({ country, country_code, timezone_offset, region, subregion }) => |
| 67 | + JSON.stringify({ country, country_code, timezone_offset, region, subregion }), |
| 68 | + ); |
| 69 | + fs.writeFileSync(path.join(FIXTURES_DIR, 'country_mapping_no_flags_ds.ndjson'), noFlags.join('\n') + '\n'); |
| 70 | + |
| 71 | + console.error(`Wrote ${rows.length} rows to country_mapping_ds.ndjson and country_mapping_no_flags_ds.ndjson`); |
| 72 | +} |
| 73 | + |
| 74 | +try { |
| 75 | + main(); |
| 76 | +} catch (err) { |
| 77 | + console.error(err); |
| 78 | + process.exit(1); |
| 79 | +} |
0 commit comments