{"id":50726002,"url":"https://github.com/adesurirey/fresh-currency-codes","last_synced_at":"2026-06-10T04:01:57.524Z","repository":{"id":360987098,"uuid":"1252577502","full_name":"adesurirey/fresh-currency-codes","owner":"adesurirey","description":"TypeScript ISO 4217 currency lookup, auto-refreshed weekly from the SIX-Group XML.","archived":false,"fork":false,"pushed_at":"2026-05-28T17:45:57.000Z","size":38,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-28T19:21:12.638Z","etag":null,"topics":["bun","currency","esm","iso4217","typescript"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/adesurirey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-28T16:56:03.000Z","updated_at":"2026-05-28T17:46:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/adesurirey/fresh-currency-codes","commit_stats":null,"previous_names":["adesurirey/fresh-currency-codes"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/adesurirey/fresh-currency-codes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adesurirey%2Ffresh-currency-codes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adesurirey%2Ffresh-currency-codes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adesurirey%2Ffresh-currency-codes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adesurirey%2Ffresh-currency-codes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adesurirey","download_url":"https://codeload.github.com/adesurirey/fresh-currency-codes/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adesurirey%2Ffresh-currency-codes/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34136112,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bun","currency","esm","iso4217","typescript"],"created_at":"2026-06-10T04:01:56.727Z","updated_at":"2026-06-10T04:01:57.519Z","avatar_url":"https://github.com/adesurirey.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fresh-currency-codes\n\nA TypeScript-first lookup library for ISO 4217 currency data, auto-refreshed weekly from the canonical [SIX-Group XML](https://www.six-group.com/dam/download/financial-information/data-center/iso-currrency/lists/list-one.xml). Active and deprecated currencies, ISO-official country names, and a `publishDate` export so consumers can see exactly how fresh the data is.\n\n\u003e [!NOTE]\n\u003e This library is inspired by [`freeall/currency-codes`](https://github.com/freeall/currency-codes). The data shape, sourcing pipeline, and a few API contracts have been tightened; see [Divergences](#divergences-from-currency-codes) below.\n\n## Performance\n\nThis library is **significantly faster** than the original `currency-codes` library. It uses O(1) `Map` indexes and cached list data, while still returning defensive copies for array-returning helpers to keep caller semantics safe. In the latest benchmark run, lookups were approximately **17–2456× faster** than the original O(n) scan-based behavior.\n\n## Requirements\n\n- Node.js **22+**\n- ESM-only published artifact (no CJS build) — see [ADR-0008](./docs/adr/0008-esm-only-published-artifact.md)\n\nCJS consumers on Node 22.12 or later can `require()` this package directly thanks to `require(esm)`. On Node 22.0–22.11 use `await import('fresh-currency-codes')`.\n\n## Installation\n\n```sh\nnpm install fresh-currency-codes\n```\n\n```sh\nyarn add fresh-currency-codes\n```\n\n```sh\npnpm add fresh-currency-codes\n```\n\n```sh\nbun add fresh-currency-codes\n```\n\n## Import\n\n```ts\nimport * as cc from 'fresh-currency-codes'\n```\n\nOr named:\n\n```ts\nimport { code, country, number, publishDate } from 'fresh-currency-codes'\n```\n\n## Basic usage\n\n### Look up by code\n\n```ts\ncc.code('EUR')\n// {\n//   active: true,\n//   code: 'EUR',\n//   countries: [\n//     'åland islands',\n//     'andorra',\n//     'austria',\n//     'belgium',\n//     'bulgaria',\n//     'croatia',\n//     'cyprus',\n//     'estonia',\n//     'european union',\n//     'finland',\n//     'france',\n//     'french guiana',\n//     'french southern territories (the)',\n//     'germany',\n//     'greece',\n//     'guadeloupe',\n//     'holy see (the)',\n//     'ireland',\n//     'italy',\n//     'latvia',\n//     'lithuania',\n//     'luxembourg',\n//     'malta',\n//     'martinique',\n//     'mayotte',\n//     'monaco',\n//     'montenegro',\n//     'netherlands (the)',\n//     'portugal',\n//     'réunion',\n//     'saint barthélemy',\n//     'saint martin (french part)',\n//     'saint pierre and miquelon',\n//     'san marino',\n//     'slovakia',\n//     'slovenia',\n//     'spain',\n//   ],\n//   currency: 'Euro',\n//   digits: 2,\n//   number: '978',\n// }\n```\n\n### Look up by ISO numeric code\n\n`number()` takes a **string** — ISO numeric codes are zero-padded 3-digit values and the leading zero matters (see [ADR-0006](./docs/adr/0006-number-parameter-as-string.md)).\n\n```ts\ncc.number('978')\n// {\n//   active: true,\n//   code: 'EUR',\n//   countries: [ /* same list as above */ ],\n//   currency: 'Euro',\n//   digits: 2,\n//   number: '978',\n// }\n```\n\n### Look up by country\n\nCountry names are the ISO-official label, lowercased verbatim (see [ADR-0004](./docs/adr/0004-iso-official-country-names.md)) — not friendly aliases.\n\n```ts\ncc.country('colombia')\n// [\n//   {\n//     active: true,\n//     code: 'COP',\n//     countries: ['colombia'],\n//     currency: 'Colombian Peso',\n//     digits: 2,\n//     number: '170',\n//   },\n//   {\n//     active: true,\n//     code: 'COU',\n//     countries: ['colombia'],\n//     currency: 'Unidad de Valor Real',\n//     digits: 2,\n//     number: '970',\n//   },\n// ]\n```\n\n### List all codes / numbers / countries\n\n```ts\ncc.codes()\n// =\u003e ['AED', 'AFN', 'ALL', ...]\n\ncc.numbers()\n// =\u003e ['784', '971', '008', ...]\n\ncc.countries()\n// =\u003e ['united arab emirates (the)', 'afghanistan', 'albania', ...]\n```\n\n### List all currency records\n\n```ts\ncc.currencies()\n// [\n//   {\n//     active: true,\n//     code: 'AED',\n//     countries: ['united arab emirates (the)'],\n//     currency: 'UAE Dirham',\n//     digits: 2,\n//     number: '784',\n//   },\n//   {\n//     active: true,\n//     code: 'AFN',\n//     countries: ['afghanistan'],\n//     currency: 'Afghani',\n//     digits: 2,\n//     number: '971',\n//   },\n//   // ...\n// ]\n```\n\n### Inspect when the data was last refreshed\n\n```ts\nconsole.log(cc.publishDate)\n// =\u003e '2026-01-01'\n```\n\n## Including deprecated currencies\n\nDeprecated currencies are filtered out by default. Opt in with `{ includeDeprecated: true }` on any of the lookup methods.\n\n```ts\ncc.code('ZWL')\n// =\u003e undefined\n\ncc.code('ZWL', { includeDeprecated: true })\n// {\n//   active: false,\n//   code: 'ZWL',\n//   countries: ['zimbabwe'],\n//   currency: 'Zimbabwe Dollar',\n//   digits: 2,\n//   number: '932',\n// }\n```\n\nThe same option works on `number()`, `country()`, `codes()`, `numbers()`, `countries()`, and `currencies()`.\n\n## `digits: null` semantics\n\nISO publishes `N.A.` for currencies that have **no minor unit at all** (gold, IMF SDRs, the bond-market funds units). We surface this as `digits: null` — semantically distinct from `digits: 0`, which means a defined zero minor units (e.g. JPY). See [ADR-0003](./docs/adr/0003-digits-nullable-for-no-minor-unit.md).\n\n```ts\ncc.code('XAU')\n// {\n//   active: true,\n//   code: 'XAU',\n//   countries: ['zz08_gold'],\n//   currency: 'Gold',\n//   digits: null,\n//   number: '959',\n// }\n```\n\nConsumers must handle the `null` case explicitly — flattening it to `0` silently corrupts records like XAU.\n\n## Freshness\n\nThe point of this fork is that the dataset stays current without anyone remembering to bump it.\n\n- **Weekly auto-refresh** via GitHub Actions, sourced exclusively from the SIX-Group XML ([`list-one.xml`](https://www.six-group.com/dam/download/financial-information/data-center/iso-currrency/lists/list-one.xml)).\n- **Sanity-guarded** on every refresh: at least 100 active currencies, no more than 10 removals in a single run, and `publishDate` must not regress. A guard failure aborts the refresh and leaves the previous dataset intact.\n- **Auto-published on merge** — when a refresh PR (or any version-bumping PR) merges into `main`, the publish workflow ships the new version to npm. See [ADR-0007](./docs/adr/0007-auto-publish-on-version-bump-merge.md).\n\nThe `publishDate` export is the canonical freshness signal — it mirrors the `Pblshd` field of the SIX-Group XML, not the npm publish date.\n\n### Stability contract\n\nFrom `1.0.0`, this package follows semver — but for a deliberately *living* dataset. The 1.x guarantee covers the **public API** and the **data shape** (the `CurrencyCodeRecord` structure, function signatures, and `digits: null` semantics), **not the data values**. Currency additions and deprecations are expected weekly churn shipped as `patch` releases; they are not breaking changes. A `2.0.0` is reserved for human-gated changes to the API or data shape. See [ADR-0010](./docs/adr/0010-v1-stability-contract-covers-api-and-shape-not-data.md).\n\nIf you need a **frozen snapshot** of the data — e.g. for reproducible builds or to insulate against a currency being deprecated upstream — pin an exact version (`fresh-currency-codes: \"1.2.3\"`) rather than a range (`^1.0.0`).\n\n## Changelog\n\nRelease notes for every version live on the [GitHub Releases page](https://github.com/adesurirey/fresh-currency-codes/releases). Automated data refreshes carry their added/deprecated counts; manual API changes carry hand-written notes.\n\n## Divergences from `currency-codes`\n\n| Behaviour | `freeall/currency-codes` | `fresh-currency-codes` |\n| --- | --- | --- |\n| `number()` parameter | `string` or `number` | **`string` only** (preserves leading zeros — see [ADR-0006](./docs/adr/0006-number-parameter-as-string.md)) |\n| `number` field on records | `number` | **`string`** (e.g. `'008'` for ALL) |\n| Country names | curated friendly aliases | **ISO-official label, lowercased verbatim** (e.g. `'united kingdom of great britain and northern ireland (the)'` — see [ADR-0004](./docs/adr/0004-iso-official-country-names.md)) |\n| `digits` for `N.A.` entries | `number` (often coerced to `0`) | **`number \\| null`**, with `null` for entries that have no minor unit at all (see [ADR-0003](./docs/adr/0003-digits-nullable-for-no-minor-unit.md)) |\n| Deprecated currencies | filtered out, no opt-in | **opt-in via `{ includeDeprecated: true }`** |\n| Freshness signal | none | **`publishDate` export** mirroring the SIX-Group XML |\n| Data sourcing | hand-curated | **auto-refreshed weekly** from the SIX-Group XML — no hand-curated entries |\n| Performance | O(n) array scans for all lookups | **O(1) Map lookups and precomputed arrays** — up to 50–2500× faster |\n| Runtime dependencies | Yes | **none** (zero runtime deps) |\n\n## Updating the data manually\n\nThe dataset refreshes automatically every week, so this is rarely needed. To pull a snapshot locally:\n\n```sh\nbun run iso\n```\n\nThis fetches the latest `list-one.xml` from SIX-Group and rewrites `src/data.json`.\n\n## Project structure\n\n- [`CONTEXT.md`](./CONTEXT.md) — domain glossary (Currency, Code, Number, Country, Digits, Publish date, Active, Deprecated, SIX-Group list).\n- [`docs/adr/`](./docs/adr/) — architectural decision records (ADRs 0001–0010).\n\n## License\n\nMIT © Arnaud de Surirey — see [`LICENSE`](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadesurirey%2Ffresh-currency-codes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadesurirey%2Ffresh-currency-codes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadesurirey%2Ffresh-currency-codes/lists"}