strict-money-parse 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +111 -167
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,219 +5,163 @@
|
|
|
5
5
|
[](https://bundlephobia.com/package/strict-money-parse)
|
|
6
6
|
[](https://www.typescriptlang.org/)
|
|
7
7
|
[](https://opensource.org/licenses/MIT)
|
|
8
|
-
[](https://github.com/yourusername/strict-money-parse)
|
|
9
8
|
[](https://github.com/MoneyConverter/strict-money-parse/actions)
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
Strict TypeScript library for parsing monetary values from strings with evidence-based currency detection.
|
|
12
11
|
|
|
13
|
-
|
|
12
|
+
Originally developed for [MoneyConvert.net](https://moneyconvert.net/).
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
## Table of contents
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
- [Installation](#installation)
|
|
17
|
+
- [🚀 Quick start](#-quick-start)
|
|
18
|
+
- [API](#api)
|
|
19
|
+
- [Options](#options)
|
|
20
|
+
- [Notes](#notes)
|
|
21
|
+
- [License](#license)
|
|
18
22
|
|
|
19
|
-
|
|
20
|
-
- [✨ Features](#-features)
|
|
21
|
-
- [📦 Installation](#-installation)
|
|
22
|
-
- [🚀 Quick Start](#-quick-start)
|
|
23
|
-
- [📖 API Reference](#-api-reference)
|
|
24
|
-
- [💡 Usage Examples](#-usage-examples)
|
|
25
|
-
- [European Number Formats](#european-number-formats)
|
|
26
|
-
- [Asian Currencies](#asian-currencies)
|
|
27
|
-
- [Handling Ambiguous Symbols](#handling-ambiguous-symbols)
|
|
28
|
-
- [ISO 4217 Code Detection](#iso-4217-code-detection)
|
|
29
|
-
- [False Positive Prevention](#false-positive-prevention)
|
|
30
|
-
- [HTML Content Parsing](#html-content-parsing)
|
|
23
|
+
## Installation
|
|
31
24
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
- [🤝 Contributing](#-contributing)
|
|
42
|
-
- [🙏 Acknowledgments](#-acknowledgments)
|
|
43
|
-
- [📞 Support](#-support)
|
|
44
|
-
- [🗺️ Roadmap](#️-roadmap)
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
## 🌍 Battle-Tested with Real-World Data
|
|
25
|
+
```bash
|
|
26
|
+
npm install strict-money-parse
|
|
27
|
+
# or
|
|
28
|
+
yarn add strict-money-parse
|
|
29
|
+
# or
|
|
30
|
+
pnpm add strict-money-parse
|
|
31
|
+
# or
|
|
32
|
+
bun add strict-money-parse
|
|
33
|
+
```
|
|
51
34
|
|
|
52
|
-
|
|
35
|
+
Node.js >= 18 is required.
|
|
53
36
|
|
|
54
|
-
|
|
55
|
-
- 🇪🇺 **Europe:** Germany, UK, France, Spain, Italy, Poland, Czech Republic, Switzerland, Sweden, Norway, Denmark, Hungary, Romania, Bulgaria, Greece, Albania
|
|
56
|
-
- 🇦🇸 **Asia:** Japan, China, South Korea, India, Indonesia, Thailand, Vietnam, Kazakhstan, Uzbekistan, Armenia, Israel, Georgia, Azerbaijan, Pakistan
|
|
57
|
-
- 🇿🇦 **Africa:** South Africa, Nigeria, Kenya, Ghana, Morocco, Algeria, Tunisia, Ethiopia
|
|
58
|
-
- 🇦🇺 **Oceania:** Australia, New Zealand, Papua New Guinea, Fiji, Vanuatu, Maldives
|
|
37
|
+
## 🚀 Quick Start
|
|
59
38
|
|
|
60
|
-
|
|
39
|
+
```ts
|
|
40
|
+
import { parsePriceString } from "strict-money-parse";
|
|
61
41
|
|
|
62
|
-
|
|
42
|
+
// Basic usage
|
|
43
|
+
parsePriceString("€1,234.56");
|
|
44
|
+
parsePriceString("1.234,56 €");
|
|
45
|
+
parsePriceString("USD 99.99");
|
|
46
|
+
parsePriceString("¥125,000");
|
|
47
|
+
```
|
|
63
48
|
|
|
64
|
-
##
|
|
49
|
+
## API
|
|
65
50
|
|
|
66
|
-
|
|
67
|
-
- ✅ **Evidence-Based Detection** – Provides proof of currency detection with confidence levels
|
|
68
|
-
- ✅ **Global Format Support** – Handles comma/dot decimals, space separators, European formats (\`.-\`, \`—\`, \`:-\`)
|
|
69
|
-
- ✅ **181 ISO 4217 Codes** – Complete support for all official currency codes
|
|
70
|
-
- ✅ **75+ Currency Symbols** – Including Unicode symbols (€, ₴, ₸, ₪, ฿, ₫, Rp, KSh, Kč, zł, TL, etc.)
|
|
71
|
-
- ✅ **Ambiguity Resolution** – Smart handling of \`$\`, \`£\`, \`¥\`, \`kr\`, \`Lei\`, \`Rs\`, \`р.\`, \`Fr\` symbols
|
|
72
|
-
- ✅ **False Positive Prevention** – Filters out phone numbers, dates, years, percentages, ranges, dimensions
|
|
73
|
-
- ✅ **Fully Typed** – Complete TypeScript support with strict types
|
|
74
|
-
- ✅ **Production-Ready** – 99.2% test coverage, extensively validated against real-world data
|
|
51
|
+
### `parsePriceString(input, options?)`
|
|
75
52
|
|
|
76
|
-
|
|
53
|
+
Parses a single price string and returns the best match.
|
|
77
54
|
|
|
78
|
-
|
|
55
|
+
**Parameters:**
|
|
79
56
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
```
|
|
57
|
+
- `input` (`string`): The string to parse (e.g., "$10.50", "1 200 RUB").
|
|
58
|
+
- `options` (`ParseOptions?`): Optional configuration object. See [Options](#options) below.
|
|
83
59
|
|
|
84
|
-
|
|
85
|
-
yarn add strict-money-parse
|
|
86
|
-
```
|
|
60
|
+
**Returns:** `ParseResult`
|
|
87
61
|
|
|
88
|
-
```
|
|
89
|
-
|
|
62
|
+
```ts
|
|
63
|
+
type CurrencyStatus = "CONFIRMED" | "AMBIGUOUS" | "UNKNOWN";
|
|
90
64
|
|
|
91
|
-
|
|
92
|
-
|
|
65
|
+
type ParseResult = {
|
|
66
|
+
status: CurrencyStatus; // Confidence level of the currency detection
|
|
67
|
+
rawAmount: number | null; // The parsed numeric value (e.g., 10.5)
|
|
68
|
+
currency: string | null; // ISO 4217 code (e.g., "USD") or symbol if unknown
|
|
69
|
+
symbol: string | null; // The detected currency symbol (e.g., "$")
|
|
70
|
+
currencyHints: string[]; // List of potential currency codes if ambiguous
|
|
71
|
+
evidence: {
|
|
72
|
+
matchedText: string; // The substring that was parsed
|
|
73
|
+
normalizedText: string; // Text after normalization
|
|
74
|
+
amountToken?: string; // The numeric part as a string
|
|
75
|
+
isoCodeFound?: string; // Detected ISO code
|
|
76
|
+
symbolFound?: string; // Detected symbol
|
|
77
|
+
};
|
|
78
|
+
};
|
|
93
79
|
```
|
|
94
80
|
|
|
95
|
-
|
|
81
|
+
### `parsePriceCandidates(input, options?)`
|
|
96
82
|
|
|
97
|
-
|
|
83
|
+
Finds all potential price candidates in a string. Useful when the input might contain multiple prices or noise.
|
|
98
84
|
|
|
99
|
-
|
|
85
|
+
**Parameters:**
|
|
100
86
|
|
|
101
|
-
|
|
87
|
+
- `input` (`string`): The text to search.
|
|
88
|
+
- `options` (`ParseCandidatesOptions?`): Configuration object. Extends `ParseOptions` with:
|
|
89
|
+
- `maxCandidates` (`number?`): Maximum number of candidates to return.
|
|
102
90
|
|
|
103
|
-
|
|
104
|
-
import { parsePriceString } from 'strict-money-parse';
|
|
91
|
+
**Returns:** `Candidate[]` (Array of `ParseResult` with additional scoring info)
|
|
105
92
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
// currency: 'EUR',
|
|
113
|
-
// symbol: '€',
|
|
114
|
-
// currencyHints: [],
|
|
115
|
-
// evidence: { ... }
|
|
116
|
-
// }
|
|
117
|
-
|
|
118
|
-
// Works with various formats
|
|
119
|
-
parsePriceString('$1,999.99'); // US format
|
|
120
|
-
parsePriceString('1.234,56 €'); // European format
|
|
121
|
-
parsePriceString('2 499 Kč'); // Czech format with space separator
|
|
122
|
-
parsePriceString('¥125,000'); // Japanese yen
|
|
123
|
-
parsePriceString('₴5,678.90'); // Ukrainian hryvnia
|
|
124
|
-
parsePriceString('USD 99.99'); // ISO code
|
|
125
|
-
parsePriceString('12.500,00 TL'); // Turkish lira
|
|
93
|
+
```ts
|
|
94
|
+
type Candidate = ParseResult & {
|
|
95
|
+
score: number; // Relevance score
|
|
96
|
+
indexStart: number; // Start index in the original string
|
|
97
|
+
indexEnd: number; // End index in the original string
|
|
98
|
+
};
|
|
126
99
|
```
|
|
127
100
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
## 📖 API Reference
|
|
101
|
+
### `buildCurrencyTables()`
|
|
131
102
|
|
|
132
|
-
|
|
103
|
+
Pre-builds currency data tables.
|
|
133
104
|
|
|
134
|
-
|
|
105
|
+
**Returns:** `CurrencyTables`
|
|
135
106
|
|
|
136
|
-
|
|
107
|
+
**Usage:**
|
|
108
|
+
If you are parsing thousands of strings, you can build the tables once and pass them to `parsePriceString` via options to improve performance.
|
|
137
109
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
- \`domain?: string\` – Domain/URL hint for ambiguous currency resolution
|
|
141
|
-
- \`ignorePercentages?: boolean\` – Whether to ignore percentages (default: \`false\`)
|
|
142
|
-
- \`maxFractionDigits?: number\` – Maximum decimal places (default: \`3\`)
|
|
110
|
+
```ts
|
|
111
|
+
import { buildCurrencyTables, parsePriceString } from "strict-money-parse";
|
|
143
112
|
|
|
144
|
-
|
|
113
|
+
const tables = buildCurrencyTables(); // Build once
|
|
145
114
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
currency: string | null; // ISO 4217 code or null
|
|
151
|
-
symbol: string | null; // Original currency symbol
|
|
152
|
-
currencyHints: string[]; // Possible currencies (when ambiguous)
|
|
153
|
-
evidence: Evidence; // Detection metadata
|
|
154
|
-
}
|
|
115
|
+
// Reuse in loop
|
|
116
|
+
data.forEach(str => {
|
|
117
|
+
parsePriceString(str, { tables });
|
|
118
|
+
});
|
|
155
119
|
```
|
|
156
120
|
|
|
157
|
-
|
|
121
|
+
## Options
|
|
158
122
|
|
|
159
|
-
|
|
160
|
-
- **\`AMBIGUOUS\`** – Multiple currencies possible (e.g., \`$\` could be USD, CAD, AUD, etc.)
|
|
161
|
-
- **\`UNKNOWN\`** – No currency detected or false positive filtered out
|
|
123
|
+
The `options` object allows you to fine-tune the parsing behavior.
|
|
162
124
|
|
|
163
|
-
|
|
125
|
+
### `domain`
|
|
164
126
|
|
|
165
|
-
|
|
127
|
+
- **Type:** `"price" | "fx" | "crypto"`
|
|
128
|
+
- **Default:** `"price"`
|
|
129
|
+
- **Description:** Sets the default `maxFractionDigits` based on the expected domain.
|
|
130
|
+
- `price`: 2 decimal places (standard retail prices).
|
|
131
|
+
- `fx`: 4 decimal places (foreign exchange rates).
|
|
132
|
+
- `crypto`: 8 decimal places (cryptocurrencies).
|
|
166
133
|
|
|
167
|
-
###
|
|
134
|
+
### `maxFractionDigits`
|
|
168
135
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
// → { status: 'CONFIRMED', rawAmount: 1234.56, currency: 'EUR' }
|
|
136
|
+
- **Type:** `number`
|
|
137
|
+
- **Default:** Depends on `domain` (2, 4, or 8).
|
|
138
|
+
- **Description:** Explicitly limits the number of decimal places allowed. If the number in the string has more decimal places than this, it might be split or parsed differently. Overrides the `domain` default.
|
|
173
139
|
|
|
174
|
-
|
|
175
|
-
parsePriceString("CHF 1'234.56");
|
|
176
|
-
// → { status: 'CONFIRMED', rawAmount: 1234.56, currency: 'CHF' }
|
|
140
|
+
### `maxSymbolDistance`
|
|
177
141
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
```
|
|
142
|
+
- **Type:** `number`
|
|
143
|
+
- **Default:** `6`
|
|
144
|
+
- **Description:** The maximum number of characters allowed between the currency symbol/code and the numeric value. Useful to avoid matching unrelated symbols far from the number.
|
|
182
145
|
|
|
183
|
-
###
|
|
184
|
-
|
|
185
|
-
```typescript
|
|
186
|
-
// Dollar sign without additional context
|
|
187
|
-
const result = parsePriceString('$99.99');
|
|
188
|
-
console.log(result);
|
|
189
|
-
// {
|
|
190
|
-
// status: 'AMBIGUOUS',
|
|
191
|
-
// rawAmount: 99.99,
|
|
192
|
-
// currency: 'USD', // Default assumption
|
|
193
|
-
// currencyHints: ['USD', 'CAD', 'AUD', 'NZD', ...] // All 26 possibilities
|
|
194
|
-
// }
|
|
195
|
-
|
|
196
|
-
// Use explicit ISO codes when currency is known
|
|
197
|
-
parsePriceString('CAD 99.99');
|
|
198
|
-
// → { status: 'CONFIRMED', rawAmount: 99.99, currency: 'CAD' }
|
|
199
|
-
|
|
200
|
-
parsePriceString('99.99 AUD');
|
|
201
|
-
// → { status: 'CONFIRMED', rawAmount: 99.99, currency: 'AUD' }
|
|
202
|
-
|
|
203
|
-
// Or use unambiguous prefixed symbols
|
|
204
|
-
parsePriceString('CA$ 99.99');
|
|
205
|
-
// → { status: 'CONFIRMED', rawAmount: 99.99, currency: 'CAD' }
|
|
206
|
-
```
|
|
146
|
+
### `ignorePercentages`
|
|
207
147
|
|
|
208
|
-
|
|
148
|
+
- **Type:** `boolean`
|
|
149
|
+
- **Default:** `true`
|
|
150
|
+
- **Description:** If `true`, ignores numeric values followed immediately by a `%` sign (e.g., "50% off").
|
|
209
151
|
|
|
210
|
-
|
|
211
|
-
// Japanese yen with kanji
|
|
212
|
-
parsePriceString('¥1,234 円');
|
|
213
|
-
// → { status: 'CONFIRMED', rawAmount: 1234, currency: 'JPY' }
|
|
152
|
+
### `tables`
|
|
214
153
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
154
|
+
- **Type:** `CurrencyTables`
|
|
155
|
+
- **Default:** `undefined` (tables are built on the fly)
|
|
156
|
+
- **Description:** Pre-computed currency tables from `buildCurrencyTables()`. Pass this to avoid rebuilding tables for every call.
|
|
218
157
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
158
|
+
## Notes
|
|
159
|
+
|
|
160
|
+
- `domain` does not map website domains like `amazon.ca` to a currency. It only selects a precision profile (`price`/`fx`/`crypto`).
|
|
161
|
+
- ISO 4217 currency list (`src/data/iso4217.json`) last downloaded: 2026-01-02.
|
|
162
|
+
- Real-world HTML-based test notes: [`REAL_WORLD_HTML_TESTS.md`](REAL_WORLD_HTML_TESTS.md)
|
|
163
|
+
- Third-party notices: [`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md)
|
|
164
|
+
|
|
165
|
+
## License
|
|
223
166
|
|
|
167
|
+
MIT. See [`LICENSE`](LICENSE).
|
package/package.json
CHANGED