# Migration Guide

Upgrade notes for each major version, with concrete before/after guidance for every breaking change. See [CHANGELOG.md](CHANGELOG.md) for the full release history, including non-breaking changes.

---

## Upgrading to v3.0.0 (unreleased)

Tracked in [#328](https://github.com/Monsieur-Nico/textConvert/issues/328). Each item below is filled in with real before/after details in the PR that implements it, and checked off alongside its matching checkbox in #328 — check back here, not just the CHANGELOG, before upgrading past v2.x.

- [x] **ISO 639-1 language codes** ([#329](https://github.com/Monsieur-Nico/textConvert/issues/329)) — `detectLanguage`'s `Language` enum now uses ISO 639-1 codes instead of English names: `English` -> `'en'` (was `'english'`), `French` -> `'fr'` (was `'french'`), `Spanish` -> `'es'` (was `'spanish'`), `German` -> `'de'` (was `'german'`), `Italian` -> `'it'` (was `'italian'`), `Portuguese` -> `'pt'` (was `'portuguese'`), `Dutch` -> `'nl'` (was `'dutch'`). `Unknown` now uses `'und'` (was `'unknown'`) — the same "undetermined" token `franc` and BCP-47 tooling use, rather than a fabricated ISO-looking code, since ISO 639-1 itself has no "unknown" entry. Code doing `result.language === 'french'` (string literal, bypassing the enum) breaks; code comparing against `Language.French` etc. is unaffected.
- [x] **ESM-only, CJS dropped** ([#331](https://github.com/Monsieur-Nico/textConvert/issues/331)) — `require('textconvert')` no longer works; use `import` instead. In practice this formalizes something that was already broken: the package's `"type": "module"` meant Node treated the previously-shipped `dist/textConvert.js` (a CJS-format file with a plain `.js` extension) as ESM, so `require('textconvert')` already threw `ReferenceError: exports is not defined` before this change — nobody was actually able to use it. `package.json`'s `exports`/`main` now point only at the ESM bundle (`dist/textConvert.mjs`).
- [x] **`spread()`'s return type, error messages, and undocumented quirks** ([#389](https://github.com/Monsieur-Nico/textConvert/issues/389)) — `spread` now always returns `string[]`, using `[]` for invalid input instead of a string error message (`spread(123)` was `'Input text should be a string!'`, now `[]`; `spread('')` was `'Please provide a valid text input'`, now `[]`) — matching `extractEmails`/`extractUrls`/etc.'s existing convention for array-returning functions. Also drops two undocumented quirks: `spread` no longer uppercases the input's first character (`spread('hello')` was `['H', 'e', ...]`, now `['h', 'e', ...]`), and no longer strips whitespace from the output (`spread('cat dog')` was `['c', 'a', 't', 'd', 'o', 'g']`, now `['c', 'a', 't', ' ', 'd', 'o', 'g']` — every character of the input is now preserved verbatim).
- [x] **`numbersToWords`'s missing "and"** ([#393](https://github.com/Monsieur-Nico/textConvert/issues/393)) — adds the same `'and'` the hundred-branch already inserts (e.g. `'one hundred and five'`) to the thousand/million branches too, for numbers whose remainder is under 100 (e.g. `'one hundred thousand and five'`, not `'one hundred thousand five'`). **Also affects `ordinalToWords`**, which ordinalizes the last word of whatever `numbersToWords` produces: `ordinalToWords(100005)` gains the same `'and'` (`'one hundred thousand and fifth'`, not `'one hundred thousand fifth'`) even though `ordinalToWords` itself isn't otherwise changing.
