@indodev/toolkit 0.1.4 → 0.2.0
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 +91 -183
- package/dist/compare-B1MKSOWV.d.cts +938 -0
- package/dist/compare-B1MKSOWV.d.ts +938 -0
- package/dist/index.cjs +908 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +896 -1
- package/dist/index.js.map +1 -1
- package/dist/text/index.cjs +915 -0
- package/dist/text/index.cjs.map +1 -0
- package/dist/text/index.d.cts +284 -0
- package/dist/text/index.d.ts +284 -0
- package/dist/text/index.js +898 -0
- package/dist/text/index.js.map +1 -0
- package/package.json +19 -2
package/README.md
CHANGED
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
<!-- # @indodev/toolkit
|
|
2
|
-
|
|
3
|
-
TypeScript utilities for Indonesian data validation and formatting.
|
|
4
|
-
|
|
5
|
-
<div align="center">
|
|
6
|
-
|
|
7
|
-
[](https://github.com/choiruladamm/indo-dev-utils/actions) [](https://npmjs.com/package/@indodev/toolkit) [](https://bundlephobia.com/package/@indodev/toolkit) [](https://typescriptlang.org/) [](https://opensource.org/licenses/MIT)
|
|
8
|
-
|
|
9
|
-
</div> -->
|
|
10
|
-
|
|
11
1
|
<div align="center">
|
|
12
2
|
|
|
13
3
|
# @indodev/toolkit
|
|
@@ -20,37 +10,38 @@ TypeScript utilities for Indonesian data validation and formatting.
|
|
|
20
10
|
|
|
21
11
|
## Why?
|
|
22
12
|
|
|
23
|
-
Building apps for Indonesia means dealing with NIK validation, phone number formatting, and
|
|
13
|
+
Building apps for Indonesia means dealing with NIK validation, phone number formatting, Rupiah display, and proper text handling. Instead of rewriting the same logic across projects, use battle-tested utilities that just work.
|
|
24
14
|
|
|
25
15
|
## Features
|
|
26
16
|
|
|
27
17
|
- **NIK validation** - Verify Indonesian National Identity Numbers with province, date, and gender checks
|
|
28
18
|
- **Phone formatting** - Support for all major operators (Telkomsel, XL, Indosat, Smartfren, Axis) and 200+ area codes
|
|
29
19
|
- **Rupiah formatting** - Display currency with proper grammar rules (1,5 juta, not 1,0 juta)
|
|
20
|
+
- **Text utilities** - Smart capitalization, slug generation, abbreviation expansion, and string comparison with Indonesian language support
|
|
30
21
|
- **Terbilang converter** - Numbers to Indonesian words (1500000 → "satu juta lima ratus ribu rupiah")
|
|
31
22
|
- **Type-safe** - Full TypeScript support with proper type inference
|
|
32
|
-
- **Well-tested** -
|
|
23
|
+
- **Well-tested** - 1060+ test cases with 95%+ coverage
|
|
33
24
|
- **Zero dependencies** - Lightweight and tree-shakeable
|
|
34
25
|
|
|
35
26
|
## Install
|
|
27
|
+
|
|
36
28
|
```bash
|
|
37
29
|
npm install @indodev/toolkit
|
|
38
30
|
```
|
|
39
31
|
|
|
40
|
-
##
|
|
32
|
+
## Quick Start
|
|
41
33
|
|
|
42
34
|
### NIK Validation & Parsing
|
|
35
|
+
|
|
43
36
|
```typescript
|
|
44
37
|
import { validateNIK, parseNIK, maskNIK } from '@indodev/toolkit/nik';
|
|
45
38
|
|
|
46
39
|
// Validate
|
|
47
40
|
validateNIK('3201234567890123'); // true
|
|
48
|
-
validateNIK('1234'); // false
|
|
49
41
|
|
|
50
42
|
// Extract info
|
|
51
43
|
const info = parseNIK('3201234567890123');
|
|
52
44
|
console.log(info.province.name); // 'Jawa Barat'
|
|
53
|
-
console.log(info.birthDate); // Date object
|
|
54
45
|
console.log(info.gender); // 'male' or 'female'
|
|
55
46
|
|
|
56
47
|
// Mask for privacy
|
|
@@ -58,241 +49,158 @@ maskNIK('3201234567890123'); // '3201****0123'
|
|
|
58
49
|
```
|
|
59
50
|
|
|
60
51
|
### Phone Numbers
|
|
52
|
+
|
|
61
53
|
```typescript
|
|
62
|
-
import {
|
|
54
|
+
import {
|
|
55
|
+
validatePhoneNumber,
|
|
56
|
+
formatPhoneNumber,
|
|
57
|
+
getOperator,
|
|
58
|
+
} from '@indodev/toolkit/phone';
|
|
63
59
|
|
|
64
|
-
// Validate
|
|
60
|
+
// Validate and format
|
|
65
61
|
validatePhoneNumber('081234567890'); // true
|
|
66
|
-
validatePhoneNumber('+6281234567890'); // true
|
|
67
|
-
|
|
68
|
-
// Format
|
|
69
62
|
formatPhoneNumber('081234567890', 'international'); // '+62 812-3456-7890'
|
|
70
|
-
formatPhoneNumber('081234567890', 'national'); // '0812-3456-7890'
|
|
71
63
|
|
|
72
64
|
// Detect operator
|
|
73
65
|
getOperator('081234567890'); // 'Telkomsel'
|
|
74
|
-
getOperator('085612345678'); // 'Indosat'
|
|
75
66
|
```
|
|
76
67
|
|
|
77
68
|
### Currency Formatting
|
|
69
|
+
|
|
78
70
|
```typescript
|
|
79
|
-
import {
|
|
71
|
+
import {
|
|
72
|
+
formatRupiah,
|
|
73
|
+
formatCompact,
|
|
74
|
+
toWords,
|
|
75
|
+
} from '@indodev/toolkit/currency';
|
|
80
76
|
|
|
81
77
|
// Standard format
|
|
82
78
|
formatRupiah(1500000); // 'Rp 1.500.000'
|
|
83
|
-
formatRupiah(1500000.50, { decimal: true }); // 'Rp 1.500.000,50'
|
|
84
79
|
|
|
85
80
|
// Compact format (follows Indonesian grammar!)
|
|
86
81
|
formatCompact(1500000); // 'Rp 1,5 juta'
|
|
87
82
|
formatCompact(1000000); // 'Rp 1 juta' (not '1,0 juta')
|
|
88
83
|
|
|
89
84
|
// Terbilang
|
|
90
|
-
toWords(1500000);
|
|
91
|
-
// 'satu juta lima ratus ribu rupiah'
|
|
92
|
-
|
|
93
|
-
toWords(1500000, { uppercase: true, withCurrency: false });
|
|
94
|
-
// 'Satu juta lima ratus ribu'
|
|
85
|
+
toWords(1500000); // 'satu juta lima ratus ribu rupiah'
|
|
95
86
|
```
|
|
96
87
|
|
|
97
|
-
###
|
|
88
|
+
### Text Utilities
|
|
89
|
+
|
|
98
90
|
```typescript
|
|
99
|
-
import {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
91
|
+
import {
|
|
92
|
+
toTitleCase,
|
|
93
|
+
slugify,
|
|
94
|
+
expandAbbreviation,
|
|
95
|
+
truncate,
|
|
96
|
+
} from '@indodev/toolkit/text';
|
|
97
|
+
|
|
98
|
+
// Smart title case (respects Indonesian particles)
|
|
99
|
+
toTitleCase('buku panduan belajar di rumah');
|
|
100
|
+
// 'Buku Panduan Belajar di Rumah'
|
|
101
|
+
|
|
102
|
+
// Indonesian-aware slugs
|
|
103
|
+
slugify('Pria & Wanita'); // 'pria-dan-wanita'
|
|
104
|
+
slugify('Hitam/Putih'); // 'hitam-atau-putih'
|
|
105
|
+
|
|
106
|
+
// Expand abbreviations
|
|
107
|
+
expandAbbreviation('Jl. Sudirman No. 45');
|
|
108
|
+
// 'Jalan Sudirman Nomor 45'
|
|
109
|
+
|
|
110
|
+
// Smart truncation
|
|
111
|
+
truncate('Ini adalah text yang sangat panjang', 20);
|
|
112
|
+
// 'Ini adalah text...'
|
|
107
113
|
```
|
|
108
114
|
|
|
109
|
-
##
|
|
115
|
+
## API Reference
|
|
110
116
|
|
|
111
|
-
###
|
|
112
|
-
```typescript
|
|
113
|
-
import { formatRupiah, formatCompact } from '@indodev/toolkit/currency';
|
|
117
|
+
### NIK Module
|
|
114
118
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
+
| Function | Description |
|
|
120
|
+
| ---------------------------- | ------------------------------------ |
|
|
121
|
+
| `validateNIK(nik)` | Check if NIK is valid |
|
|
122
|
+
| `parseNIK(nik)` | Extract province, birth date, gender |
|
|
123
|
+
| `formatNIK(nik, separator?)` | Format with separators |
|
|
124
|
+
| `maskNIK(nik, options?)` | Mask for privacy |
|
|
119
125
|
|
|
120
|
-
|
|
121
|
-
<div className="total">
|
|
122
|
-
Total: {formatRupiah(cart.total, { decimal: true })}
|
|
123
|
-
{/* "Rp 1.500.000,50" */}
|
|
124
|
-
</div>
|
|
125
|
-
```
|
|
126
|
+
### Phone Module
|
|
126
127
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if (!validateNIK(data.nik)) {
|
|
134
|
-
return 'NIK tidak valid';
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (!validatePhoneNumber(data.phone)) {
|
|
138
|
-
return 'Nomor telepon tidak valid';
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
```
|
|
128
|
+
| Function | Description |
|
|
129
|
+
| ---------------------------------- | ------------------------------------- |
|
|
130
|
+
| `validatePhoneNumber(phone)` | Validate Indonesian phone numbers |
|
|
131
|
+
| `formatPhoneNumber(phone, format)` | Format to international/national/e164 |
|
|
132
|
+
| `getOperator(phone)` | Detect operator (Telkomsel, XL, etc) |
|
|
133
|
+
| `parsePhoneNumber(phone)` | Get all phone info |
|
|
144
134
|
|
|
145
|
-
###
|
|
146
|
-
```typescript
|
|
147
|
-
import { formatRupiah, toWords } from '@indodev/toolkit/currency';
|
|
135
|
+
### Currency Module
|
|
148
136
|
|
|
149
|
-
|
|
137
|
+
| Function | Description |
|
|
138
|
+
| -------------------------------- | -------------------------------- |
|
|
139
|
+
| `formatRupiah(amount, options?)` | Standard Rupiah format |
|
|
140
|
+
| `formatCompact(amount)` | Compact format (1,5 juta) |
|
|
141
|
+
| `parseRupiah(formatted)` | Parse formatted string to number |
|
|
142
|
+
| `toWords(amount, options?)` | Convert to Indonesian words |
|
|
150
143
|
|
|
151
|
-
|
|
152
|
-
console.log(`Terbilang: ${toWords(total, { uppercase: true })}`);
|
|
144
|
+
### Text Module
|
|
153
145
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
146
|
+
| Function | Description |
|
|
147
|
+
| -------------------------------------- | ----------------------------------------------- |
|
|
148
|
+
| `toTitleCase(text, options?)` | Smart capitalization with Indonesian rules |
|
|
149
|
+
| `slugify(text, options?)` | URL-friendly slugs with Indonesian conjunctions |
|
|
150
|
+
| `expandAbbreviation(text, options?)` | Expand Indonesian abbreviations (Jl., Bpk.) |
|
|
151
|
+
| `truncate(text, maxLength, options?)` | Smart text truncation at word boundaries |
|
|
152
|
+
| `compareStrings(str1, str2, options?)` | Robust string comparison |
|
|
153
|
+
| `sanitize(text, options?)` | Clean and normalize text |
|
|
158
154
|
|
|
159
155
|
## TypeScript Support
|
|
160
156
|
|
|
161
157
|
Full type inference out of the box:
|
|
158
|
+
|
|
162
159
|
```typescript
|
|
163
160
|
import type { NIKInfo, PhoneInfo, RupiahOptions } from '@indodev/toolkit';
|
|
164
161
|
|
|
165
162
|
const nikInfo: NIKInfo = parseNIK('3201234567890123');
|
|
166
|
-
//
|
|
167
|
-
// nikInfo.birthDate ✓ Date type
|
|
168
|
-
// nikInfo.gender ✓ 'male' | 'female' | null
|
|
169
|
-
|
|
170
|
-
const options: RupiahOptions = {
|
|
171
|
-
symbol: true,
|
|
172
|
-
decimal: true,
|
|
173
|
-
precision: 2,
|
|
174
|
-
separator: '.',
|
|
175
|
-
decimalSeparator: ',',
|
|
176
|
-
};
|
|
163
|
+
// Auto-complete for province, birthDate, gender ✓
|
|
177
164
|
```
|
|
178
165
|
|
|
179
166
|
## Tree-Shaking
|
|
180
167
|
|
|
181
168
|
Import only what you need - unused code gets removed:
|
|
169
|
+
|
|
182
170
|
```typescript
|
|
183
171
|
// ✅ Recommended: Import from submodules
|
|
184
172
|
import { formatRupiah } from '@indodev/toolkit/currency';
|
|
185
173
|
import { validateNIK } from '@indodev/toolkit/nik';
|
|
174
|
+
import { slugify } from '@indodev/toolkit/text';
|
|
186
175
|
|
|
187
176
|
// ⚠️ Works but imports everything
|
|
188
|
-
import { formatRupiah, validateNIK } from '@indodev/toolkit';
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
## Framework Examples
|
|
192
|
-
|
|
193
|
-
Works with any framework:
|
|
194
|
-
```typescript
|
|
195
|
-
// React
|
|
196
|
-
import { formatRupiah } from '@indodev/toolkit/currency';
|
|
197
|
-
|
|
198
|
-
function ProductCard({ price }) {
|
|
199
|
-
return <div>{formatRupiah(price)}</div>;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// Vue
|
|
203
|
-
import { formatPhoneNumber } from '@indodev/toolkit/phone';
|
|
204
|
-
|
|
205
|
-
export default {
|
|
206
|
-
computed: {
|
|
207
|
-
formattedPhone() {
|
|
208
|
-
return formatPhoneNumber(this.phone, 'international');
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// Svelte
|
|
214
|
-
<script>
|
|
215
|
-
import { validateNIK } from '@indodev/toolkit/nik';
|
|
216
|
-
|
|
217
|
-
$: isValid = validateNIK(nik);
|
|
218
|
-
</script>
|
|
177
|
+
import { formatRupiah, validateNIK, slugify } from '@indodev/toolkit';
|
|
219
178
|
```
|
|
220
179
|
|
|
221
|
-
## API Reference
|
|
222
|
-
|
|
223
|
-
### NIK Module
|
|
224
|
-
|
|
225
|
-
| Function | Description |
|
|
226
|
-
|----------|-------------|
|
|
227
|
-
| `validateNIK(nik)` | Check if NIK is valid |
|
|
228
|
-
| `parseNIK(nik)` | Extract province, birth date, gender |
|
|
229
|
-
| `formatNIK(nik, separator?)` | Format with separators |
|
|
230
|
-
| `maskNIK(nik, options?)` | Mask for privacy |
|
|
231
|
-
|
|
232
|
-
### Phone Module
|
|
233
|
-
|
|
234
|
-
| Function | Description |
|
|
235
|
-
|----------|-------------|
|
|
236
|
-
| `validatePhoneNumber(phone)` | Validate Indonesian phone numbers |
|
|
237
|
-
| `formatPhoneNumber(phone, format)` | Format to international/national/e164 |
|
|
238
|
-
| `getOperator(phone)` | Detect operator (Telkomsel, XL, etc) |
|
|
239
|
-
| `parsePhoneNumber(phone)` | Get all phone info |
|
|
240
|
-
|
|
241
|
-
### Currency Module
|
|
242
|
-
|
|
243
|
-
| Function | Description |
|
|
244
|
-
|----------|-------------|
|
|
245
|
-
| `formatRupiah(amount, options?)` | Standard Rupiah format |
|
|
246
|
-
| `formatCompact(amount)` | Compact format (1,5 juta) |
|
|
247
|
-
| `parseRupiah(formatted)` | Parse formatted string to number |
|
|
248
|
-
| `toWords(amount, options?)` | Convert to Indonesian words |
|
|
249
|
-
| `roundToClean(amount, unit?)` | Round to clean amounts |
|
|
250
|
-
|
|
251
180
|
## Bundle Size
|
|
252
181
|
|
|
253
|
-
| Module
|
|
254
|
-
|
|
255
|
-
| NIK
|
|
256
|
-
| Phone
|
|
257
|
-
| Currency
|
|
258
|
-
|
|
|
259
|
-
|
|
260
|
-
Import only what you need to keep your bundle small.
|
|
182
|
+
| Module | Size (minified + gzipped) |
|
|
183
|
+
| --------- | ------------------------- |
|
|
184
|
+
| NIK | ~5 KB |
|
|
185
|
+
| Phone | ~12 KB |
|
|
186
|
+
| Currency | ~6 KB |
|
|
187
|
+
| Text | ~8 KB |
|
|
188
|
+
| **Total** | **~31 KB** |
|
|
261
189
|
|
|
262
190
|
## Requirements
|
|
263
191
|
|
|
264
192
|
- Node.js >= 18
|
|
265
193
|
- TypeScript >= 5.0 (optional)
|
|
266
194
|
|
|
267
|
-
##
|
|
268
|
-
|
|
269
|
-
Found a bug? Want to add more Indonesian utilities?
|
|
270
|
-
|
|
271
|
-
1. Fork the repo
|
|
272
|
-
2. Create a branch: `git checkout -b feat/my-feature`
|
|
273
|
-
3. Make changes and add tests
|
|
274
|
-
4. Submit a PR
|
|
195
|
+
## Documentation
|
|
275
196
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
- [x] NIK validation & parsing
|
|
279
|
-
- [x] Phone number utilities
|
|
280
|
-
- [x] Currency formatting & terbilang
|
|
281
|
-
- [ ] NPWP validation
|
|
282
|
-
- [ ] Bank account validation
|
|
283
|
-
- [ ] Indonesian address parsing
|
|
284
|
-
- [ ] Date & holiday utilities
|
|
285
|
-
- [ ] Zod schema exports
|
|
197
|
+
- 📖 [Full Documentation](https://toolkit.adamm.cloud/docs)
|
|
198
|
+
- 🐛 [Report Issues](https://github.com/choiruladamm/indo-dev-utils/issues)
|
|
286
199
|
|
|
287
200
|
## License
|
|
288
201
|
|
|
289
202
|
MIT © [choiruladamm](https://github.com/choiruladamm)
|
|
290
203
|
|
|
291
|
-
## Support
|
|
292
|
-
|
|
293
|
-
- 📖 [Documentation](#) (coming soon)
|
|
294
|
-
- 🐛 [Report Issues](https://github.com/yourusername/indo-dev-utils/issues)
|
|
295
|
-
|
|
296
204
|
---
|
|
297
205
|
|
|
298
|
-
Made with ❤️ for Indonesian developers. Stop copy-pasting, start shipping.
|
|
206
|
+
Made with ❤️ for Indonesian developers. Stop copy-pasting, start shipping.
|