utilzify 1.13.3 → 1.14.2
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 +689 -1
- package/lib/browser/bundle.iife.js +1 -1
- package/lib/browser/bundle.umd.js +1 -1
- package/lib/cjs/_virtual/customParseFormat.js +1 -0
- package/lib/cjs/_virtual/dayjs.min.js +1 -0
- package/lib/cjs/node_modules/dayjs/dayjs.min.js +1 -0
- package/lib/cjs/node_modules/dayjs/plugin/customParseFormat.js +1 -0
- package/lib/cjs/utils/_dayjs.d.ts +3 -0
- package/lib/cjs/utils/_dayjs.d.ts.map +1 -0
- package/lib/cjs/utils/_dayjs.js +1 -0
- package/lib/cjs/utils/axios-handlers.js +1 -1
- package/lib/cjs/utils/column-parser.js +1 -1
- package/lib/cjs/utils/convert-base64-to-file.js +1 -1
- package/lib/cjs/utils/dom.js +1 -1
- package/lib/cjs/utils/excel.js +1 -1
- package/lib/cjs/utils/mappers.d.ts.map +1 -1
- package/lib/cjs/utils/mappers.js +1 -1
- package/lib/cjs/utils/objecters.d.ts.map +1 -1
- package/lib/cjs/utils/objecters.js +1 -1
- package/lib/cjs/utils/save-file.js +1 -1
- package/lib/cjs/utils/tools.js +1 -1
- package/lib/esm/_virtual/customParseFormat.js +1 -0
- package/lib/esm/_virtual/dayjs.min.js +1 -0
- package/lib/esm/node_modules/dayjs/dayjs.min.js +1 -0
- package/lib/esm/node_modules/dayjs/plugin/customParseFormat.js +1 -0
- package/lib/esm/utils/_dayjs.d.ts +3 -0
- package/lib/esm/utils/_dayjs.d.ts.map +1 -0
- package/lib/esm/utils/_dayjs.js +1 -0
- package/lib/esm/utils/axios-handlers.js +1 -1
- package/lib/esm/utils/column-parser.js +1 -1
- package/lib/esm/utils/convert-base64-to-file.js +1 -1
- package/lib/esm/utils/dom.js +1 -1
- package/lib/esm/utils/excel.js +1 -1
- package/lib/esm/utils/mappers.d.ts.map +1 -1
- package/lib/esm/utils/mappers.js +1 -1
- package/lib/esm/utils/objecters.d.ts.map +1 -1
- package/lib/esm/utils/objecters.js +1 -1
- package/lib/esm/utils/save-file.js +1 -1
- package/lib/esm/utils/tools.js +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1 +1,689 @@
|
|
|
1
|
-
#
|
|
1
|
+
# utilzify
|
|
2
|
+
|
|
3
|
+
> JavaScript va TypeScript loyihalari uchun yengil, modulli yordamchi funksiyalar kutubxonasi.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/utilzify)
|
|
6
|
+
[](https://www.npmjs.com/package/utilzify)
|
|
7
|
+
[](https://github.com/svkhrobbeck/utilzify/blob/main/LICENSE)
|
|
8
|
+
|
|
9
|
+
`utilzify` — frontend va backend ishlanmalarda eng ko'p uchraydigan vazifalarni soddalashtirish uchun mo'ljallangan utilitlar to'plami. Sana formatlash, raqam parselash, Excel/CSV bilan ishlash, Google Sheets'dan ma'lumot o'qish, HTTP header generatsiyasi, xato xabarlarini chiqarib olish va boshqa ko'plab vazifalar uchun tayyor yechimlar.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Mundarija
|
|
14
|
+
|
|
15
|
+
- [O'rnatish](#ornatish)
|
|
16
|
+
- [Xususiyatlar](#xususiyatlar)
|
|
17
|
+
- [Tezkor boshlash](#tezkor-boshlash)
|
|
18
|
+
- [API hujjati](#api-hujjati)
|
|
19
|
+
- [Sana bilan ishlash](#sana-bilan-ishlash)
|
|
20
|
+
- [Raqam va matnni formatlash](#raqam-va-matnni-formatlash)
|
|
21
|
+
- [Asinxron yordamchilar](#asinxron-yordamchilar)
|
|
22
|
+
- [Vaqt birliklari](#vaqt-birliklari)
|
|
23
|
+
- [Object va jadval bilan ishlash](#object-va-jadval-bilan-ishlash)
|
|
24
|
+
- [Excel bilan ishlash](#excel-bilan-ishlash)
|
|
25
|
+
- [Column / Row parser](#column--row-parser)
|
|
26
|
+
- [Google Sheets mapper](#google-sheets-mapper)
|
|
27
|
+
- [Axios handler'lari](#axios-handlerlari)
|
|
28
|
+
- [HTTP header generator](#http-header-generator)
|
|
29
|
+
- [Xato xabarlarini ajratish](#xato-xabarlarini-ajratish)
|
|
30
|
+
- [DOM va fayl saqlash](#dom-va-fayl-saqlash)
|
|
31
|
+
- [Atrof-muhit (environment)](#atrof-muhit-environment)
|
|
32
|
+
- [Boshqa utilitlar](#boshqa-utilitlar)
|
|
33
|
+
- [TypeScript qo'llab-quvvatlash](#typescript-qollab-quvvatlash)
|
|
34
|
+
- [Litsenziya](#litsenziya)
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## O'rnatish
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# yarn
|
|
42
|
+
yarn add utilzify
|
|
43
|
+
|
|
44
|
+
# npm
|
|
45
|
+
npm install utilzify
|
|
46
|
+
|
|
47
|
+
# pnpm
|
|
48
|
+
pnpm add utilzify
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Talablar:** Node.js >= 20. Kutubxona ESM, CJS va UMD formatlarida tarqatiladi.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Xususiyatlar
|
|
56
|
+
|
|
57
|
+
- **Yengil bundle** — sanalar uchun `dayjs` (~2kb gzip)
|
|
58
|
+
- **Tree-shakeable** — `sideEffects: false`, faqat ishlatilgan funksiyalar build'ga tushadi
|
|
59
|
+
- **TypeScript** — barcha funksiyalar uchun to'liq typelar va nested key inferensiyasi
|
|
60
|
+
- **Universal** — Node.js va brauzer muhitlarida ishlaydi (muhitga bog'liq funksiyalar avtomatik tekshiriladi)
|
|
61
|
+
- **Excel/CSV** — `exceljs` asosida o'qish/yozish
|
|
62
|
+
- **Robust xato ajratish** — har qanday API javobidan xato matnini topib oladi
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Tezkor boshlash
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import { getFormattedDate, formatCurrencyPrice, debounce, Excel } from "utilzify";
|
|
70
|
+
|
|
71
|
+
// Sana formatlash
|
|
72
|
+
getFormattedDate(new Date(), "DD/MM/YYYY"); // "15/05/2026"
|
|
73
|
+
|
|
74
|
+
// Pulni formatlash
|
|
75
|
+
formatCurrencyPrice(1250000, "UZS"); // "UZS 1,250,000.00"
|
|
76
|
+
|
|
77
|
+
// Debounce
|
|
78
|
+
const onSearch = debounce((q: string) => fetch(`/api?q=${q}`), 300);
|
|
79
|
+
|
|
80
|
+
// Excel o'qish (frontend)
|
|
81
|
+
const excel = new Excel();
|
|
82
|
+
const rows = await excel.readFromArrayBuffer(blob, 1);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## API hujjati
|
|
88
|
+
|
|
89
|
+
### Sana bilan ishlash
|
|
90
|
+
|
|
91
|
+
Ichkarida `dayjs` ishlatiladi, `customParseFormat` plugini avtomatik kengaytirilgan — `moment` formatidagi tokenlar (`DD/MM/YYYY`, `HH:mm:ss` va h.k.) ishlayveradi.
|
|
92
|
+
|
|
93
|
+
#### `getFormattedDate(date?, format?)`
|
|
94
|
+
|
|
95
|
+
`Date`, `number` yoki `string` qiymatni formatlangan satrga aylantiradi.
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
getFormattedDate(); // "15/05/2026 14:30:00" (default: DD/MM/YYYY HH:mm:ss)
|
|
99
|
+
getFormattedDate(Date.now(), "YYYY-MM-DD"); // "2026-05-15"
|
|
100
|
+
getFormattedDate("2026-05-15T10:00:00Z", "HH:mm"); // "15:00"
|
|
101
|
+
getFormattedDate("noto'g'ri sana"); // "" (yaroqsiz bo'lsa bo'sh satr)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
#### `getValidDate(dateStr, parseFormat)`
|
|
105
|
+
|
|
106
|
+
Formatga ko'ra satrdan `Date` obyektini parselaydi.
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
getValidDate("15/05/2026", "DD/MM/YYYY"); // Date obyekti
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### `formatDateLocaleString(date, locales?, timeZone?)`
|
|
113
|
+
|
|
114
|
+
`Intl` orqali mahalliy formatlash. Default: `en-GB` locale, `Asia/Tashkent` vaqt zonasi.
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
formatDateLocaleString(Date.now()); // "15/05/2026, 14:30:00"
|
|
118
|
+
formatDateLocaleString(Date.now(), "uz-UZ", "Asia/Tashkent"); // "15.05.2026, 14:30:00"
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
### Raqam va matnni formatlash
|
|
124
|
+
|
|
125
|
+
#### `formatCurrencyPrice(price, currency, locales?)`
|
|
126
|
+
|
|
127
|
+
Pul qiymatini valyuta bilan birga formatlaydi.
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
formatCurrencyPrice(1250000, "UZS"); // "UZS 1,250,000.00"
|
|
131
|
+
formatCurrencyPrice(99.99, "USD", "en-US"); // "$99.99"
|
|
132
|
+
formatCurrencyPrice(1500, "EUR", "de-DE"); // "1.500,00 €"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### `formatStringToFloat(str, defaultValue?)`
|
|
136
|
+
|
|
137
|
+
Har xil formatdagi raqamli matnlarni `number` ga aylantiradi. Hind (`1,23,456.78`), Yevropa (`1.234,56`) va oddiy (`1234.56`) formatlarni tushunadi.
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
formatStringToFloat("1,234.56"); // 1234.56
|
|
141
|
+
formatStringToFloat("1.234,56"); // 1234.56
|
|
142
|
+
formatStringToFloat("1,23,456.78"); // 123456.78
|
|
143
|
+
formatStringToFloat("noto'g'ri", 0); // 0
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
#### `parseSeparatedNumber(str)`
|
|
147
|
+
|
|
148
|
+
Verguldan tozalab `Number` ga aylantiradi.
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
parseSeparatedNumber("1,234,567"); // 1234567
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
#### `isIndianFormat(str)` / `parseIndianFormat(str)` / `parseEuropeanFormat(str)`
|
|
155
|
+
|
|
156
|
+
Spetsifik format aniqlovchilari va parserlar (`formatStringToFloat` ichida ishlatiladi).
|
|
157
|
+
|
|
158
|
+
#### `stripHtmlTags(html)`
|
|
159
|
+
|
|
160
|
+
HTML teglarni olib tashlaydi.
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
stripHtmlTags("<p>Salom <b>dunyo</b></p>"); // "Salom dunyo"
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
### Asinxron yordamchilar
|
|
169
|
+
|
|
170
|
+
#### `delay(ms)`
|
|
171
|
+
|
|
172
|
+
Berilgan vaqtga kutadi.
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
await delay(1000); // 1 soniya
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
#### `delayRun(ms, callback?)`
|
|
179
|
+
|
|
180
|
+
Berilgan vaqtdan keyin callback'ni ishga tushiradi va natijasini qaytaradi.
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
const result = await delayRun(500, async () => fetchData());
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
#### `debounce(func, delay?, immediate?)`
|
|
187
|
+
|
|
188
|
+
Funksiyani debounce qiladi (default: 300ms).
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
const onChange = debounce((value: string) => {
|
|
192
|
+
console.log("Foydalanuvchi yozishni to'xtatdi:", value);
|
|
193
|
+
}, 500);
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
#### `measureExecutionTime(fn, label?, format)`
|
|
197
|
+
|
|
198
|
+
Funksiya bajarilish vaqtini o'lchaydi va konsolga chiqaradi.
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
const data = await measureExecutionTime(
|
|
202
|
+
() => fetchLargeDataset(),
|
|
203
|
+
"fetchLargeDataset",
|
|
204
|
+
"s",
|
|
205
|
+
);
|
|
206
|
+
// [fetchLargeDataset] Boshladi: 15/05/2026 14:30:00
|
|
207
|
+
// [fetchLargeDataset] Tugadi: 15/05/2026 14:30:03
|
|
208
|
+
// [fetchLargeDataset] Davomiyligi: 3.20 soniya
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
### Vaqt birliklari
|
|
214
|
+
|
|
215
|
+
#### `toMilliseconds(time)`
|
|
216
|
+
|
|
217
|
+
Turli vaqt birliklarini millisekundga aylantiradi.
|
|
218
|
+
|
|
219
|
+
```ts
|
|
220
|
+
toMilliseconds({ minutes: 5, seconds: 30 }); // 330000
|
|
221
|
+
toMilliseconds({ hours: 1, days: 2 }); // 176400000
|
|
222
|
+
toMilliseconds({ years: 1 }); // 31557600000
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Qabul qiluvchi kalitlar: `milliseconds`, `seconds`, `minutes`, `hours`, `days`, `weeks`, `months` (30.44 kun), `years` (365.25 kun).
|
|
226
|
+
|
|
227
|
+
#### `formatDuration(ms, format)`
|
|
228
|
+
|
|
229
|
+
Davomiylikni odamga tushunarli ko'rinishga keltiradi.
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
formatDuration(125000, "human"); // "2 daqiqa 5 soniya"
|
|
233
|
+
formatDuration(125000, "s"); // "125.00 soniya"
|
|
234
|
+
formatDuration(125000, "min"); // "2.08 daqiqa"
|
|
235
|
+
formatDuration(125000, "ms"); // "125000 millisoniya"
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
### Object va jadval bilan ishlash
|
|
241
|
+
|
|
242
|
+
#### `getNestedValue(obj, key)`
|
|
243
|
+
|
|
244
|
+
Nested kalit bo'yicha qiymatni xavfsiz olish.
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
getNestedValue({ a: { b: { c: 42 } } }, "a.b.c"); // 42
|
|
248
|
+
getNestedValue({ a: null }, "a.b.c"); // null
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
TypeScript bilan ishlatilganda `NestedKeyOf<T>` orqali kalit avtomatik to'liq tip xavfsiz bo'ladi.
|
|
252
|
+
|
|
253
|
+
#### `buildTableRows(data, columns, withHeader?, extraMapper?)`
|
|
254
|
+
|
|
255
|
+
Obyekt massivini jadval (`any[][]`) ko'rinishiga aylantiradi. Excel/CSV eksporti va react-table kabi kutubxonalar uchun ideal.
|
|
256
|
+
|
|
257
|
+
```ts
|
|
258
|
+
type User = { id: number; name: string; email: string; createdAt: string };
|
|
259
|
+
|
|
260
|
+
const users: User[] = [...];
|
|
261
|
+
|
|
262
|
+
const rows = buildTableRows(users, {
|
|
263
|
+
id: "ID", // sodda header
|
|
264
|
+
name: { header: "Ismi" }, // obyekt formati
|
|
265
|
+
email: [
|
|
266
|
+
"Email manzili",
|
|
267
|
+
(val, row) => `<${val}>`, // tuple: [header, mapper]
|
|
268
|
+
],
|
|
269
|
+
createdAt: (val) => getFormattedDate(val), // faqat mapper
|
|
270
|
+
}, true);
|
|
271
|
+
|
|
272
|
+
// Natija:
|
|
273
|
+
// [
|
|
274
|
+
// ["ID", "Ismi", "Email manzili", "createdAt"],
|
|
275
|
+
// [1, "Ali", "<ali@example.com>", "15/05/2026 14:30:00"],
|
|
276
|
+
// ...
|
|
277
|
+
// ]
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**Column tip variantlari:**
|
|
281
|
+
|
|
282
|
+
| Format | Misol | Tushuntirish |
|
|
283
|
+
|---|---|---|
|
|
284
|
+
| `string` | `"Header nomi"` | Faqat header matni |
|
|
285
|
+
| `MapperFn` | `(val, row, key) => ...` | Faqat mapper, header avtomatik |
|
|
286
|
+
| `[string, MapperFn]` | `["Header", mapper]` | Header va mapper |
|
|
287
|
+
| `Object` | `{ header, mapper, emptyVal, staticVal }` | To'liq nazorat |
|
|
288
|
+
| `false` | — | Bu ustun skip qilinadi |
|
|
289
|
+
|
|
290
|
+
**Performance:** Funksiya 25k+ qatorlik massivlar bilan ham tez ishlaydi — column metadata bir marta compile qilinib hot loopda qayta ishlatiladi.
|
|
291
|
+
|
|
292
|
+
#### `objectToArray(data, keys, headers?, emptyVal?)`
|
|
293
|
+
|
|
294
|
+
Tezkor variant: faqat ko'rsatilgan kalitlardan jadval tuzadi (mapper yo'q).
|
|
295
|
+
|
|
296
|
+
```ts
|
|
297
|
+
objectToArray(users, ["id", "name", "email"], ["ID", "Ism", "Email"]);
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
#### `objectItemToArray(row, keys, emptyVal?)`
|
|
301
|
+
|
|
302
|
+
Bitta obyektni massivga aylantiradi.
|
|
303
|
+
|
|
304
|
+
#### `getPrimitiveKeys(input)`
|
|
305
|
+
|
|
306
|
+
Obyekt yoki massiv ichidagi barcha primitiv kalitlarni `dot.notation` ko'rinishida qaytaradi (dinamik tablica generatsiyasi uchun foydali).
|
|
307
|
+
|
|
308
|
+
```ts
|
|
309
|
+
getPrimitiveKeys([{ id: 1, user: { name: "Ali" } }]);
|
|
310
|
+
// ["id", "user.name"]
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
### Excel bilan ishlash
|
|
316
|
+
|
|
317
|
+
`Excel` sinfi `exceljs` asosida ishlaydi va faqat **frontend muhitda** chaqiriladi (konstruktor o'zi muhitni tekshiradi).
|
|
318
|
+
|
|
319
|
+
```ts
|
|
320
|
+
import { Excel } from "utilzify";
|
|
321
|
+
|
|
322
|
+
const excel = new Excel();
|
|
323
|
+
|
|
324
|
+
// 1) Blob/ArrayBuffer dan o'qish
|
|
325
|
+
const rows = await excel.readFromArrayBuffer(blob, 1);
|
|
326
|
+
|
|
327
|
+
// 2) Disk yo'lidan o'qish (Node muhitida)
|
|
328
|
+
const rows2 = await excel.read("./data.xlsx", "Sheet1");
|
|
329
|
+
|
|
330
|
+
// 3) Obyekt massividan yozish va yuklatish
|
|
331
|
+
await excel.write(
|
|
332
|
+
users,
|
|
333
|
+
["ID", "Ismi", "Email"],
|
|
334
|
+
["id", "name", "email"],
|
|
335
|
+
"users",
|
|
336
|
+
"Sheet1",
|
|
337
|
+
);
|
|
338
|
+
// → users_2026-05-15.xlsx yuklab olinadi
|
|
339
|
+
|
|
340
|
+
// 4) Massivlardan yozish
|
|
341
|
+
await excel.writeFromArray(
|
|
342
|
+
[["1", "Ali", "ali@example.com"]],
|
|
343
|
+
["ID", "Ismi", "Email"],
|
|
344
|
+
"users",
|
|
345
|
+
);
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
### Column / Row parser
|
|
351
|
+
|
|
352
|
+
Excel/Google Sheets dan kelgan qator massivlarini tip-xavfsiz ravishda parselash uchun.
|
|
353
|
+
|
|
354
|
+
#### Yordamchi funksiyalar
|
|
355
|
+
|
|
356
|
+
```ts
|
|
357
|
+
getColumnIndex("A"); // 0
|
|
358
|
+
getColumnIndex("Z"); // 25
|
|
359
|
+
getColumnIndex("AA"); // 26
|
|
360
|
+
|
|
361
|
+
getColumnName(0); // "A"
|
|
362
|
+
getColumnName(26); // "AA"
|
|
363
|
+
|
|
364
|
+
getValueByName(row, "C", null); // C ustun qiymati
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
#### `ColumnParser`
|
|
368
|
+
|
|
369
|
+
Default qiymat va tip-xavfsiz ishlash bilan.
|
|
370
|
+
|
|
371
|
+
```ts
|
|
372
|
+
const row = ["Ali", "25", "TRUE", "1,250,000", "15/05/2026"];
|
|
373
|
+
|
|
374
|
+
ColumnParser.string(row, "A"); // "Ali"
|
|
375
|
+
ColumnParser.number(row, "B", 0); // 25
|
|
376
|
+
ColumnParser.boolean(row, "C", false); // true
|
|
377
|
+
ColumnParser.price(row, "D"); // 1250000
|
|
378
|
+
ColumnParser.date(row, "E", "DD/MM/YYYY"); // Date obyekti
|
|
379
|
+
ColumnParser.formattedDate(row, "E", "DD/MM/YYYY", "YYYY-MM-DD"); // "2026-05-15"
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
#### `ColumnMapper` va `IndexMapper`
|
|
383
|
+
|
|
384
|
+
Eski API — `ColumnMapper` kalit nomi bo'yicha (`"A"`, `"B"`), `IndexMapper` indeks bo'yicha (`0`, `1`) ishlaydi.
|
|
385
|
+
|
|
386
|
+
```ts
|
|
387
|
+
ColumnMapper.getStr(row, "A", "default");
|
|
388
|
+
ColumnMapper.getNum(row, "B", 0);
|
|
389
|
+
ColumnMapper.getBool(row, "C", false);
|
|
390
|
+
ColumnMapper.getPrice(row, "D");
|
|
391
|
+
ColumnMapper.getDate(row, "E", "DD/MM/YYYY");
|
|
392
|
+
ColumnMapper.getDateFormatted(row, "E", "YYYY-MM-DD", "DD/MM/YYYY");
|
|
393
|
+
|
|
394
|
+
IndexMapper.getStr(row, 0);
|
|
395
|
+
IndexMapper.getNum(row, 1);
|
|
396
|
+
// ...
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
#### `resolveHeaderColumn` va `resolveHeaderColumnMap`
|
|
400
|
+
|
|
401
|
+
Sheet'ning birinchi qatoridagi headerlar bo'yicha ustun harflarini topish.
|
|
402
|
+
|
|
403
|
+
```ts
|
|
404
|
+
const headers = ["ID", "Ismi", "Email", "Sana"];
|
|
405
|
+
|
|
406
|
+
resolveHeaderColumn(headers, "Email"); // "C"
|
|
407
|
+
resolveHeaderColumn(headers, "Telefon", "X"); // "X" (topilmasa)
|
|
408
|
+
|
|
409
|
+
resolveHeaderColumnMap(headers, {
|
|
410
|
+
id: "ID",
|
|
411
|
+
name: "Ismi",
|
|
412
|
+
email: ["Email", "C"], // [header, default]
|
|
413
|
+
});
|
|
414
|
+
// → { id: "A", name: "B", email: "C" }
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
### Google Sheets mapper
|
|
420
|
+
|
|
421
|
+
Tipik Google Sheets ma'lumotlarini tip-xavfsiz ravishda obyektlarga aylantirish uchun yuqori darajali API.
|
|
422
|
+
|
|
423
|
+
#### `createColMapper` — ustun harfi bo'yicha
|
|
424
|
+
|
|
425
|
+
```ts
|
|
426
|
+
import { createColMapper, col } from "utilzify";
|
|
427
|
+
|
|
428
|
+
const mapRow = createColMapper({
|
|
429
|
+
id: col.num("A"),
|
|
430
|
+
name: col.str("B", ""),
|
|
431
|
+
isActive: col.bool("C", false),
|
|
432
|
+
price: col.price("D"),
|
|
433
|
+
createdAt: col.date("E", "DD/MM/YYYY"),
|
|
434
|
+
formattedDate: col.datefmt("E", "DD/MM/YYYY", "YYYY-MM-DD"),
|
|
435
|
+
fullName: col.fn((row) => `${row[1]} ${row[2]}`), // custom logika
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
const result = mapRow(["1", "Ali", "TRUE", "1,250,000", "15/05/2026"]);
|
|
439
|
+
// { id: 1, name: "Ali", isActive: true, price: 1250000, ... }
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
#### `createHdrMapper` — header nomi bo'yicha
|
|
443
|
+
|
|
444
|
+
Sheet ustunlari joyi o'zgarib turishi mumkin bo'lgan holatlar uchun.
|
|
445
|
+
|
|
446
|
+
```ts
|
|
447
|
+
import { createHdrMapper, hdr } from "utilzify";
|
|
448
|
+
|
|
449
|
+
const buildMapper = createHdrMapper({
|
|
450
|
+
id: hdr.num("ID"),
|
|
451
|
+
name: hdr.str("Ismi"),
|
|
452
|
+
email: hdr.str(["Email", "C"]), // default ustun "C"
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
const rows = await excel.read("./data.xlsx");
|
|
456
|
+
const [headers, ...dataRows] = rows;
|
|
457
|
+
|
|
458
|
+
const mapRow = buildMapper(headers);
|
|
459
|
+
const users = dataRows.map(mapRow);
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
Builderlar: `col.str()`, `col.num()`, `col.bool()`, `col.price()`, `col.date()`, `col.datefmt()`, `col.fn()`. Shu kabi `hdr.*`.
|
|
463
|
+
|
|
464
|
+
---
|
|
465
|
+
|
|
466
|
+
### Axios handler'lari
|
|
467
|
+
|
|
468
|
+
`axios` interceptor'lari uchun tayyor handler'lar.
|
|
469
|
+
|
|
470
|
+
```ts
|
|
471
|
+
import axios from "axios";
|
|
472
|
+
import { axiosSuccessHandler, axiosErrorHandler } from "utilzify";
|
|
473
|
+
|
|
474
|
+
axios.interceptors.response.use(
|
|
475
|
+
axiosSuccessHandler((data) => console.log("OK:", data)),
|
|
476
|
+
axiosErrorHandler((err, message) => console.error("XATO:", message)),
|
|
477
|
+
);
|
|
478
|
+
|
|
479
|
+
// Endi har qanday so'rov natijasi:
|
|
480
|
+
// { ...response, type: "SUCCESS" }
|
|
481
|
+
// yoki rejected: { error, data, status, statusText, type: "ERROR" }
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
`axiosErrorHandler` ning ikkinchi parametri (`reject`) `false` qilinsa, xato o'rniga resolved promise qaytariladi.
|
|
485
|
+
|
|
486
|
+
---
|
|
487
|
+
|
|
488
|
+
### HTTP header generator
|
|
489
|
+
|
|
490
|
+
Brauzer fingerprintingidan qochish yoki test qilish uchun real ko'rinishdagi headerlar.
|
|
491
|
+
|
|
492
|
+
```ts
|
|
493
|
+
import {
|
|
494
|
+
generateUserAgents,
|
|
495
|
+
generateRandomHeaders,
|
|
496
|
+
generateAndAssignRandomHeaders,
|
|
497
|
+
clearHeaders,
|
|
498
|
+
headerRandomizer,
|
|
499
|
+
randIp,
|
|
500
|
+
} from "utilzify";
|
|
501
|
+
|
|
502
|
+
generateUserAgents(5);
|
|
503
|
+
// ["Mozilla/5.0 (Windows NT 10.0; en) Chrome/12.3 Blink/4.7", ...]
|
|
504
|
+
|
|
505
|
+
generateRandomHeaders();
|
|
506
|
+
// { Accept: "...", "User-Agent": "...", Referer: "...", "X-Forwarded-For": "...", ... }
|
|
507
|
+
|
|
508
|
+
randIp(); // "15.234.12.87"
|
|
509
|
+
|
|
510
|
+
// Axios config'iga to'g'ridan-to'g'ri qo'shish
|
|
511
|
+
const config = generateAndAssignRandomHeaders({ url: "/api/data" });
|
|
512
|
+
|
|
513
|
+
clearHeaders(headers, ["x-custom-header"]); // Sezgir headerlarni olib tashlaydi
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
Eslatma: Brauzer muhitida `User-Agent`, `Referer` va shu kabilar avtomatik o'tkazib yuboriladi (brauzer ularni o'zi belgilaydi).
|
|
517
|
+
|
|
518
|
+
---
|
|
519
|
+
|
|
520
|
+
### Xato xabarlarini ajratish
|
|
521
|
+
|
|
522
|
+
Har qanday API javobidan eng mos xato matnini topib chiqaradi (50+ umumiy kalit yo'llari sinab ko'riladi).
|
|
523
|
+
|
|
524
|
+
#### `extractErrorMessage(error, defaultMsg?, additionalKeys?)`
|
|
525
|
+
|
|
526
|
+
```ts
|
|
527
|
+
import { extractErrorMessage } from "utilzify";
|
|
528
|
+
|
|
529
|
+
try {
|
|
530
|
+
await api.request();
|
|
531
|
+
} catch (err) {
|
|
532
|
+
const msg = extractErrorMessage(err, "Noma'lum xato");
|
|
533
|
+
showToast(msg);
|
|
534
|
+
}
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
Quyidagi yo'llardan biri bo'yicha xato topiladi: `response.data.error`, `response.data.message`, `error.message`, `cause.message`, `errors[*].message`, va h.k. HTML teglar avtomatik tozalanadi.
|
|
538
|
+
|
|
539
|
+
#### `extractErrorMessages(error, additionalKeys?)`
|
|
540
|
+
|
|
541
|
+
Bir nechta xato xabarlarini massiv ko'rinishida qaytaradi (validatsiya xatolari uchun).
|
|
542
|
+
|
|
543
|
+
```ts
|
|
544
|
+
const messages = extractErrorMessages(validationError);
|
|
545
|
+
// ["Ism majburiy", "Email noto'g'ri formatda", ...]
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
---
|
|
549
|
+
|
|
550
|
+
### DOM va fayl saqlash
|
|
551
|
+
|
|
552
|
+
> Bu funksiyalar **faqat brauzer muhitida** ishlaydi. Node.js da chaqirilsa `Error` tashlanadi.
|
|
553
|
+
|
|
554
|
+
#### `scrollToElement(selector)`
|
|
555
|
+
|
|
556
|
+
```ts
|
|
557
|
+
scrollToElement("#section-2"); // smooth scroll
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
#### `saveFile(blob, fileName)`
|
|
561
|
+
|
|
562
|
+
Blob'ni foydalanuvchiga fayl ko'rinishida yuklatadi.
|
|
563
|
+
|
|
564
|
+
```ts
|
|
565
|
+
const blob = new Blob([data], { type: "application/pdf" });
|
|
566
|
+
saveFile(blob, "hisobot.pdf");
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
#### `convertBase64ToFile(base64, fileName, fileType)`
|
|
570
|
+
|
|
571
|
+
Base64 satrni faylga aylantirib yuklatadi.
|
|
572
|
+
|
|
573
|
+
```ts
|
|
574
|
+
convertBase64ToFile(base64String, "rasm", "PNG");
|
|
575
|
+
convertBase64ToFile(pdfBase64, "shartnoma", "PDF");
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
Qo'llab-quvvatlanadigan turlar: `PDF`, `PNG`, `JPEG`, `EXCEL`, `WORD`, `TEXT`.
|
|
579
|
+
|
|
580
|
+
---
|
|
581
|
+
|
|
582
|
+
### Atrof-muhit (environment)
|
|
583
|
+
|
|
584
|
+
```ts
|
|
585
|
+
import { isBrowser, isNode, checkEnvironment } from "utilzify";
|
|
586
|
+
|
|
587
|
+
if (isBrowser()) {
|
|
588
|
+
// brauzer kodi
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
if (isNode()) {
|
|
592
|
+
// Node.js kodi
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
// Noto'g'ri muhitda chaqirilsa xato tashlaydi:
|
|
596
|
+
checkEnvironment("frontend");
|
|
597
|
+
checkEnvironment("backend");
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
---
|
|
601
|
+
|
|
602
|
+
### Boshqa utilitlar
|
|
603
|
+
|
|
604
|
+
#### `getRandomInt(min, max)`
|
|
605
|
+
|
|
606
|
+
```ts
|
|
607
|
+
getRandomInt(1, 100); // 1 va 100 oraligida tasodifiy butun son
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
#### `generateIdempotencyKey()`
|
|
611
|
+
|
|
612
|
+
UUID v4 generatsiyasi (API'larda takroriy so'rovlarni oldini olish uchun).
|
|
613
|
+
|
|
614
|
+
```ts
|
|
615
|
+
generateIdempotencyKey(); // "f47ac10b-58cc-4372-a567-0e02b2c3d479"
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
#### `convertDigitalSize(input, output, value)`
|
|
619
|
+
|
|
620
|
+
Raqamli o'lchov birliklarini aylantirish: `bit`, `byte`, `kb`, `mb`, `gb`, `tb`.
|
|
621
|
+
|
|
622
|
+
```ts
|
|
623
|
+
convertDigitalSize("mb", "gb", 1500); // 1.46
|
|
624
|
+
convertDigitalSize("byte", "kb", 2048); // 2
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
#### `calculateDiscountedPrice(originalPrice, discountPercentage)`
|
|
628
|
+
|
|
629
|
+
Chegirma narxini hisoblash.
|
|
630
|
+
|
|
631
|
+
```ts
|
|
632
|
+
calculateDiscountedPrice(100000, 15); // 85000
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
#### `formatJsonForTelegram(data)`
|
|
636
|
+
|
|
637
|
+
Telegram bot uchun JSON xabarini `<pre>` blokda formatlash (HTML parse mode).
|
|
638
|
+
|
|
639
|
+
```ts
|
|
640
|
+
formatJsonForTelegram({ status: "ok", id: 42 });
|
|
641
|
+
// "<pre>{\n \"status\": \"ok\",\n \"id\": 42\n}</pre>"
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
#### `FileType` va `fileConfigs`
|
|
645
|
+
|
|
646
|
+
Fayl turlari va ularning MIME-type/extension xaritalari.
|
|
647
|
+
|
|
648
|
+
```ts
|
|
649
|
+
import { FileType, fileConfigs } from "utilzify";
|
|
650
|
+
|
|
651
|
+
fileConfigs[FileType.PDF]; // { mimeType: "application/pdf", extension: "pdf" }
|
|
652
|
+
fileConfigs[FileType.EXCEL]; // { mimeType: "...spreadsheetml.sheet", extension: "xlsx" }
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
---
|
|
656
|
+
|
|
657
|
+
## TypeScript qo'llab-quvvatlash
|
|
658
|
+
|
|
659
|
+
Kutubxona TypeScript bilan yozilgan va barcha publik API uchun tiplar mavjud. Eng qiziq tiplar:
|
|
660
|
+
|
|
661
|
+
```ts
|
|
662
|
+
import type {
|
|
663
|
+
NestedKeyOf, // T obyektining "a.b.c" ko'rinishidagi barcha kalitlari
|
|
664
|
+
MapperFn, // buildTableRows uchun mapper signature
|
|
665
|
+
SortedArrayColumn, // buildTableRows kolumn definitsiyasi
|
|
666
|
+
ColSchema, HdrSchema, // createColMapper / createHdrMapper sxemalari
|
|
667
|
+
InferColSchema, // sxemadan natija tipini inferensiya qilish
|
|
668
|
+
TimeInput, // toMilliseconds parametri
|
|
669
|
+
FormatDurationTime, // "ms" | "s" | "min" | "human"
|
|
670
|
+
UnitType, // "bit" | "byte" | "kb" | "mb" | "gb" | "tb"
|
|
671
|
+
FileConfig,
|
|
672
|
+
EcosystemApp, // pm2 ecosystem.config tipi
|
|
673
|
+
EcosystemConfig,
|
|
674
|
+
} from "utilzify";
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
`NestedKeyOf` orqali nested kalitlar avtomatik to'liq tip-xavfsiz bo'ladi:
|
|
678
|
+
|
|
679
|
+
```ts
|
|
680
|
+
type User = { id: number; profile: { name: string; age: number } };
|
|
681
|
+
|
|
682
|
+
getNestedValue<User, "profile.name">(user, "profile.name"); // string | null
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
---
|
|
686
|
+
|
|
687
|
+
## Litsenziya
|
|
688
|
+
|
|
689
|
+
ISC © [svkhrobbeck](https://github.com/svkhrobbeck)
|