Release v1.0.0#1
Merged
Merged
Conversation
…eGetCurrency, safeGetSymbol) covered by jest and tsd test suites. Tighten tsconfig and the build script so test files stay out of typecheck and dts-bundle-generator's resolution graph.
…e bundled data's per-source citations and per-field licensing are documented before the first publish.
… GitHub Actions CI workflow and structured issue templates for bugs, features, and data corrections.
…n files so the licensing chain referenced from LICENSE, NOTICE, and the data-file headers is self-contained inside the published tarball.
…ing every maintenance-agency-recognized active currency, including the supranational codes EUR, XOF, XAF, XCD, XPF, XCG). Move CurrencyCode out of types.ts to a codegen'd src/codes.ts driven by scripts/codegen-codes.ts, lock the code list with a Jest snapshot, and tighten data-integrity assertions to per-record shape checks instead of hardcoded counts.
…reflect the full fiat dataset and codegen tooling. Update CONTRIBUTING with the codegen / snapshot-refresh workflow and add npm run codegen:check to the CI workflow.
All sub-project #2 deliverables are committed: full ~155-record ISO 4217 fiat dataset, codegen tooling, snapshot test, CI drift check, README/CHANGELOG/CONTRIBUTING updates.
…x Maps (sub-project #3). New exports: getCurrencyByNumeric, getCurrencyByCountry, getCurrenciesBySymbol, getCurrencyByLocale, isValidCode (type-narrowing guard), isCryptocurrency, isHistorical. Three new Maps built at module load (byNumericCode, byCountry, bySymbol). 66 tests, 100% coverage, 4.75 KB ESM.
…arse sub-project.
…operty-based round-trip tests.
Adds test for Intl.NumberFormat fallback path (symbol + toFixed) when Intl is unavailable, and test for variant: 'narrow' to cover all toCurrencyDisplay branches. Increases branch coverage from 94.73% to 97.36%, meeting the 95% threshold.
… version to 1.0.0-alpha.3.
…Unreleased CHANGELOG link.
…adonly arrays built once at module load. Cover with runtime tests, tsd type assertions, and a memoization check.
…y market cap, with chain identifiers and capped display decimals (≤8) since the format/parse path is JS-Number based. Split the data-integrity code-shape rule per type so fiat stays strict ISO-4217 alpha-3 while crypto tickers can be 2-10 letters, refresh the snapshot, regenerate src/codes.ts, and bump the size-limit caps to 8 KB ESM / 9 KB CJS to fit the larger dataset.
…rencies covering the twelve original Eurozone predecessors, the seven later Eurozone joiners, and notable redenominations across the post-Soviet, ex-Yugoslav, and emerging-market transitions. Refresh the dataset snapshot and regenerate src/codes.ts.
…rypto/listHistorical, the top-50 cryptocurrency expansion, and the 30-record historical dataset. Refresh README data-scope copy and the public roadmap to reflect what shipped this cycle and what's queued next.
…ackages stay one-line: currency-core/compat/symbol-map exports a flat code→symbol Record, currency-core/compat/codes exports a readonly array of every shipped CurrencyCode, and currency-core/compat/exponent-map exports a code→{ code, base: 10, exponent } map for libraries that prefer explicit base/exponent. Each shim is built once at module load from the bundled dataset, ships as its own self-contained ESM/CJS bundle plus .d.ts (Rollup multi-input + dts-bundle-generator config), is wired through package.json#exports, and carries its own size-limit budget (7 KB ESM each, currently 6.55-6.58 KB).
…e record. Each src/currencies/<CODE>.ts is codegen'd from the bundled dataset (236 entries) with only a type-only Currency import — the emitted .esm.js is roughly the literal record alone, so importing currency-core/currencies/USD pulls in ~200 bytes instead of the full dataset. Wire the entries through Rollup multi-config, dts-bundle-generator config, package.json#exports wildcard, package.json#files, and a CI codegen drift check. Exclude the generated tree from coverage measurement since the files are pure data literals.
…r-currency tree-shake entries and the three compat subpaths. Refresh the README with quick-start examples for currency-core/currencies/<CODE> and currency-core/compat/* and move the now-shipped items out of the public roadmap.
…, diffs the active fiat and historical datasets against upstream, auto-applies safe field updates (decimals, numericCode) with --apply, and writes the surviving drift to regen-report.md for manual curation. Name spelling drift is intentionally not surfaced because SIX prefers terse country-noun forms ("Schilling", "Pakistan Rupee") while the bundled data uses clearer English; historical "new upstream" entries are also suppressed because the 30-record curation in historical.ts is intentional rather than exhaustive. The first run flags two real drift items already: VED (new ISO code distinct from our existing VES) and BGN (Bulgaria moving to historical with the 2026 Eurozone accession).
…s shipped crypto tickers absent from the top-200 by market cap. Scope is intentionally narrow — no auto-add of new tickers (avoids weekly snapshot churn) and no field-level updates from CoinGecko (the cheap markets endpoint does not expose decimals or chain, and per-coin lookups would hit free-tier rate limits). The first run flags WBTC, MATIC, MKR, FLOW, and EGLD for human review.
…egen:apply, refreshes the codegen and per-currency entry artifacts, updates the data-integrity snapshot, and opens or updates a stable data-regen/weekly PR via peter-evans/create-pull-request@v6. The workflow targets release/1.0.0 and emits no PR when upstream is unchanged. Bump to 1.0.0-beta.1 with the CHANGELOG entry covering the regen script, the cron, and the surfaced first-run drift items.
…the gate so PRD NFR-3 (full bundle ≤30 KB) and NFR-4 (single-currency tree-shake ≤500 B) are enforced on every PR rather than informally tracked. The main bundle goes to 10 KB ESM/CJS (current 7.16/7.33 KB brotlied — 40% headroom for v1.x data growth before the cap moves), compat shims to 8 KB each, and currencies/USD as the per-currency probe at 500 B (measures 183 B brotlied — 63% margin). Also add an ESLint no-restricted-imports rule scoped to src/ that bans node:* plus the bare-name builtins (fs, path, crypto, child_process, http, process, stream, buffer, url, util, tls, net, https, events, os, zlib, fs/promises) so cross-runtime portability is caught at lint time, not as nine cryptic Bun/Deno/Workers/RN smoke failures. The scripts/ tree is exempt and continues to use node:fs / node:path for codegen and regen tooling.
…ode version, and clean up the three real packaging bugs it surfaced. The .esm.js / .cjs.js dist outputs are renamed to .mjs / .cjs so Node stops defaulting them to CJS (resolves attw's UnexpectedModuleSyntax and the noisy MODULE_TYPELESS_PACKAGE_JSON log for direct-path consumers); the compat shims switch from default to named exports — { symbolMap }, { codes }, { exponentMap } — because the previous module.exports = X paired with .d.ts export default X tripped attw's FalseExportDefault for TS-under-node16 CJS importers. A new scripts/dual-dts.ts post-build step duplicates each .d.ts to .d.mts / .d.cts siblings and package.json#exports routes import.types → .d.mts, require.types → .d.cts, removing the Masquerading-as-CJS flag without forcing "type": "module" through the rollup / jest configs. The only attw suppression is --ignore-rules no-resolution, which covers the unfixable Node-10 exports-map gap on compat subpaths (we're Node-18+ baseline). Add a runtime-agnostic smoke runner at smoke/run.mjs that imports the built bundle and exercises every public subpath, plus matrix CI jobs for Bun (oven-sh/setup-bun@v2) and Deno v2.x (denoland/setup-deno@v2) that run the same smoke against the dist/ produced on each runner. Both compat-shim and dist-extension changes were possible without a deprecation cycle because nothing has shipped to npm yet.
…e CI matrix beyond the Node / Bun / Deno path. Browser smoke drives Chromium / Firefox / WebKit through Playwright against a static page (smoke/browser/index.html) that loads the built dist/ over a tiny http.createServer rooted at the package; Cloudflare Workers smoke pre-bundles smoke/workers/worker.mjs with esbuild using the worker / browser / import resolution conditions Wrangler ships with, then runs the bundle under workerd via miniflare and asserts on the JSON response; React Native smoke bundles smoke/rn/smoke.mjs with esbuild using the react-native / browser / import conditions metro applies and then statically scans the bundled output for any forbidden Hermes-incompatible primitives (node:* imports, process. other than process.env, Buffer, __dirname, __filename, global., bare require()) before executing the bundle. Real RN device-runtime testing is intentionally deferred to the @currency-core/react companion package — the V8 / JSC runtime substance is already covered by the Workers and browser smokes, and pulling react-native + metro into devDeps for one smoke is not justified. New devDeps: playwright, miniflare, esbuild. Lint config gains a smoke/browser/** scope so window / document references in the Playwright runner are not flagged as undefined.
…cross-runtime hardening). Captures the new Bun / Deno / Workers / RN / Playwright smoke surface, the arethetypeswrong gate, the hard size-limit caps, the lint ban on node:* in src/, and the two beta-window-only dist breakages — .esm.js / .cjs.js outputs renamed to .mjs / .cjs and compat shims switched from default to named exports — that attw forced and that no published version had to absorb.
…ct + SCSS app per playbook §8, with the library wired in via path alias (currency-core plus the three /compat/* subpaths) so HMR fires on src/ edits with no rebuild and demo/ has its own package.json + lockfile that CI installs in isolation. Five panels cover roadmap row #9: hero live code lookup with quick-pick chips and full Currency-record render, format playground (locale + variant + signDisplay + parse round-trip + toMinor / fromMinor preview), country↔currency explorer with country-code and BCP 47 locale-tag tabs, a 236-row currency browser table filterable by type / status / free-text across code+name+symbol+country, and a symbol disambiguator showing every currency that shares an entered symbol. Chrome is sticky Navbar + Sidebar (intersection-observer active-section tracking) wrapped in skip-link + main + Footer, with a pre-hydration theme script in <head> to avoid FOUC and a two-layer SCSS palette (raw colors → semantic CSS custom properties) themed on emerald (#10b981 dark / #059669 light) — matching the sister postal-code-checker demo for portfolio coherence — plus currency-specific gold / slate / rose tokens for the type chips on crypto / fiat / historical records. The .github/workflows/deploy-demo.yml job ships alongside, triggered on demo/** + src/** pushes to master, builds with VITE_BASE=/currency-core/ for the GitHub Pages subpath, and uploads demo/dist as the Pages artifact. demo/ is excluded from the npm tarball by the existing files allowlist (verified via npm pack --dry-run). The .gitignore gains demo/vite.config.{js,d.ts} so the tsc -b emit artifacts that sit alongside the source vite.config.ts (Vite reads the .ts directly and the emit is unused) stay out of the tree.
…ht mode / `#009CDE` dark mode — both real PayPal brand shades, paired so the navy is the AA-contrast match against white surfaces and the cyan-blue carries on dark surfaces where the navy disappears against ink-900). PayPal blue is neutral on the East-vs-West color convention for finance — green = up in Western markets but green = down in CN/JP/KR markets, so a green accent quietly takes a side that a global ISO 4217 + crypto package shouldn't — and visually distinct from the sister postal-code-checker demo so the two read as separate packages rather than one product. The two-layer palette architecture (raw SCSS → semantic CSS custom properties) absorbed the change inside _theme.scss alone — every component reads var(--color-accent) and picked up the new value automatically with zero TSX edits. The currency-specific gold / slate / rose tokens for the crypto / fiat / historical type chips stay untouched since those carry information rather than brand. The favicon flips from emerald-bg + dark-glyph to navy-bg + white-glyph for the same readability reason, and the index.html theme-color meta moves to #003087 so the mobile browser chrome matches.
…first cut. Five new sections land between the existing chrome — InstallMatrix (npm/yarn/pnpm/bun/deno tabs with copy-to-clipboard), UseCases (six real-world drop-ins covering price display, payment-gateway numeric round-trip, multi-currency cart, crypto wallet labels, historical-currency tooltip, country-aware default), LiveEditor (CodeMirror-backed playground via a new ExamplePlayground primitive that evals snippets through new Function with the full library injected as parameters; ten presets cover lookup helpers, safe variants, getCurrencyByNumeric, country and locale resolution, symbol disambiguation, the type predicates, listCrypto / listHistorical, format with all variants, parse round-trip, and minor-unit conversion), CodeExamples (static reference blocks for the build-time API surface that can't run in an eval — per-currency tree-shake imports with the 183-byte brotlied size badge, and the three compat shims symbolMap / codes / exponentMap, plus a TypeScript type-narrowing pattern and a tiny React useCurrency hook), and Faq (eight collapsible questions covering scope, the 8-decimal crypto cap, framework support, bundle sizes, data sources, regen cadence, custom-currency roadmap, and the no-rates scope decision). The ExamplePlayground reads the resolved theme and swaps between darcula and githubLight so syntax highlighting tracks the surrounding palette. Sections data and Sidebar grow to ten anchors so the new panels show up in the sticky nav with intersection-observer tracking. App.tsx interleaves the new sections in reading order — Hero → Install → Format → Country → UseCases → Playground → Snippets → Browser → Symbols → FAQ — so a visitor can scan top-to-bottom and hit every API method along the way. New deps in demo/package.json: @uiw/react-codemirror, @codemirror/lang-javascript, @uiw/codemirror-theme-darcula, @uiw/codemirror-theme-github (pinned to exact versions to match the sister postal-code-checker demo's lockstep). Bundle grew from 213 KB / 63 KB gzipped to 753 KB / 246 KB gzipped — entirely the CodeMirror editor weight, the same cost the sister demo absorbs for the live-playground feature, and only the demo bundle (the published library is still 7 KB).
…ps getting linted from the root. Flat-config patterns are anchored to the project root, so the previous `dist/**` only matched the package's own dist (which never exists in source-tree state) and silently let `demo/dist/**` through — which triggered 2044 errors against minified bundle output the moment the demo was built locally. Patterns are now `**/dist/**`, `**/node_modules/**`, `**/coverage/**`, plus an explicit `demo/**` ignore since the demo is a standalone subproject with its own deps and would need its own ESLint config to lint cleanly. The root ESLint now only sees src/, scripts/, smoke/, and the root config files — exactly its intended surface.
…allout flips from "1.0.0-alpha cycle" to a stable-API statement; the Quick start drops the `@next` dist-tag mention since the very first npm publish is the GA publish (the entire alpha / beta / rc cycle was internal-only, no version was ever pushed to npm); the bundle-size bullet updates from the stale ~680 B / ~762 B numbers (those were measured against the original 6-currency seed in sub-project #1) to the current 7.16 KB / 7.33 KB brotlied figures and surfaces the 183 B per-currency tree-shake number that NFR-4 enforces; the Roadmap section collapses the stale "in progress" + "planned" buckets (data-regen pipeline, cross-runtime hardening, demo site — all shipped) into a single "What v1.0 ships" enumeration plus a forward-looking "Beyond v1.0" paragraph. A new "Other exports" subsection enumerates the 13 API methods that landed in sub-projects #3–#7 but had never made it into the README's hand-authored API reference (reverse lookups, predicates, listings, format / parse, minor units, per-currency tree-shake imports, the three compat shims) — one-line each, with a pointer to dist/index.d.ts for full signatures and the demo for runnable snippets, so visitors see the whole public surface without the README ballooning to per-method docs that better belong in a 1.0.1 follow-up. The CHANGELOG gains a `## [1.0.0] - 2026-05-02` block at the top with a narrative summary of what shipped (lookup surface, reverse lookups, predicates / listings, format / parse / minor units, dataset, tree-shake entries, compat shims, dual ESM/CJS + attw, size budgets, cross-runtime CI matrix, weekly regen, interactive demo). The pre-release entries below it are kept verbatim as implementation history for future maintainers, with a one-line note that none were published to npm. The pre-1.0 dist-tag advisory line is dropped from the changelog header for the same reason.
…-alpha.0 through 1.0.0-rc.0 across sub-projects #1–#9; the next push to master triggers the GA publish to the latest dist-tag and the v1.0.0 tag on the merge commit.
…he GitHub repo's actual default branch is main and never got renamed (the local roadmap and playbook §2 both said master, but the rename in sub-project #1 was aspirational and didn't happen on the remote — keeping main matches reality with zero external link breakage). ci.yml push and pull_request triggers now listen on release/** + main; deploy-demo.yml triggers on main pushes so the GitHub Pages build fires after the v1.0.0 merge instead of waiting on a branch that doesn't exist; data-regen.yml's peter-evans PR action targets base: main so the weekly regen lands on the trunk after GA closes the release/1.0.0 branch.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
First public release of
currency-core. Closes the long-livedrelease/1.0.0branch — sub-projects #1–#9 land in one merge tomain, the GA version goes tolatest, and thev1.0.0tag goes on the merge commit. Nothing in the alpha / beta / rc cycle was published to npm; this is the first npm publish for the package.What v1.0 ships
getCurrency,getSymbol,getName,getDecimalswith dual overloads.safeGetCurrency/safeGetSymbolfor never-throw variants. Runtime.toUpperCase()backstop againstas CurrencyCodecasts.getCurrencyByNumeric(ISO 4217 numeric → record),getCurrencyByCountry(ISO 3166-1 alpha-2 → primary),getCurrencyByLocale(BCP 47 → primary via region subtag),getCurrenciesBySymbol(symbol → array).isValidCode(TypeScript user-defined type guard),isCryptocurrency,isHistorical,listCrypto,listHistorical.formatwrapsIntl.NumberFormatwith locale + variant + signDisplay options and a graceful symbol +toFixedfallback.parseis the inverse with locale-aware decimal-separator detection.toMinor/fromMinorfor major↔minor unit conversion. Property-based round-trip tests viafast-check.list-one.xml), top-50 crypto withchainidentifiers and decimals capped at 8 (CoinGecko top-200), 30 historical (SIXlist-three.xml).import { USD } from "currency-core/currencies/USD"— 236 entries, 500-byte hard cap per entry (NFR-4); USD measures 183 B brotlied.currency-core/compat/symbol-map,/compat/codes,/compat/exponent-map— named exports, attw-clean.arethetypeswrongdual-resolution gate green on every subpath..d.mts/.d.ctssiblings let the type resolver pick the right declaration per condition.src/, snapshot-locked dataset,tsdtype-level assertions,verify:headersdata-citation enforcement, ESLintno-restricted-importsban onnode:*and bare-builtin imports insidesrc/.data-regen/weeklyPR on upstream changes.https://sashiksu.github.io/currency-core/— live code lookup, format playground, country↔currency explorer, 236-row filterable browser, symbol disambiguator, install-matrix tabs, six real-world use-case snippets, CodeMirror live playground covering every runtime API method, static reference blocks for build-time API (per-currency tree-shake + compat shims), and FAQ.Local verification (all green on
c49c0c7)npm run lintnpm run typechecknpm test— 133 / 133, 100% coveragenpm run test:types— tsdnpm run verify:headers— 3/3 data files cite sourcesnpm run codegen:check— 236 records in syncnpm run codegen:currencies:check— 236 entries + dts config in syncnpm run build— Rollup + dts-bundle-generator + dual-dtsnpm run size— every cap respectednpm run attw— every subpath green across node10 / node16-CJS / node16-ESM / bundlernpm run smoke:workers— workerd via miniflarenpm run smoke:rn— esbuild bundler resolution + structuralnpm run smoke:browser— Chromium + Firefox + WebKitnpm pack --dry-run—currency-core-1.0.0.tgz181 KB packed, nodemo/leakageTest plan for CI
arethetypeswronggate green per Node versionsize-limitgate green per per-currency entry, compat shim, and main bundlecodegen:checkandverify:headersgates greenWorkflow rename note
The last commit on this branch (
c49c0c7) repoints the CI / deploy / regen workflows frommastertomainsince the repo's actual default branch ismain(the local docs aspirationally saidmasterbut the rename never happened). After this PR merges, the deploy-demo workflow will fire on themainpush and rebuild the GitHub Pages site athttps://sashiksu.github.io/currency-core/.Post-merge release steps (manual)
git tag v1.0.0 <merge-sha> && git push origin v1.0.0npm publish --access public— needs OTP; per playbook §10 use the--ignore-scriptsworkaround ifprepare+prepublishOnlypush past the 30s OTP windownpm install currency-corefrom a scratch dir, confirm version1.0.0and the bundled exports resolvedocs/marketing.md