@libs-ui/utils 0.2.355-9 → 0.2.356-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.
Files changed (52) hide show
  1. package/README.md +633 -2
  2. package/base64.d.ts +25 -0
  3. package/cache.d.ts +73 -0
  4. package/collection.d.ts +12 -0
  5. package/color.d.ts +37 -0
  6. package/communicate-micro.d.ts +34 -1
  7. package/crypto-3rd.d.ts +12 -0
  8. package/crypto.d.ts +17 -0
  9. package/dangerous-object.d.ts +8 -1
  10. package/data.d.ts +5 -3
  11. package/date.d.ts +12 -0
  12. package/dom.d.ts +56 -0
  13. package/download.d.ts +21 -0
  14. package/esm2022/base64.mjs +27 -2
  15. package/esm2022/cache.mjs +74 -1
  16. package/esm2022/collection.mjs +13 -1
  17. package/esm2022/color.mjs +38 -1
  18. package/esm2022/communicate-micro.mjs +37 -5
  19. package/esm2022/crypto-3rd.mjs +13 -1
  20. package/esm2022/crypto.mjs +18 -1
  21. package/esm2022/dangerous-object.mjs +11 -2
  22. package/esm2022/data.mjs +6 -4
  23. package/esm2022/date.mjs +13 -1
  24. package/esm2022/dom.mjs +57 -1
  25. package/esm2022/download.mjs +22 -1
  26. package/esm2022/file.mjs +54 -1
  27. package/esm2022/format-number.mjs +31 -3
  28. package/esm2022/format-text.mjs +73 -2
  29. package/esm2022/function-check-embed-frame.mjs +28 -1
  30. package/esm2022/pattern.mjs +83 -3
  31. package/esm2022/trace.mjs +8 -1
  32. package/esm2022/two-way-signal-object.mjs +14 -1
  33. package/esm2022/uri.mjs +22 -3
  34. package/esm2022/url-search-params.mjs +68 -1
  35. package/esm2022/url.mjs +10 -1
  36. package/esm2022/uuid.mjs +7 -1
  37. package/esm2022/xss-filter.mjs +14 -1
  38. package/fesm2022/libs-ui-utils.mjs +723 -21
  39. package/fesm2022/libs-ui-utils.mjs.map +1 -1
  40. package/file.d.ts +53 -0
  41. package/format-number.d.ts +29 -1
  42. package/format-text.d.ts +71 -0
  43. package/function-check-embed-frame.d.ts +22 -0
  44. package/package.json +2 -2
  45. package/pattern.d.ts +81 -1
  46. package/trace.d.ts +7 -0
  47. package/two-way-signal-object.d.ts +13 -0
  48. package/uri.d.ts +20 -0
  49. package/url-search-params.d.ts +67 -0
  50. package/url.d.ts +9 -0
  51. package/uuid.d.ts +6 -0
  52. package/xss-filter.d.ts +13 -0
package/README.md CHANGED
@@ -1,3 +1,634 @@
1
- ## utils
1
+ # @libs-ui/utils
2
2
 
3
- This library was generated with [Nx](https://nx.dev).
3
+ > Thư viện tập trung toàn bộ **utility functions** dùng chung cho các libs-ui trong project.
4
+
5
+ **Version**: `0.2.355-10`
6
+
7
+ ## Giới thiệu
8
+
9
+ Thư viện `@libs-ui/utils` cung cấp các hàm tiện ích dùng chung (format, transform, validate...) để:
10
+
11
+ - Giảm trùng lặp code utility trong nhiều libs khác nhau
12
+ - Dễ bảo trì và mở rộng khi cần thêm utility mới
13
+ - Chuẩn hóa cách xử lý dữ liệu trong toàn bộ project
14
+
15
+ ## Cài đặt
16
+
17
+ ```bash
18
+ npm install @libs-ui/utils
19
+ # hoặc
20
+ yarn add @libs-ui/utils
21
+ ```
22
+
23
+ ## Sử dụng
24
+
25
+ ### Import
26
+
27
+ ```typescript
28
+ import {
29
+ isNil,
30
+ isEmpty,
31
+ get,
32
+ set,
33
+ cloneDeep,
34
+ keyBy,
35
+ groupBy,
36
+ range,
37
+ isEqual,
38
+ uniqBy,
39
+ base64Encode,
40
+ base64Decode,
41
+ convertBase64ToBlob,
42
+ convertFileToBase64,
43
+ UtilsCache,
44
+ addArrayToSet,
45
+ convertSetToArray,
46
+ colorContrastFromOrigin,
47
+ getColorById,
48
+ detectAndCleanNearWhiteColors,
49
+ UtilsCommunicateMicro,
50
+ encrypt3rd,
51
+ decrypt3rd,
52
+ setKeyCrypto3rd,
53
+ encrypt,
54
+ decrypt,
55
+ setKeyCrypto,
56
+ md5,
57
+ isDangerousObject,
58
+ isPrimitiveType,
59
+ isDOMObject,
60
+ isFrameworkObject,
61
+ getObjectSize,
62
+ getDayjs,
63
+ formatDate,
64
+ isDifferenceDay,
65
+ setDefaultTimeZone,
66
+ getDeviceInfo,
67
+ isTouchDevice,
68
+ getViewport,
69
+ setStylesElement,
70
+ downloadFileByUrl,
71
+ downloadFileByUrlUseXmlRequest,
72
+ } from '@libs-ui/utils';
73
+ ```
74
+
75
+ ### Ví dụ cơ bản
76
+
77
+ #### Base64 & File
78
+
79
+ ````typescript
80
+ import { base64Encode, base64Decode, convertFileToBase64 } from '@libs-ui/utils';
81
+
82
+ // Mã hóa Unicode an toàn
83
+ const encoded = base64Encode('Xin chào 👋');
84
+ const decoded = base64Decode(encoded); // 'Xin chào 👋'
85
+
86
+ // Chuyển File sang Base64 để preview
87
+ const base64 = await convertFileToBase64(file);
88
+ // data:image/png;base64,iVBORw...
89
+
90
+ #### Language
91
+ ```typescript
92
+ import { UtilsLanguageConstants } from '@libs-ui/utils';
93
+
94
+ // Dùng hằng số thay vì hardcode chuỗi
95
+ const viCode = UtilsLanguageConstants.VI; // 'vi'
96
+ const enCode = UtilsLanguageConstants.EN; // 'en'
97
+ const jaCode = UtilsLanguageConstants.JA; // 'ja'
98
+
99
+ // Tự động phát hiện ngôn ngữ trình duyệt (fallback về 'en')
100
+ const lang = UtilsLanguageConstants.defaultLang();
101
+
102
+ // Kiểm tra hỗ trợ
103
+ UtilsLanguageConstants.isSupported('vi'); // true
104
+ UtilsLanguageConstants.isSupported('xx'); // false
105
+
106
+ // Tùy chỉnh danh sách ngôn ngữ hỗ trợ (gọi một lần lúc khởi động)
107
+ UtilsLanguageConstants.setSupportedLanguages(['vi', 'en']);
108
+
109
+ #### Random & String Protection
110
+ ```typescript
111
+ import { protectString, revealString, createUniqueRandomIntGenerator } from '@libs-ui/utils';
112
+
113
+ // Obfuscate nhẹ cổng giao tiếp
114
+ const hidden = protectString('user-token-abc123');
115
+ const plain = revealString(hidden); // 'user-token-abc123'
116
+
117
+ // Round-trip luôn trả về cỗi gốc
118
+ console.log(revealString(protectString('Xin chào')) === 'Xin chào'); // true
119
+
120
+ // Tạo số ngẫu nhiên không trùng trong 10 lần gần nhất
121
+ const nextId = createUniqueRandomIntGenerator(1, 100);
122
+ console.log(nextId()); // 42
123
+ console.log(nextId()); // 17 (khác 42)
124
+
125
+ #### Cache
126
+ ```typescript
127
+ import { UtilsCache } from '@libs-ui/utils';
128
+
129
+ // LocalStorage (Đồng bộ)
130
+ UtilsCache.Set('key', { a: 1 }, 3600); // 1 giờ
131
+ const data = UtilsCache.Get('key');
132
+
133
+ // IndexedDB (Bất đồng bộ)
134
+ await UtilsCache.SetAsync('large_key', data);
135
+ const asyncData = await UtilsCache.GetAsync('large_key');
136
+
137
+ #### Collection
138
+ ```typescript
139
+ import { addArrayToSet, convertSetToArray } from '@libs-ui/utils';
140
+
141
+ const s = new Set([1]);
142
+ addArrayToSet(s, [1, 2, 3]); // Set {1, 2, 3}
143
+
144
+ const arr = convertSetToArray(s, v => `Item ${v}`); // ["Item 1", "Item 2", "Item 3"]
145
+
146
+ #### Color
147
+ ```typescript
148
+ import { colorContrastFromOrigin, getColorById } from '@libs-ui/utils';
149
+
150
+ // Tạo bảng màu
151
+ const palette = colorContrastFromOrigin('#226FF5');
152
+
153
+ // Lấy màu định danh theo ID
154
+ const userColor = getColorById('user_id_123');
155
+
156
+ /* ... */
157
+
158
+ #### Communicate Micro
159
+ ```typescript
160
+ import { UtilsCommunicateMicro } from '@libs-ui/utils';
161
+
162
+ // Khởi tạo tại AppComponent
163
+ UtilsCommunicateMicro.initEvent(window, destroyRef);
164
+
165
+ // Lắng nghe
166
+ UtilsCommunicateMicro.GetMessage('DATA_SYNC').subscribe(e => {
167
+ console.log(e.data.response);
168
+ });
169
+
170
+ // Gửi cho cha (ví dụ từ Iframe)
171
+ UtilsCommunicateMicro.PostMessageToParent({ type: 'DATA_SYNC', response: { id: 1 } });
172
+
173
+ #### Crypto 3rd
174
+ ```typescript
175
+ import { encrypt3rd, decrypt3rd, setKeyCrypto3rd } from '@libs-ui/utils';
176
+
177
+ // Setup key (một lần)
178
+ setKeyCrypto3rd('12345678901234567890123456789012');
179
+
180
+ // Mã hóa
181
+ const secret = encrypt3rd('My Secret Data');
182
+
183
+ // Giải mã
184
+ const original = decrypt3rd(secret);
185
+
186
+ #### Crypto
187
+ ```typescript
188
+ import { encrypt, decrypt, md5 } from '@libs-ui/utils';
189
+
190
+ // AES Internal
191
+ const secureData = encrypt('Secret');
192
+ const plain = decrypt(secureData);
193
+
194
+ // MD5 Hash
195
+ const hash = md5('hello');
196
+
197
+ #### Dangerous Object
198
+ ```typescript
199
+ import { isDangerousObject, isPrimitiveType } from '@libs-ui/utils';
200
+
201
+ isDangerousObject(window); // true
202
+ isDangerousObject(document.body); // true
203
+ isPrimitiveType(123); // true
204
+ isPrimitiveType({}); // false
205
+
206
+ #### Data
207
+ ```typescript
208
+ import { getObjectSize } from '@libs-ui/utils';
209
+
210
+ const size = getObjectSize({ a: 1 }); // "10 bytes"
211
+
212
+ #### Date
213
+ ```typescript
214
+ import { formatDate, getDayjs } from '@libs-ui/utils';
215
+
216
+ // Format tiếng Việt
217
+ formatDate('2024-05-20', 'dmy', 'vi'); // "20 Thg 5, 2024"
218
+
219
+ // Lấy đối tượng Day.js (local timezone)
220
+ const now = getDayjs();
221
+
222
+ #### DOM
223
+ ```typescript
224
+ import { getViewport, isTouchDevice } from '@libs-ui/utils';
225
+
226
+ const { width, height } = getViewport();
227
+ const isTouch = isTouchDevice();
228
+
229
+ #### Download
230
+ ```typescript
231
+ import { downloadFileByUrl } from '@libs-ui/utils';
232
+
233
+ // Tải file PDF từ server
234
+ await downloadFileByUrl('https://example.com/report.pdf', 'report.pdf');
235
+
236
+ // Chỉ mở tầ mới (không download)
237
+ await downloadFileByUrl('https://example.com/doc.pdf', 'preview.pdf', true);
238
+
239
+ #### Regex Patterns
240
+ ```typescript
241
+ import { patternEmail, patternMobilePhone, patternUrl } from '@libs-ui/utils';
242
+
243
+ // Kiểm tra email
244
+ const emailRe = patternEmail();
245
+ emailRe.test('user@gmail.com'); // true
246
+
247
+ // Kiểm tra số điện thoại VN
248
+ patternMobilePhone().test('0987654321'); // true
249
+
250
+ // Match pattern cụ thể
251
+ const templateRe = patternRuleFieldReplace(); // /[{]{2}[a-zA-Z_-]+[}]{2}/g
252
+ 'hello {{name}}'.match(templateRe); // ['{{name}}']
253
+ ```
254
+
255
+ #### Trace Stack
256
+ ```typescript
257
+ import { traceStack } from '@libs-ui/utils';
258
+
259
+ function a() {
260
+ b();
261
+ }
262
+
263
+ function b() {
264
+ console.log(traceStack());
265
+ // Output: ["a", "b"] (đã lọc các frame rác)
266
+ }
267
+ ```
268
+
269
+ #### Two-Way Signal Object
270
+ ```typescript
271
+ import { convertObjectToSignal, convertSignalToObject } from '@libs-ui/utils';
272
+
273
+ const obj = { name: 'Alice' };
274
+ const reactive = convertObjectToSignal<any>(obj);
275
+
276
+ reactive().name.set('Bob');
277
+
278
+ const plain = convertSignalToObject(reactive);
279
+ console.log(plain.name); // 'Bob'
280
+ ```
281
+
282
+ #### URI
283
+ ```typescript
284
+ import { encodeURI, decodeURI, endCodeUrl } from '@libs-ui/utils';
285
+
286
+ // Mã hóa/Giải mã
287
+ const encoded = encodeURI('Xin chào & Hẹn gặp lại!');
288
+ const decoded = decodeURI(encoded);
289
+
290
+ // Query String builder
291
+ const qs = endCodeUrl({ id: 1, q: 'tag' }, false); // "?id=1&q=tag"
292
+
293
+ #### URL
294
+ ```typescript
295
+ import { normalizeUrl } from '@libs-ui/utils';
296
+
297
+ // Chuẩn hóa đường dẫn URL (gộp dấu // dư thừa)
298
+ const clean = normalizeUrl('http://example.com//api///users');
299
+ // Output: "http://example.com/api/users"
300
+ ```
301
+
302
+ #### UUID
303
+ ```typescript
304
+ import { uuid } from '@libs-ui/utils';
305
+
306
+ // Tạo unique ID (MD5 hash - 32 character)
307
+ const newId = uuid();
308
+ // Output: "a1b2c3d4..."
309
+ ```
310
+
311
+ #### XSS Filter
312
+ ```typescript
313
+ import { updateFunctionXssFilter, xssFilter } from '@libs-ui/utils';
314
+ import DOMPurify from 'dompurify';
315
+
316
+ // 1. Cấu hình ban đầu (Ví dụ: trong app.component.ts)
317
+ updateFunctionXssFilter(async (data: string) => DOMPurify.sanitize(data));
318
+
319
+ // 2. Sử dụng ở mọi nơi để làm sạch HTML
320
+ const cleanHTML = await xssFilter('<script>evil()</script><b>Good</b>');
321
+ // Output: "<b>Good</b>"
322
+ ```
323
+
324
+ #### URL Search Params
325
+ ```typescript
326
+ import { UtilsUrlSearchParams } from '@libs-ui/utils';
327
+
328
+ const usp = new UtilsUrlSearchParams('?id=1&name=test');
329
+ console.log(usp.get('id')); // "1"
330
+
331
+ usp.set('page', '2');
332
+ console.log(usp.toString()); // "id=1&name=test&page=2"
333
+ ```
334
+ ```
335
+ ```
336
+ ```
337
+ ```
338
+ ```
339
+ ```
340
+ ```
341
+ ```
342
+ ```
343
+ ````
344
+
345
+ ````
346
+
347
+ #### Kiểm tra giá trị
348
+
349
+ ```typescript
350
+ import { isNil, isEmpty, isTruthy, isFalsy } from '@libs-ui/utils';
351
+
352
+ // Kiểm tra null/undefined
353
+ isNil(null); // true
354
+ isNil(undefined); // true
355
+ isNil(0); // false
356
+
357
+ // Kiểm tra rỗng
358
+ isEmpty(null); // true
359
+ isEmpty(''); // true
360
+ isEmpty({}); // true
361
+ isEmpty([]); // true
362
+ isEmpty({ a: 1 }); // false
363
+ ```
364
+
365
+ #### Thao tác Object
366
+
367
+ ```typescript
368
+ import { get, set, cloneDeep } from '@libs-ui/utils';
369
+
370
+ const user = {
371
+ profile: {
372
+ name: 'John',
373
+ address: { city: 'Hanoi' },
374
+ },
375
+ };
376
+
377
+ // Lấy giá trị theo path
378
+ get(user, 'profile.name'); // 'John'
379
+ get(user, 'profile.address.city'); // 'Hanoi'
380
+ get(user, 'profile.email', 'N/A'); // 'N/A' (default value)
381
+
382
+ // Thiết lập giá trị theo path
383
+ set(user, 'profile.name', 'Jane');
384
+ set(user, 'profile.age', 25);
385
+
386
+ // Clone sâu
387
+ const cloned = cloneDeep(user);
388
+ cloned.profile.name = 'Bob'; // Không ảnh hưởng user gốc
389
+ ```
390
+
391
+ #### Thao tác Array
392
+
393
+ ```typescript
394
+ import { keyBy, groupBy, range, uniqBy, isEqual } from '@libs-ui/utils';
395
+
396
+ const users = [
397
+ { id: 1, name: 'John', type: 'admin' },
398
+ { id: 2, name: 'Jane', type: 'user' },
399
+ { id: 3, name: 'Bob', type: 'admin' },
400
+ ];
401
+
402
+ // Chuyển array thành object
403
+ keyBy(users, 'id');
404
+ // { "1": {id:1,name:"John",type:"admin"}, "2": {...}, "3": {...} }
405
+
406
+ // Nhóm theo type
407
+ groupBy(users, 'type');
408
+ // { "admin": [{...}, {...}], "user": [{...}] }
409
+
410
+ // Tạo mảng số
411
+ range(5); // [0, 1, 2, 3, 4]
412
+ range(1, 5); // [1, 2, 3, 4]
413
+ range(0, 10, 2); // [0, 2, 4, 6, 8]
414
+
415
+ // Loại bỏ trùng lặp
416
+ uniqBy([{ id: 1 }, { id: 2 }, { id: 1 }], 'id'); // [{id:1}, {id:2}]
417
+
418
+ // So sánh deep equality
419
+ isEqual({ a: 1, b: 2 }, { a: 1, b: 2 }); // true
420
+ isEqual([1, 2, 3], [1, 2, 3]); // true
421
+ ```
422
+
423
+ #### HTTP Query Params (Type-Safe)
424
+
425
+ ```typescript
426
+ import { UtilsHttpParamsRequest, UtilsHttpParamsRequestInstance } from '@libs-ui/utils';
427
+
428
+ // Định nghĩa interface cho params
429
+ interface SearchParams {
430
+ keyword: string;
431
+ page: number;
432
+ size: number;
433
+ }
434
+
435
+ // 1. Dùng fromObject với type safety
436
+ const params = new UtilsHttpParamsRequest<SearchParams>({
437
+ fromObject: { keyword: 'Angular', page: 1, size: 20 },
438
+ });
439
+ params.toString(); // keyword=Angular&page=1&size=20
440
+
441
+ // 2. Factory function (không cần new)
442
+ const params2 = UtilsHttpParamsRequestInstance<SearchParams>({
443
+ fromObject: { keyword: 'Angular', page: 1, size: 20 },
444
+ });
445
+
446
+ // 3. Method chaining
447
+ const params3 = new UtilsHttpParamsRequest().set('page', 1).set('size', 10).set('sort', 'name');
448
+
449
+ params3.delete('sort');
450
+ params3.toString(); // page=1&size=10
451
+
452
+ // 4. Wrap HttpParams có sẵn
453
+ import { HttpParams } from '@angular/common/http';
454
+ const base = new HttpParams().set('version', 'v2');
455
+ const wrapped = new UtilsHttpParamsRequest(undefined, base);
456
+ wrapped.get('version'); // 'v2'
457
+ ```
458
+
459
+ #### GET_PATH_VARIABLE — Type-Safe Path Params
460
+
461
+ ```typescript
462
+ import { GET_PATH_VARIABLE } from '@libs-ui/utils';
463
+
464
+ interface UserResource {
465
+ userId: number;
466
+ orgId: string;
467
+ }
468
+
469
+ // Tạo type với pattern "pathVariable-{key}"
470
+ type UserPathParams = GET_PATH_VARIABLE<UserResource>;
471
+ // Tương đương: { "pathVariable-userid": number; "pathVariable-orgid": string }
472
+
473
+ const pathParams: UserPathParams = {
474
+ 'pathVariable-userid': 123,
475
+ 'pathVariable-orgid': 'org-abc',
476
+ };
477
+ ```
478
+
479
+ ## Important Notes
480
+
481
+ ⚠️ **Lưu ý quan trọng khi sử dụng**:
482
+
483
+ - Các functions hỗ trợ unwrap Signal tự động (trừ khi dùng option `ignoreUnWrapSignal`).
484
+ - `get()` và `set()` hỗ trợ path dạng string (vd: `"user.profile.name"`) hoặc array (vd: `["user", "profile", "name"]`).
485
+ - `cloneDeep()` có thể clone Signal, Date, RegExp, Map, Set và các object phức tạp khác.
486
+ - `isEqual()` có thể so sánh deep equality cho objects và arrays.
487
+ - `UtilsHttpParamsRequest` kế thừa `HttpParams` — compatible 100% với Angular HttpClient.
488
+ - `HttpParams` của Angular là **immutable**; `UtilsHttpParamsRequest` xử lý điều này nội bộ (tự assign lại `this.params` sau mỗi mutation).
489
+
490
+ ## API Reference
491
+
492
+ Xem chi tiết API tại [Documentation](./docs/utils/utils.md) hoặc [Demo Live](http://localhost:4500/utils/helpers).
493
+
494
+ ### Các Functions chính
495
+
496
+ | Function | Mô tả |
497
+ | ------------------------------------------------------- | -------------------------------------------- |
498
+ | `isNil(value, options?)` | Kiểm tra giá trị có phải null hoặc undefined |
499
+ | `isEmpty(value, options?)` | Kiểm tra giá trị có rỗng không |
500
+ | `isTruthy(value, options?)` | Kiểm tra giá trị truthy |
501
+ | `isFalsy(value, options?)` | Kiểm tra giá trị falsy |
502
+ | `get(obj, path, defaultValue?, keepLastValueIfSignal?)` | Lấy giá trị theo path |
503
+ | `set(obj, path, value, options?)` | Thiết lập giá trị theo path |
504
+ | `cloneDeep(data, options?, seen?)` | Clone sâu object/array |
505
+ | `keyBy(data, key)` | Chuyển array thành object |
506
+ | `groupBy(data, key)` | Nhóm array theo key |
507
+ | `range(start, end?, step?)` | Tạo mảng số |
508
+ | `isEqual(value1, value2, options?)` | So sánh deep equality |
509
+ | `uniqBy(data, key?)` | Loại bỏ trùng lặp |
510
+ | `omitBy(objData, predicate)` | Loại bỏ thuộc tính theo điều kiện |
511
+ | `generateInterface(obj, interfaceName)` | Tạo interface từ object |
512
+ | `base64Encode(value)` | Mã hóa Base64 (hỗ trợ Unicode) |
513
+ | `base64Decode(value)` | Giải mã Base64 (hỗ trợ Unicode) |
514
+ | `convertBase64ToBlob(data)` | Chuyển Base64 sang Blob |
515
+ | `convertFileToBase64(file)` | Chuyển File sang Base64 string |
516
+ | `UtilsCache` | Quản lý Cache (Sync & Async) |
517
+ | `addArrayToSet(set, data)` | Thêm mảng vào Set |
518
+ | `convertSetToArray(set, map?)` | Chuyển Set sang Array |
519
+ | `colorContrastFromOrigin(color)` | Tạo bảng sắc độ (shades/tints) |
520
+ | `getColorById(str)` | Hash chuỗi thành màu cố định |
521
+ | `detectAndCleanNearWhiteColors(style)` | Làm sạch CSS style khỏi màu gần trắng |
522
+ | `UtilsCommunicateMicro` | Giao tiếp Cross-window (mã hóa) |
523
+ | `encrypt3rd(data)` | Mã hóa AES-CBC |
524
+ | `decrypt3rd(data)` | Giải mã AES-CBC |
525
+ | `encrypt(data)` | Mã hóa AES nội bộ |
526
+ | `md5(data)` | Hash MD5 |
527
+ | `isDangerousObject(obj)` | Kiểm tra Window/DOM/Global |
528
+ | `isPrimitiveType(val)` | Kiểm tra kiểu dữ liệu nguyên thủy |
529
+ | `getObjectSize(obj)` | Đo dung lượng object |
530
+ | `formatDate(date, format?)` | Định dạng ngày tháng |
531
+ | `getDayjs(config?)` | Khởi tạo Day.js instance |
532
+ | `getDeviceInfo()` | Lấy thông tin thiết bị |
533
+ | `isTouchDevice()` | Kiểm tra thiết bị cảm ứng |
534
+ | `getViewport()` | Lấy kích thước Viewport |
535
+ | `downloadFileByUrl(url, name, onlyOpen?)` | Tải file từ URL |
536
+ | `downloadFileByUrlUseXmlRequest(url, name)` | Tải file bằng XMLHttpRequest |
537
+ | `downloadImageFromELement(img, type?, name?)` | Lưu ảnh từ thẻ img |
538
+ | `isTypeImage(file)` | Kiểm tra Blob/File là ảnh |
539
+ | `isTypeVideo(file)` | Kiểm tra Blob/File là video |
540
+ | `getFileExtension(file)` | Lấy extension của file |
541
+ | `getLabelBySizeFile(size, toFixed?)` | Format kích thước byte |
542
+ | `convertBlobToFile(blob, name?)` | Chuyển Blob thành File |
543
+ | `formatNumber(value)` | Chuẩn hóa chuỗi số theo locale |
544
+ | `viewDataNumberByLanguage(val, neg, fixed?, ...)` | Định dạng số theo VI/EN locale |
545
+ | `UtilsLanguageConstants.{KEY}` | Hằng số mã ngôn ngữ ISO 639-1 (27 ngôn ngữ) |
546
+ | `UtilsLanguageConstants.defaultLang()` | Tự dò ngôn ngữ trình duyệt, fallback 'en' |
547
+ | `UtilsLanguageConstants.isSupported(lang)` | Kiểm tra ngôn ngữ có được hỗ trợ |
548
+ | `UtilsLanguageConstants.setSupportedLanguages(langs)` | Ghi đè danh sách ngôn ngữ hỗ trợ |
549
+ | `protectString(input)` | XOR + reverse + base64 encode (obfuscation) |
550
+ | `revealString(encoded)` | Giải mã ngược lại protectString |
551
+ | `createUniqueRandomIntGenerator(min, max)` | Factory tạo số ngẫu nhiên không trùng (10 lần) |
552
+ | `patternEmail()` | Regex kiểm tra email chuẩn |
553
+ | `patternUrl()` | Regex kiểm tra URL đầy đủ |
554
+ | `patternMobilePhone()` | Regex kiểm tra SĐT di động Việt Nam |
555
+ | `patternNameUtf8()` | Regex hỗ trợ tên tiếng Việt có dấu |
556
+ | `patternEmoji()` | Regex phát hiện ký tự emoji (global) |
557
+ | `traceStack()` | Trích xuất call stack sạch (lọc rác) |
558
+ | `convertObjectToSignal()` | Biến object thành cấu trúc Signals lồng nhau |
559
+ | `convertSignalToObject()` | Chuyển cấu trúc signals về plain object |
560
+ | `unwrapSignal()` | Lấy giá trị cuối cùng từ (lồng) signal |
561
+ | `normalizeUrl(rawUrl)` | Chuẩn hóa URL, gộp dấu // trong pathname |
562
+ | `uuid()` | Tạo chuỗi định danh duy nhất (MD5 hash) |
563
+ | `xssFilter(data)` | Lọc chuỗi HTML khỏi XSS thông qua hàm custom |
564
+ | `updateFunctionXssFilter(fn)` | Cập nhật custom implementation cho xssFilter |
565
+
566
+ ## Demo
567
+
568
+ - **Local Utilities**: [http://localhost:4500/utils/helpers](http://localhost:4500/utils/helpers)
569
+ - **Local Base64**: [http://localhost:4500/utils/base64](http://localhost:4500/utils/base64)
570
+ - **Local Cache**: [http://localhost:4500/utils/cache](http://localhost:4500/utils/cache)
571
+ - **Local Collection**: [http://localhost:4500/utils/collection](http://localhost:4500/utils/collection)
572
+ - **Local Color**: [http://localhost:4500/utils/color](http://localhost:4500/utils/color)
573
+ - **Local Micro Comms**: [http://localhost:4500/utils/communicate-micro](http://localhost:4500/utils/communicate-micro)
574
+ - **Local Crypto 3rd**: [http://localhost:4500/utils/crypto-3rd](http://localhost:4500/utils/crypto-3rd)
575
+ - **Local Crypto**: [http://localhost:4500/utils/crypto](http://localhost:4500/utils/crypto)
576
+ - **Local Dangerous Object**: [http://localhost:4500/utils/dangerous-object](http://localhost:4500/utils/dangerous-object)
577
+ - **Local Data**: [http://localhost:4500/utils/data](http://localhost:4500/utils/data)
578
+ - **Local Date**: [http://localhost:4500/utils/date](http://localhost:4500/utils/date)
579
+ - **Local DOM**: [http://localhost:4500/utils/dom](http://localhost:4500/utils/dom)
580
+ - **Local Download**: [http://localhost:4500/utils/download](http://localhost:4500/utils/download)
581
+ - **Local File**: [http://localhost:4500/utils/file](http://localhost:4500/utils/file)
582
+ - **Local Format Number**: [http://localhost:4500/utils/format-number](http://localhost:4500/utils/format-number)
583
+ - **Local Format Text**: [http://localhost:4500/utils/format-text](http://localhost:4500/utils/format-text)
584
+ - **Local Embed Frame**: [http://localhost:4500/utils/embed-frame](http://localhost:4500/utils/embed-frame)
585
+ - **Local Smart Axis Scale**: [http://localhost:4500/utils/smart-axis-scale](http://localhost:4500/utils/smart-axis-scale)
586
+ - **Local Language**: [http://localhost:4500/utils/language](http://localhost:4500/utils/language)
587
+ - **Local Random & String Protection**: [http://localhost:4500/utils/random](http://localhost:4500/utils/random)
588
+ - **Local Patterns (Regex)**: [http://localhost:4500/utils/pattern](http://localhost:4500/utils/pattern)
589
+ - **Local Trace Stack**: [http://localhost:4500/utils/trace](http://localhost:4500/utils/trace)
590
+ - **Local Two-Way Signal Object**: [http://localhost:4500/utils/two-way-signal-object](http://localhost:4500/utils/two-way-signal-object)
591
+ - **Local URI Utilities**: [http://localhost:4500/utils/uri](http://localhost:4500/utils/uri)
592
+ - **Local URL Utilities**: [http://localhost:4500/utils/url](http://localhost:4500/utils/url)
593
+ - **Local URL Search Params**: [http://localhost:4500/utils/url-search-params](http://localhost:4500/utils/url-search-params)
594
+ - **Local UUID Utilities**: [http://localhost:4500/utils/uuid](http://localhost:4500/utils/uuid)
595
+ - **Local Xss Filter Utilities**: [http://localhost:4500/utils/xss-filter](http://localhost:4500/utils/xss-filter)
596
+
597
+ ### HTTP Params
598
+
599
+ | Class / Type | Mô tả |
600
+ | ----------------------------------------- | ---------------------------------------------------------------------------------------------- |
601
+ | `UtilsHttpParamsRequest<Type>` | Wrapper type-safe cho Angular HttpParams — hỗ trợ method chaining, fromObject với generic type |
602
+ | `UtilsHttpParamsRequestInstance<Type>()` | Factory function tạo `UtilsHttpParamsRequest` không cần `new` |
603
+ | `GET_PATH_VARIABLE<TypePath, TypeOther?>` | Utility type tạo map path-variable từ interface (pattern: `pathVariable-{key}`) |
604
+ | `HttpParamsOptions<Type>` | Interface options cho constructor (`fromString`, `fromObject`, `encoder`) |
605
+
606
+ ### InjectionTokens
607
+
608
+ | Token | Mô tả |
609
+ | -------------------------------------------------- | ----------------------------------------------------- |
610
+ | `LINK_IMAGE_ERROR_TOKEN_INJECT` | InjectionToken cho link ảnh fallback |
611
+ | `PROCESS_BAR_STANDARD_CONFIG_DEFAULT_TOKEN_INJECT` | InjectionToken cấu hình mặc định process bar standard |
612
+ | `PROCESS_BAR_STEPS_CONFIG_DEFAULT_TOKEN_INJECT` | InjectionToken cấu hình mặc định process bar steps |
613
+
614
+ ## Demo
615
+
616
+ - **Helpers utilities**: [http://localhost:4500/utils/helpers](http://localhost:4500/utils/helpers)
617
+ - **HTTP Params**: [http://localhost:4500/utils/http-params](http://localhost:4500/utils/http-params)
618
+ - **Injection Tokens**: [http://localhost:4500/utils/inject-token](http://localhost:4500/utils/inject-token)
619
+ - **Key Cache**: [http://localhost:4500/utils/key-cache](http://localhost:4500/utils/key-cache)
620
+ - **Key Code**: [http://localhost:4500/utils/key-code](http://localhost:4500/utils/key-code)
621
+ - **Production**: (Chưa có)
622
+
623
+ ## Công nghệ sử dụng
624
+
625
+ - **Angular**: >=18.0.0
626
+ - **TypeScript**: Latest
627
+ - **RxJS**: ~7.8.0
628
+ - **dayjs**: 1.11.5
629
+ - **crypto-es**: ^2.1.0
630
+
631
+ ## Tài liệu
632
+
633
+ Xem thêm tài liệu chi tiết tại [docs/utils/utils.md](../../docs/utils/utils.md).
634
+ ````
package/base64.d.ts CHANGED
@@ -1,5 +1,30 @@
1
+ /**
2
+ * Mã hóa chuỗi thành Base64 (có hỗ trợ ký tự đặc biệt qua encodeURI)
3
+ * @param value Chuỗi cần mã hóa
4
+ * @returns Chuỗi đã mã hóa Base64
5
+ */
1
6
  export declare const base64Encode: (value: string) => string;
7
+ /**
8
+ * Giải mã chuỗi Base64 (có hỗ trợ ký tự đặc biệt qua decodeURI)
9
+ * @param value Chuỗi Base64 cần giải mã
10
+ * @returns Chuỗi đã giải mã
11
+ */
2
12
  export declare const base64Decode: (value: string) => string;
13
+ /**
14
+ * Chuyển đổi dữ liệu Base64 thành Blob
15
+ * @param dataBase64 Dữ liệu Base64 (có thể bao gồm marker ;base64,)
16
+ * @returns Blob tương ứng
17
+ */
3
18
  export declare const convertBase64ToBlob: (dataBase64: string) => Blob;
19
+ /**
20
+ * Chuyển đổi File thành Base64 string hoặc Object URL tùy loại file
21
+ * @param file Đối tượng File cần chuyển đổi
22
+ * @returns Nếu là ảnh, trả về Base64 string. Ngược lại trả về Object URL.
23
+ */
4
24
  export declare const convertFileToBase64_ObjectUrl: (file: File) => Promise<string | ArrayBuffer>;
25
+ /**
26
+ * Chuyển đổi File thành Base64 string
27
+ * @param file Đối tượng File cần chuyển đổi
28
+ * @returns Promise chứa chuỗi Base64
29
+ */
5
30
  export declare const convertFileToBase64: (file: File) => Promise<string | ArrayBuffer>;