@chaos_team/chaos-ui 1.0.5
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/CHANGELOG.md +286 -0
- package/LICENSE +21 -0
- package/README.md +295 -0
- package/THIRD_PARTY_NOTICES.md +22 -0
- package/dist/business.cjs +26 -0
- package/dist/business.d.cts +10311 -0
- package/dist/business.d.ts +10311 -0
- package/dist/business.js +26 -0
- package/dist/format-BUpOzeCo.d.cts +8 -0
- package/dist/format-BUpOzeCo.d.ts +8 -0
- package/dist/hooks.cjs +8 -0
- package/dist/hooks.d.cts +1148 -0
- package/dist/hooks.d.ts +1148 -0
- package/dist/hooks.js +8 -0
- package/dist/index.cjs +6 -0
- package/dist/index.d.cts +5616 -0
- package/dist/index.d.ts +5616 -0
- package/dist/index.js +6 -0
- package/dist/lib.cjs +42 -0
- package/dist/lib.d.cts +804 -0
- package/dist/lib.d.ts +804 -0
- package/dist/lib.js +42 -0
- package/dist/message-KJli9tvf.d.cts +71 -0
- package/dist/message-KJli9tvf.d.ts +71 -0
- package/dist/message-provider-BI-P3CNq.d.cts +11 -0
- package/dist/message-provider-BI-P3CNq.d.ts +11 -0
- package/dist/next.cjs +6 -0
- package/dist/next.d.cts +103 -0
- package/dist/next.d.ts +103 -0
- package/dist/next.js +6 -0
- package/dist/theme-toggle-JL_jZE-w.d.cts +81 -0
- package/dist/theme-toggle-JL_jZE-w.d.ts +81 -0
- package/dist/time-picker-H1AaecnE.d.cts +452 -0
- package/dist/time-picker-H1AaecnE.d.ts +452 -0
- package/dist/ui/icons.cjs +6 -0
- package/dist/ui/icons.d.cts +3 -0
- package/dist/ui/icons.d.ts +3 -0
- package/dist/ui/icons.js +6 -0
- package/dist/ui-icons.cjs +6 -0
- package/dist/ui-icons.d.cts +205 -0
- package/dist/ui-icons.d.ts +205 -0
- package/dist/ui-icons.js +6 -0
- package/dist/ui.cjs +6 -0
- package/dist/ui.d.cts +39 -0
- package/dist/ui.d.ts +39 -0
- package/dist/ui.js +6 -0
- package/package.json +265 -0
- package/styles.css +1300 -0
- package/styles.css.d.ts +11 -0
package/dist/lib.d.ts
ADDED
|
@@ -0,0 +1,804 @@
|
|
|
1
|
+
import { ClassValue } from 'clsx';
|
|
2
|
+
export { b as MessageGlobalConfig, M as MessageOptions, c as MessagePlacement, a as MessageType, m as message } from './message-KJli9tvf.js';
|
|
3
|
+
import { AxiosRequestConfig } from 'axios';
|
|
4
|
+
export { f as formatCurrency, a as formatDate, b as formatDateTime, c as formatNumber, d as formatPercent, e as formatRelativeTime } from './format-BUpOzeCo.js';
|
|
5
|
+
import * as React$1 from 'react';
|
|
6
|
+
import { Resource } from 'i18next';
|
|
7
|
+
export { default as i18n } from 'i18next';
|
|
8
|
+
|
|
9
|
+
declare function cn(...inputs: ClassValue[]): string;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @lib storage
|
|
13
|
+
* @category lib/storage
|
|
14
|
+
* @since 0.2.0
|
|
15
|
+
* @description localStorage/sessionStorage 包装(过期/序列化/加密) / Storage wrapper with expiry, serialization, and optional encryption
|
|
16
|
+
* @example
|
|
17
|
+
* storage.set('key', { foo: 'bar' }, { expires: 3600 });
|
|
18
|
+
* const data = storage.get<{ foo: string }>('key');
|
|
19
|
+
*/
|
|
20
|
+
interface StorageOptions {
|
|
21
|
+
/** Expiry in seconds / 过期时间(秒) */
|
|
22
|
+
expires?: number;
|
|
23
|
+
/** Whether to use sessionStorage instead of localStorage / 是否使用 sessionStorage */
|
|
24
|
+
session?: boolean;
|
|
25
|
+
}
|
|
26
|
+
declare const storage: {
|
|
27
|
+
/**
|
|
28
|
+
* Set a value in storage / 设置存储值
|
|
29
|
+
* @param key Storage key
|
|
30
|
+
* @param value Value to store
|
|
31
|
+
* @param options Storage options (expiry, session)
|
|
32
|
+
*/
|
|
33
|
+
set<T>(key: string, value: T, options?: StorageOptions): void;
|
|
34
|
+
/**
|
|
35
|
+
* Get a value from storage / 获取存储值
|
|
36
|
+
* @param key Storage key
|
|
37
|
+
* @param options Storage options (session)
|
|
38
|
+
* @returns The stored value or null if not found or expired
|
|
39
|
+
*/
|
|
40
|
+
get<T>(key: string, options?: StorageOptions): T | null;
|
|
41
|
+
/**
|
|
42
|
+
* Remove a value from storage / 移除存储值
|
|
43
|
+
*/
|
|
44
|
+
remove(key: string, options?: StorageOptions): void;
|
|
45
|
+
/**
|
|
46
|
+
* Clear all storage / 清空存储
|
|
47
|
+
*/
|
|
48
|
+
clear(options?: StorageOptions): void;
|
|
49
|
+
/**
|
|
50
|
+
* Check if a key exists and is not expired / 检查键是否存在
|
|
51
|
+
*/
|
|
52
|
+
has(key: string, options?: StorageOptions): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Get all keys / 获取所有键
|
|
55
|
+
*/
|
|
56
|
+
keys(options?: StorageOptions): string[];
|
|
57
|
+
/**
|
|
58
|
+
* Get storage size (approximate in bytes) / 获取存储大小(近似字节)
|
|
59
|
+
*/
|
|
60
|
+
size(options?: StorageOptions): number;
|
|
61
|
+
};
|
|
62
|
+
/** SessionStorage convenience wrapper / sessionStorage 便捷包装 */
|
|
63
|
+
declare const sessionStorage: {
|
|
64
|
+
set: <T>(key: string, value: T, options?: Omit<StorageOptions, "session">) => void;
|
|
65
|
+
get: <T>(key: string) => T | null;
|
|
66
|
+
remove: (key: string) => void;
|
|
67
|
+
clear: () => void;
|
|
68
|
+
has: (key: string) => boolean;
|
|
69
|
+
keys: () => string[];
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @lib eventBus
|
|
74
|
+
* @category lib/event
|
|
75
|
+
* @since 0.2.0
|
|
76
|
+
* @description 全局事件总线 / Global event bus for cross-component communication
|
|
77
|
+
* @example
|
|
78
|
+
* eventBus.on('user:login', (user) => console.log(user));
|
|
79
|
+
* eventBus.emit('user:login', { name: 'John' });
|
|
80
|
+
* eventBus.off('user:login');
|
|
81
|
+
*/
|
|
82
|
+
type EventHandler<T = unknown> = (payload: T) => void;
|
|
83
|
+
declare class EventBus {
|
|
84
|
+
private handlers;
|
|
85
|
+
/**
|
|
86
|
+
* Subscribe to an event / 订阅事件
|
|
87
|
+
* @param event Event name
|
|
88
|
+
* @param handler Event handler
|
|
89
|
+
* @returns Unsubscribe function
|
|
90
|
+
*/
|
|
91
|
+
on<T = unknown>(event: string, handler: EventHandler<T>): () => void;
|
|
92
|
+
/**
|
|
93
|
+
* Subscribe to an event once (auto-unsubscribe after first call) / 订阅一次
|
|
94
|
+
*/
|
|
95
|
+
once<T = unknown>(event: string, handler: EventHandler<T>): () => void;
|
|
96
|
+
/**
|
|
97
|
+
* Unsubscribe from an event / 取消订阅
|
|
98
|
+
* @param event Event name
|
|
99
|
+
* @param handler Specific handler (if omitted, removes all handlers for the event)
|
|
100
|
+
*/
|
|
101
|
+
off<T = unknown>(event: string, handler?: EventHandler<T>): void;
|
|
102
|
+
/**
|
|
103
|
+
* Emit an event / 触发事件
|
|
104
|
+
*/
|
|
105
|
+
emit<T = unknown>(event: string, payload?: T): void;
|
|
106
|
+
/**
|
|
107
|
+
* Remove all handlers for an event (or all events) / 清除所有处理器
|
|
108
|
+
*/
|
|
109
|
+
clear(event?: string): void;
|
|
110
|
+
/**
|
|
111
|
+
* Get all registered event names / 获取所有事件名
|
|
112
|
+
*/
|
|
113
|
+
events(): string[];
|
|
114
|
+
/**
|
|
115
|
+
* Get handler count for an event / 获取事件处理器数量
|
|
116
|
+
*/
|
|
117
|
+
listenerCount(event: string): number;
|
|
118
|
+
}
|
|
119
|
+
/** Global event bus instance / 全局事件总线实例 */
|
|
120
|
+
declare const eventBus: EventBus;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @lib download
|
|
124
|
+
* @category lib/file
|
|
125
|
+
* @since 0.2.0
|
|
126
|
+
* @description 文件下载工具 / File download utilities (Blob/URL/Stream)
|
|
127
|
+
* @example
|
|
128
|
+
* download.text('hello.txt', 'Hello World');
|
|
129
|
+
* download.blob('data.bin', blob);
|
|
130
|
+
* download.url('https://example.com/file.pdf');
|
|
131
|
+
*/
|
|
132
|
+
declare const download: {
|
|
133
|
+
/**
|
|
134
|
+
* Download text content as a file / 下载文本文件
|
|
135
|
+
*/
|
|
136
|
+
text(filename: string, content: string, mime?: string): void;
|
|
137
|
+
/**
|
|
138
|
+
* Download JSON as a file / 下载 JSON 文件
|
|
139
|
+
*/
|
|
140
|
+
json(filename: string, data: unknown, pretty?: boolean): void;
|
|
141
|
+
/**
|
|
142
|
+
* Download a Blob / 下载 Blob
|
|
143
|
+
*/
|
|
144
|
+
blob(filename: string, blob: Blob): void;
|
|
145
|
+
/**
|
|
146
|
+
* Download from a URL / 从 URL 下载
|
|
147
|
+
*/
|
|
148
|
+
url(filename: string, url: string): void;
|
|
149
|
+
/**
|
|
150
|
+
* Download CSV from array of objects / 从对象数组下载 CSV
|
|
151
|
+
*/
|
|
152
|
+
csv(filename: string, rows: Record<string, unknown>[], headers?: string[]): void;
|
|
153
|
+
/**
|
|
154
|
+
* Download from fetch response / 从 fetch 响应下载
|
|
155
|
+
*/
|
|
156
|
+
response(filename: string, response: Response): Promise<void>;
|
|
157
|
+
/**
|
|
158
|
+
* Download via fetch with progress / 通过 fetch 下载(带进度)
|
|
159
|
+
*/
|
|
160
|
+
fetch(url: string, filename: string, options?: RequestInit): Promise<void>;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* @lib cookie
|
|
165
|
+
* @category lib/storage
|
|
166
|
+
* @since 0.2.0
|
|
167
|
+
* @description Cookie 读写工具 / Cookie read/write utilities
|
|
168
|
+
* @example
|
|
169
|
+
* cookie.set('token', 'abc123', { expires: 7, secure: true });
|
|
170
|
+
* const token = cookie.get('token');
|
|
171
|
+
* cookie.remove('token');
|
|
172
|
+
*/
|
|
173
|
+
interface CookieOptions {
|
|
174
|
+
/** Expiry in days / 过期天数 */
|
|
175
|
+
expires?: number;
|
|
176
|
+
/** Expiry date / 过期日期 */
|
|
177
|
+
expiresDate?: Date;
|
|
178
|
+
/** Path (default: '/') / 路径 */
|
|
179
|
+
path?: string;
|
|
180
|
+
/** Domain / 域名 */
|
|
181
|
+
domain?: string;
|
|
182
|
+
/** Secure flag / 安全标志 */
|
|
183
|
+
secure?: boolean;
|
|
184
|
+
/** SameSite policy / SameSite 策略 */
|
|
185
|
+
sameSite?: "strict" | "lax" | "none";
|
|
186
|
+
/** HttpOnly flag (only works when set by server) / HttpOnly 标志 */
|
|
187
|
+
httpOnly?: boolean;
|
|
188
|
+
}
|
|
189
|
+
declare const cookie: {
|
|
190
|
+
/**
|
|
191
|
+
* Set a cookie / 设置 Cookie
|
|
192
|
+
*/
|
|
193
|
+
set(name: string, value: string, options?: CookieOptions): void;
|
|
194
|
+
/**
|
|
195
|
+
* Get a cookie value / 获取 Cookie
|
|
196
|
+
*/
|
|
197
|
+
get(name: string): string | null;
|
|
198
|
+
/**
|
|
199
|
+
* Remove a cookie / 删除 Cookie
|
|
200
|
+
*/
|
|
201
|
+
remove(name: string, options?: Pick<CookieOptions, "path" | "domain">): void;
|
|
202
|
+
/**
|
|
203
|
+
* Get all cookies as an object / 获取所有 Cookie
|
|
204
|
+
*/
|
|
205
|
+
getAll(): Record<string, string>;
|
|
206
|
+
/**
|
|
207
|
+
* Check if a cookie exists / 检查 Cookie 是否存在
|
|
208
|
+
*/
|
|
209
|
+
has(name: string): boolean;
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* @lib url
|
|
214
|
+
* @category lib/url
|
|
215
|
+
* @since 0.2.0
|
|
216
|
+
* @description URL 参数解析/序列化工具 / URL parameter parse/serialize utilities
|
|
217
|
+
* @example
|
|
218
|
+
* const params = url.parse('https://example.com?a=1&b=2');
|
|
219
|
+
* url.stringify({ a: 1, b: [2, 3] });
|
|
220
|
+
* url.getQuery('key');
|
|
221
|
+
* url.setQuery('key', 'value');
|
|
222
|
+
*/
|
|
223
|
+
type QueryValue = string | number | boolean | null | undefined;
|
|
224
|
+
type QueryParams = Record<string, QueryValue | QueryValue[]>;
|
|
225
|
+
declare const url: {
|
|
226
|
+
/**
|
|
227
|
+
* Parse a query string into an object / 解析查询字符串
|
|
228
|
+
* @param search Query string (e.g., '?a=1&b=2' or 'a=1&b=2')
|
|
229
|
+
* @returns Parsed parameters object
|
|
230
|
+
*/
|
|
231
|
+
parse(search?: string): Record<string, string>;
|
|
232
|
+
/**
|
|
233
|
+
* Serialize an object into a query string / 序列化为查询字符串
|
|
234
|
+
* @param params Parameters object
|
|
235
|
+
* @returns Query string (without leading '?')
|
|
236
|
+
*/
|
|
237
|
+
stringify(params: QueryParams): string;
|
|
238
|
+
/**
|
|
239
|
+
* Get a specific query parameter / 获取特定查询参数
|
|
240
|
+
*/
|
|
241
|
+
getQuery(key: string, search?: string): string | null;
|
|
242
|
+
/**
|
|
243
|
+
* Set query parameters (updates URL in browser) / 设置查询参数
|
|
244
|
+
*/
|
|
245
|
+
setQuery(params: QueryParams, options?: {
|
|
246
|
+
push?: boolean;
|
|
247
|
+
}): void;
|
|
248
|
+
/**
|
|
249
|
+
* Remove query parameters / 移除查询参数
|
|
250
|
+
*/
|
|
251
|
+
removeQuery(keys: string | string[]): void;
|
|
252
|
+
/**
|
|
253
|
+
* Parse a full URL into parts / 解析完整 URL
|
|
254
|
+
*/
|
|
255
|
+
parseUrl(fullUrl: string): {
|
|
256
|
+
protocol: string;
|
|
257
|
+
hostname: string;
|
|
258
|
+
port: string;
|
|
259
|
+
pathname: string;
|
|
260
|
+
search: string;
|
|
261
|
+
hash: string;
|
|
262
|
+
params: Record<string, string>;
|
|
263
|
+
};
|
|
264
|
+
/**
|
|
265
|
+
* Build a URL with query parameters / 构建带参数的 URL
|
|
266
|
+
*/
|
|
267
|
+
buildUrl(base: string, params?: QueryParams): string;
|
|
268
|
+
/**
|
|
269
|
+
* Check if URL is external / 检查是否外部链接
|
|
270
|
+
*/
|
|
271
|
+
isExternal(link: string): boolean;
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
type ModalKind = "confirm" | "info" | "warning" | "success" | "error";
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* @lib modal
|
|
278
|
+
* @category lib/feedback
|
|
279
|
+
* @since 0.3.0
|
|
280
|
+
* @description 命令式模态框 API (antd Modal.confirm/Radix Dialog equivalent) / Imperative modal API
|
|
281
|
+
* @keywords modal, dialog, confirm, imperative, popup
|
|
282
|
+
* @example
|
|
283
|
+
* ```ts
|
|
284
|
+
* import { Modal } from '@chaos_team/chaos-ui';
|
|
285
|
+
*
|
|
286
|
+
* Modal.confirm({
|
|
287
|
+
* title: '确认删除?',
|
|
288
|
+
* content: '此操作不可撤销',
|
|
289
|
+
* okText: '删除',
|
|
290
|
+
* cancelText: '取消',
|
|
291
|
+
* onOk: async () => { await deleteItem(); },
|
|
292
|
+
* });
|
|
293
|
+
*
|
|
294
|
+
* Modal.info({ title: '提示', content: '请检查输入' });
|
|
295
|
+
* Modal.warning({ title: '警告', content: '余额不足' });
|
|
296
|
+
* Modal.success({ title: '成功', content: '保存完成' });
|
|
297
|
+
* Modal.error({ title: '错误', content: '网络异常' });
|
|
298
|
+
* ```
|
|
299
|
+
*/
|
|
300
|
+
|
|
301
|
+
interface ModalConfirmOptions {
|
|
302
|
+
title?: React.ReactNode;
|
|
303
|
+
content?: React.ReactNode;
|
|
304
|
+
okText?: React.ReactNode;
|
|
305
|
+
cancelText?: React.ReactNode;
|
|
306
|
+
okVariant?: "default" | "destructive";
|
|
307
|
+
width?: string | number;
|
|
308
|
+
closable?: boolean;
|
|
309
|
+
maskClosable?: boolean;
|
|
310
|
+
icon?: React.ReactNode;
|
|
311
|
+
/** Callback when OK is clicked (supports async). If provided, the modal will show a loading state until it resolves. */
|
|
312
|
+
onOk?: () => void | Promise<void>;
|
|
313
|
+
/** Callback when Cancel is clicked. */
|
|
314
|
+
onCancel?: () => void;
|
|
315
|
+
}
|
|
316
|
+
type ModalAlertOptions = Omit<ModalConfirmOptions, "okVariant" | "cancelText" | "onCancel">;
|
|
317
|
+
type ModalAPI = {
|
|
318
|
+
confirm: (options: ModalConfirmOptions) => void;
|
|
319
|
+
info: (options: ModalAlertOptions) => void;
|
|
320
|
+
warning: (options: ModalAlertOptions) => void;
|
|
321
|
+
success: (options: ModalAlertOptions) => void;
|
|
322
|
+
error: (options: ModalAlertOptions) => void;
|
|
323
|
+
closeAll: () => void;
|
|
324
|
+
};
|
|
325
|
+
declare const Modal: ModalAPI;
|
|
326
|
+
|
|
327
|
+
interface ApiError {
|
|
328
|
+
status: number;
|
|
329
|
+
code?: string;
|
|
330
|
+
message: string;
|
|
331
|
+
details?: unknown;
|
|
332
|
+
}
|
|
333
|
+
interface ApiClientConfig {
|
|
334
|
+
baseURL?: string;
|
|
335
|
+
timeout?: number;
|
|
336
|
+
getToken?: () => string | null | Promise<string | null>;
|
|
337
|
+
refreshToken?: () => Promise<string | null>;
|
|
338
|
+
onTokenExpired?: () => void;
|
|
339
|
+
onError?: (error: ApiError) => void;
|
|
340
|
+
showErrorToast?: boolean;
|
|
341
|
+
}
|
|
342
|
+
declare class ApiClient {
|
|
343
|
+
private instance;
|
|
344
|
+
constructor(config?: ApiClientConfig);
|
|
345
|
+
get<T>(url: string, config?: AxiosRequestConfig): Promise<T>;
|
|
346
|
+
post<T>(url: string, body?: unknown, config?: AxiosRequestConfig): Promise<T>;
|
|
347
|
+
put<T>(url: string, body?: unknown, config?: AxiosRequestConfig): Promise<T>;
|
|
348
|
+
patch<T>(url: string, body?: unknown, config?: AxiosRequestConfig): Promise<T>;
|
|
349
|
+
delete<T>(url: string, config?: AxiosRequestConfig): Promise<T>;
|
|
350
|
+
setHeader(key: string, value: string): void;
|
|
351
|
+
removeHeader(key: string): void;
|
|
352
|
+
}
|
|
353
|
+
declare function getApiClient(config?: ApiClientConfig): ApiClient;
|
|
354
|
+
declare function safeRequest<T>(fn: () => Promise<T>, fallback?: T): Promise<T | undefined>;
|
|
355
|
+
|
|
356
|
+
type LogLevel = "debug" | "info" | "warn" | "error";
|
|
357
|
+
declare const logger: {
|
|
358
|
+
readonly level: LogLevel;
|
|
359
|
+
setLevel(level: LogLevel): void;
|
|
360
|
+
debug: (...args: unknown[]) => void;
|
|
361
|
+
info: (...args: unknown[]) => void;
|
|
362
|
+
warn: (...args: unknown[]) => void;
|
|
363
|
+
error: (...args: unknown[]) => void;
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
type Role = "admin" | "manager" | "editor" | "viewer" | "guest";
|
|
367
|
+
type Permission = "read" | "create" | "update" | "delete" | "publish" | "export" | "import" | "manage_users" | "manage_roles" | "manage_settings";
|
|
368
|
+
declare function hasPermission(role: Role, permission: Permission): boolean;
|
|
369
|
+
declare function hasAnyPermission(role: Role, permissions: Permission[]): boolean;
|
|
370
|
+
declare function hasAllPermissions(role: Role, permissions: Permission[]): boolean;
|
|
371
|
+
|
|
372
|
+
interface ChaosI18nProviderProps {
|
|
373
|
+
locale?: string;
|
|
374
|
+
children: React.ReactNode;
|
|
375
|
+
resources?: Resource;
|
|
376
|
+
}
|
|
377
|
+
declare function ChaosI18nProvider({ locale, children, resources, }: ChaosI18nProviderProps): React$1.JSX.Element;
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Common validation utilities for forms and data processing.
|
|
381
|
+
* @since 0.2.0
|
|
382
|
+
*/
|
|
383
|
+
declare const patterns: {
|
|
384
|
+
/** Chinese mobile phone (11 digits, starts with 1) */
|
|
385
|
+
phone: RegExp;
|
|
386
|
+
/** Email address */
|
|
387
|
+
email: RegExp;
|
|
388
|
+
/** Chinese ID card (18 digits with check digit) */
|
|
389
|
+
idCard: RegExp;
|
|
390
|
+
/** Bank card number (16-19 digits) */
|
|
391
|
+
bankCard: RegExp;
|
|
392
|
+
/** Unified Social Credit Code (18 chars, alphanumeric) */
|
|
393
|
+
uscc: RegExp;
|
|
394
|
+
/** URL */
|
|
395
|
+
url: RegExp;
|
|
396
|
+
/** IPv4 */
|
|
397
|
+
ipv4: RegExp;
|
|
398
|
+
};
|
|
399
|
+
declare const validators: {
|
|
400
|
+
/** Test against a regex pattern */
|
|
401
|
+
pattern: (value: string, pattern: RegExp) => boolean;
|
|
402
|
+
/** Required field — not null, not undefined, not empty string, not whitespace-only */
|
|
403
|
+
required: (value: unknown) => boolean;
|
|
404
|
+
/** Minimum string length */
|
|
405
|
+
minLength: (value: string, min: number) => boolean;
|
|
406
|
+
/** Maximum string length */
|
|
407
|
+
maxLength: (value: string, max: number) => boolean;
|
|
408
|
+
/** Number range (inclusive) */
|
|
409
|
+
range: (value: number, min: number, max: number) => boolean;
|
|
410
|
+
/** Matches a specific value (e.g. password confirm) */
|
|
411
|
+
matches: <T>(value: T, target: T) => boolean;
|
|
412
|
+
/** Phone number */
|
|
413
|
+
phone: (value: string) => boolean;
|
|
414
|
+
/** Email */
|
|
415
|
+
email: (value: string) => boolean;
|
|
416
|
+
/** Chinese ID card */
|
|
417
|
+
idCard: (value: string) => boolean;
|
|
418
|
+
/** Bank card */
|
|
419
|
+
bankCard: (value: string) => boolean;
|
|
420
|
+
/** Unified Social Credit Code */
|
|
421
|
+
uscc: (value: string) => boolean;
|
|
422
|
+
/** URL */
|
|
423
|
+
url: (value: string) => boolean;
|
|
424
|
+
/** IPv4 */
|
|
425
|
+
ipv4: (value: string) => boolean;
|
|
426
|
+
/** Positive integer */
|
|
427
|
+
positiveInteger: (value: number) => boolean;
|
|
428
|
+
/** Non-negative integer */
|
|
429
|
+
nonNegativeInteger: (value: number) => boolean;
|
|
430
|
+
/** Decimal with precision */
|
|
431
|
+
decimal: (precision: number) => (value: number) => boolean;
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Random number and ID generation utilities.
|
|
436
|
+
* @since 0.2.0
|
|
437
|
+
*/
|
|
438
|
+
/**
|
|
439
|
+
* Random integer in [min, max] (inclusive).
|
|
440
|
+
*/
|
|
441
|
+
declare function randomInt(min: number, max: number): number;
|
|
442
|
+
/**
|
|
443
|
+
* Random float in [min, max).
|
|
444
|
+
*/
|
|
445
|
+
declare function randomFloat(min: number, max: number): number;
|
|
446
|
+
/**
|
|
447
|
+
* Generate a UUID v4 string.
|
|
448
|
+
*/
|
|
449
|
+
declare function uuid(): string;
|
|
450
|
+
/**
|
|
451
|
+
* Generate a non-repeating sequence of integers in [0, n-1] (Fisher-Yates).
|
|
452
|
+
*/
|
|
453
|
+
declare function uniqueSequence(n: number): number[];
|
|
454
|
+
/**
|
|
455
|
+
* Pick a random element from an array.
|
|
456
|
+
*/
|
|
457
|
+
declare function randomPick<T>(arr: T[]): T | undefined;
|
|
458
|
+
/**
|
|
459
|
+
* Pick n random elements from an array (without replacement).
|
|
460
|
+
*/
|
|
461
|
+
declare function randomSample<T>(arr: T[], n: number): T[];
|
|
462
|
+
/**
|
|
463
|
+
* Random string of given length (alphanumeric).
|
|
464
|
+
*/
|
|
465
|
+
declare function randomString(length: number): string;
|
|
466
|
+
/**
|
|
467
|
+
* Random hex color.
|
|
468
|
+
*/
|
|
469
|
+
declare function randomColor(): string;
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Tree data structure utilities.
|
|
473
|
+
* @since 0.2.0
|
|
474
|
+
*/
|
|
475
|
+
interface TreeNode {
|
|
476
|
+
id: string | number;
|
|
477
|
+
parentId?: string | number | null;
|
|
478
|
+
children?: TreeNode[];
|
|
479
|
+
[key: string]: unknown;
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Convert a flat array (with id/parentId) to a nested tree.
|
|
483
|
+
* Root nodes are those with parentId === null/undefined or parentId not found.
|
|
484
|
+
*/
|
|
485
|
+
declare function arrayToTree<T extends TreeNode>(items: T[], options?: {
|
|
486
|
+
idKey?: string;
|
|
487
|
+
parentKey?: string;
|
|
488
|
+
childrenKey?: string;
|
|
489
|
+
rootParentId?: string | number | null;
|
|
490
|
+
}): T[];
|
|
491
|
+
/**
|
|
492
|
+
* Flatten a nested tree back to an array.
|
|
493
|
+
*/
|
|
494
|
+
declare function treeToArray<T extends TreeNode>(tree: T[], options?: {
|
|
495
|
+
childrenKey?: string;
|
|
496
|
+
}): T[];
|
|
497
|
+
/**
|
|
498
|
+
* Find a node in a tree by predicate.
|
|
499
|
+
*/
|
|
500
|
+
declare function findInTree<T extends TreeNode>(tree: T[], predicate: (node: T) => boolean, childrenKey?: string): T | undefined;
|
|
501
|
+
/**
|
|
502
|
+
* Get the full path (ancestors) of a node by id.
|
|
503
|
+
*/
|
|
504
|
+
declare function getPathById<T extends TreeNode>(tree: T[], targetId: string | number, idKey?: string, childrenKey?: string): T[];
|
|
505
|
+
/**
|
|
506
|
+
* Get all leaf nodes from a tree.
|
|
507
|
+
*/
|
|
508
|
+
declare function getLeafNodes<T extends TreeNode>(tree: T[], childrenKey?: string): T[];
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Color utility functions.
|
|
512
|
+
* @since 0.2.0
|
|
513
|
+
*/
|
|
514
|
+
interface RGB {
|
|
515
|
+
r: number;
|
|
516
|
+
g: number;
|
|
517
|
+
b: number;
|
|
518
|
+
}
|
|
519
|
+
interface HSL {
|
|
520
|
+
h: number;
|
|
521
|
+
s: number;
|
|
522
|
+
l: number;
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Parse a hex color string to RGB.
|
|
526
|
+
*/
|
|
527
|
+
declare function hexToRgb(hex: string): RGB | null;
|
|
528
|
+
/**
|
|
529
|
+
* Convert RGB to hex string.
|
|
530
|
+
*/
|
|
531
|
+
declare function rgbToHex(r: number, g: number, b: number): string;
|
|
532
|
+
/**
|
|
533
|
+
* Convert RGB to HSL.
|
|
534
|
+
*/
|
|
535
|
+
declare function rgbToHsl({ r, g, b }: RGB): HSL;
|
|
536
|
+
/**
|
|
537
|
+
* Convert HSL to RGB.
|
|
538
|
+
*/
|
|
539
|
+
declare function hslToRgb({ h, s, l }: HSL): RGB;
|
|
540
|
+
/**
|
|
541
|
+
* Calculate relative luminance (WCAG).
|
|
542
|
+
*/
|
|
543
|
+
declare function luminance(hex: string): number;
|
|
544
|
+
/**
|
|
545
|
+
* Calculate contrast ratio between two hex colors (WCAG).
|
|
546
|
+
*/
|
|
547
|
+
declare function contrastRatio(hex1: string, hex2: string): number;
|
|
548
|
+
/**
|
|
549
|
+
* Check if contrast meets WCAG AA (4.5:1 for normal text).
|
|
550
|
+
*/
|
|
551
|
+
declare function meetsWCAGAA(hex1: string, hex2: string): boolean;
|
|
552
|
+
/**
|
|
553
|
+
* Lighten a hex color by percentage (0-100).
|
|
554
|
+
*/
|
|
555
|
+
declare function lighten(hex: string, amount: number): string;
|
|
556
|
+
/**
|
|
557
|
+
* Darken a hex color by percentage (0-100).
|
|
558
|
+
*/
|
|
559
|
+
declare function darken(hex: string, amount: number): string;
|
|
560
|
+
/**
|
|
561
|
+
* Generate a palette of shades from a base color.
|
|
562
|
+
*/
|
|
563
|
+
declare function generatePalette(hex: string, steps?: number): string[];
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Array utility functions.
|
|
567
|
+
* @since 0.2.0
|
|
568
|
+
*/
|
|
569
|
+
/**
|
|
570
|
+
* Group an array by a key or callback.
|
|
571
|
+
*/
|
|
572
|
+
declare function groupBy<T>(arr: T[], key: keyof T | ((item: T) => string | number)): Record<string, T[]>;
|
|
573
|
+
/**
|
|
574
|
+
* Sort an array by a key (stable).
|
|
575
|
+
*/
|
|
576
|
+
declare function sortBy<T>(arr: T[], key: keyof T | ((item: T) => string | number | Date), direction?: "asc" | "desc"): T[];
|
|
577
|
+
/**
|
|
578
|
+
* Remove duplicate items from an array (shallow comparison).
|
|
579
|
+
*/
|
|
580
|
+
declare function unique<T>(arr: T[]): T[];
|
|
581
|
+
/**
|
|
582
|
+
* Remove duplicates by a key or callback.
|
|
583
|
+
*/
|
|
584
|
+
declare function uniqueBy<T>(arr: T[], key: keyof T | ((item: T) => unknown)): T[];
|
|
585
|
+
/**
|
|
586
|
+
* Split an array into chunks of a given size.
|
|
587
|
+
*/
|
|
588
|
+
declare function chunk<T>(arr: T[], size: number): T[][];
|
|
589
|
+
/**
|
|
590
|
+
* Paginate an array (1-indexed page).
|
|
591
|
+
*/
|
|
592
|
+
declare function paginate<T>(arr: T[], page: number, pageSize: number): {
|
|
593
|
+
items: T[];
|
|
594
|
+
total: number;
|
|
595
|
+
totalPages: number;
|
|
596
|
+
page: number;
|
|
597
|
+
};
|
|
598
|
+
/**
|
|
599
|
+
* Count occurrences of each value.
|
|
600
|
+
*/
|
|
601
|
+
declare function countBy<T>(arr: T[], key?: keyof T | ((item: T) => string)): Record<string, number>;
|
|
602
|
+
/**
|
|
603
|
+
* Shuffle an array (Fisher-Yates, returns new array).
|
|
604
|
+
*/
|
|
605
|
+
declare function shuffle<T>(arr: T[]): T[];
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Content Security Policy (CSP) headers for Next.js apps using Chaos UI.
|
|
609
|
+
*
|
|
610
|
+
* Usage in next.config.ts:
|
|
611
|
+
* ```ts
|
|
612
|
+
* import { cspHeaders } from "@chaos_team/chaos-ui/next";
|
|
613
|
+
*
|
|
614
|
+
* export default {
|
|
615
|
+
* async headers() {
|
|
616
|
+
* return [
|
|
617
|
+
* {
|
|
618
|
+
* source: "/(.*)",
|
|
619
|
+
* headers: cspHeaders(),
|
|
620
|
+
* },
|
|
621
|
+
* ];
|
|
622
|
+
* },
|
|
623
|
+
* };
|
|
624
|
+
* ```
|
|
625
|
+
*/
|
|
626
|
+
declare function cspHeaders(): Array<{
|
|
627
|
+
key: string;
|
|
628
|
+
value: string;
|
|
629
|
+
}>;
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* @module crypto
|
|
633
|
+
* @category Utility
|
|
634
|
+
* @since 1.0.0-beta.0
|
|
635
|
+
* @description Cryptographic helpers — non-secret hashing (djb2/fnv1a), Base64/Hex encoding, random id/token generation, and a thin wrapper over the Web Crypto API for HMAC. None of these are for secrets-at-rest; use the Web Crypto `SubtleCrypto` API (exposed via `subtle`) for signed/hashed security-sensitive operations.
|
|
636
|
+
* @example
|
|
637
|
+
* hashString("abc"); // djb2 numeric hash
|
|
638
|
+
* randomId(); // "k3j8a..."
|
|
639
|
+
* toBase64("hello"); // "aGVsbG8="
|
|
640
|
+
*/
|
|
641
|
+
/**
|
|
642
|
+
* djb2 string hash — fast, non-cryptographic. Stable across runs.
|
|
643
|
+
* @returns 32-bit unsigned integer.
|
|
644
|
+
*/
|
|
645
|
+
declare function hashString(input: string): number;
|
|
646
|
+
/** FNV-1a 32-bit hash — alternative non-cryptographic hash. */
|
|
647
|
+
declare function hashFnv1a(input: string): number;
|
|
648
|
+
/** Generate a random id of the given length using a URL-safe alphabet. */
|
|
649
|
+
declare function randomId(length?: number): string;
|
|
650
|
+
/** Generate a random hex token of the given byte length (default 16 bytes → 32 hex chars). */
|
|
651
|
+
declare function randomToken(byteLength?: number): string;
|
|
652
|
+
/** Cryptographically-strong random byte array via Web Crypto (falls back to Math.random). */
|
|
653
|
+
declare function randomBytes(length: number): Uint8Array;
|
|
654
|
+
/** Encode a UTF-8 string to Base64 (browser-safe). */
|
|
655
|
+
declare function toBase64(input: string): string;
|
|
656
|
+
/** Decode a Base64 string to UTF-8. */
|
|
657
|
+
declare function fromBase64(input: string): string;
|
|
658
|
+
/** Encode a byte array / string to lowercase hex. */
|
|
659
|
+
declare function toHex(input: Uint8Array | string): string;
|
|
660
|
+
/** Decode a hex string to a byte array. */
|
|
661
|
+
declare function fromHex(input: string): Uint8Array;
|
|
662
|
+
/** Access to the Web Crypto `SubtleCrypto` API, or `undefined` when unavailable. */
|
|
663
|
+
declare const subtle: SubtleCrypto | undefined;
|
|
664
|
+
/**
|
|
665
|
+
* Backward-compat default export name. Returns the module's helper bag so that
|
|
666
|
+
* `import { crypto } from "@/lib/crypto"` keeps working; it is NOT the global
|
|
667
|
+
* `crypto` (Web Crypto). Prefer the named helpers above.
|
|
668
|
+
*/
|
|
669
|
+
declare function crypto(): {
|
|
670
|
+
hashString: typeof hashString;
|
|
671
|
+
hashFnv1a: typeof hashFnv1a;
|
|
672
|
+
randomId: typeof randomId;
|
|
673
|
+
randomToken: typeof randomToken;
|
|
674
|
+
randomBytes: typeof randomBytes;
|
|
675
|
+
toBase64: typeof toBase64;
|
|
676
|
+
fromBase64: typeof fromBase64;
|
|
677
|
+
toHex: typeof toHex;
|
|
678
|
+
fromHex: typeof fromHex;
|
|
679
|
+
subtle: SubtleCrypto | undefined;
|
|
680
|
+
};
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* @module date
|
|
684
|
+
* @category Utility
|
|
685
|
+
* @since 1.0.0-beta.0
|
|
686
|
+
* @description Date helpers that complement @/lib/format — parsing, comparison, arithmetic, and query predicates. For user-facing formatting use `formatDate`/`formatDateTime` from `@/lib/format`.
|
|
687
|
+
* @example
|
|
688
|
+
* parseDate("2026-06-30"); // Date
|
|
689
|
+
* addDays(new Date(), 7); // Date +7d
|
|
690
|
+
* isSameDay(a, b); // boolean
|
|
691
|
+
* startOfDay(new Date()); // Date at 00:00:00
|
|
692
|
+
*/
|
|
693
|
+
/** Parse a value into a Date, returning `undefined` for invalid input (does not throw). */
|
|
694
|
+
declare function parseDate(value: Date | number | string | undefined | null): Date | undefined;
|
|
695
|
+
/** Returns true if the value is a valid Date. */
|
|
696
|
+
declare function isValidDate(value: unknown): value is Date;
|
|
697
|
+
/** Add a number of units to a date. Returns a new Date. */
|
|
698
|
+
declare function add(date: Date, amount: number, unit?: "year" | "month" | "week" | "day" | "hour" | "minute" | "second"): Date;
|
|
699
|
+
/** Shorthand for add(date, amount, "day"). */
|
|
700
|
+
declare function addDays(date: Date, amount: number): Date;
|
|
701
|
+
/** Difference between two dates in the given unit (truncated, integer). */
|
|
702
|
+
declare function diff(a: Date, b: Date, unit?: "day" | "hour" | "minute" | "second"): number;
|
|
703
|
+
/** Reset a date to 00:00:00.000 local time. */
|
|
704
|
+
declare function startOfDay(date: Date): Date;
|
|
705
|
+
/** Set a date to 23:59:59.999 local time. */
|
|
706
|
+
declare function endOfDay(date: Date): Date;
|
|
707
|
+
/** True if the two dates fall on the same calendar day. */
|
|
708
|
+
declare function isSameDay(a: Date, b: Date): boolean;
|
|
709
|
+
/** True if `date` is today. */
|
|
710
|
+
declare function isToday(date: Date): boolean;
|
|
711
|
+
/** True if `date` is within the current calendar week (Sun–Sat). */
|
|
712
|
+
declare function isThisWeek(date: Date): boolean;
|
|
713
|
+
/** Format a date as an ISO `YYYY-MM-DD` string (local time). */
|
|
714
|
+
declare function toISODate(date: Date): string;
|
|
715
|
+
/** Backward-compat default export name — returns the helper bag. */
|
|
716
|
+
declare function date(): {
|
|
717
|
+
parseDate: typeof parseDate;
|
|
718
|
+
isValidDate: typeof isValidDate;
|
|
719
|
+
add: typeof add;
|
|
720
|
+
addDays: typeof addDays;
|
|
721
|
+
diff: typeof diff;
|
|
722
|
+
startOfDay: typeof startOfDay;
|
|
723
|
+
endOfDay: typeof endOfDay;
|
|
724
|
+
isSameDay: typeof isSameDay;
|
|
725
|
+
isToday: typeof isToday;
|
|
726
|
+
isThisWeek: typeof isThisWeek;
|
|
727
|
+
toISODate: typeof toISODate;
|
|
728
|
+
};
|
|
729
|
+
|
|
730
|
+
/**
|
|
731
|
+
* @module excel
|
|
732
|
+
* @category Utility
|
|
733
|
+
* @since 1.0.0-beta.0
|
|
734
|
+
* @description Spreadsheet helpers — CSV serialize/parse (RFC 4180 compliant) and a minimal XLSX (SpreadsheetML 2003 XML) generator for simple row data. No external dependency; for full XLSX read/write, integrate a peer dep like `exceljs`/`xlsx`.
|
|
735
|
+
* @example
|
|
736
|
+
* toCSV([{a:1,b:"hi"}]); // "a,b\r\n1,hi\r\n"
|
|
737
|
+
* parseCSV("a,b\r\n1,hi\r\n"); // [{a:"1",b:"hi"}]
|
|
738
|
+
*/
|
|
739
|
+
interface CsvOptions {
|
|
740
|
+
delimiter?: string;
|
|
741
|
+
quote?: string;
|
|
742
|
+
newline?: string;
|
|
743
|
+
headers?: string[];
|
|
744
|
+
}
|
|
745
|
+
/** Serialize an array of row objects into a CSV string (BOM-free). */
|
|
746
|
+
declare function toCSV(rows: Record<string, unknown>[], options?: CsvOptions): string;
|
|
747
|
+
/** Parse a CSV string into an array of row objects (first row = headers). */
|
|
748
|
+
declare function parseCSV(text: string, options?: CsvOptions): Record<string, string>[];
|
|
749
|
+
/** A minimal XLSX (SpreadsheetML 2003 XML) string for a single sheet of row data. */
|
|
750
|
+
declare function toSpreadsheetXml(rows: unknown[][], options?: {
|
|
751
|
+
sheetName?: string;
|
|
752
|
+
}): string;
|
|
753
|
+
/** Backward-compat default export name — returns the helper bag. */
|
|
754
|
+
declare function excel(): {
|
|
755
|
+
toCSV: typeof toCSV;
|
|
756
|
+
parseCSV: typeof parseCSV;
|
|
757
|
+
toSpreadsheetXml: typeof toSpreadsheetXml;
|
|
758
|
+
};
|
|
759
|
+
|
|
760
|
+
/**
|
|
761
|
+
* @module pdf
|
|
762
|
+
* @category Utility
|
|
763
|
+
* @since 1.0.0-beta.0
|
|
764
|
+
* @description Minimal PDF helpers — builds a tiny valid single-page PDF document from plain text lines and renders an HTML print view. Not a full PDF engine; for rich layout integrate a peer dep like `pdfmake`/`@react-pdf/renderer`. The generated PDF uses the standard 14 font Helvetica.
|
|
765
|
+
* @example
|
|
766
|
+
* buildPdf("Report", ["Line one", "Line two"]); // ArrayBuffer
|
|
767
|
+
* openPdf(buildPdf(...)); // opens in a new tab
|
|
768
|
+
*/
|
|
769
|
+
/** Build a minimal one-page PDF document from a title and body lines. Returns a Uint8Array. */
|
|
770
|
+
declare function buildPdf(title: string, lines?: string[]): Uint8Array;
|
|
771
|
+
/** Build a PDF and open it in a new browser tab. No-op on the server. */
|
|
772
|
+
declare function openPdf(bytes: Uint8Array): void;
|
|
773
|
+
/** Build a PDF and trigger a download with the given filename. */
|
|
774
|
+
declare function downloadPdf(bytes: Uint8Array, filename: string): void;
|
|
775
|
+
/** Backward-compat default export name — returns the helper bag. */
|
|
776
|
+
declare function pdf(): {
|
|
777
|
+
buildPdf: typeof buildPdf;
|
|
778
|
+
openPdf: typeof openPdf;
|
|
779
|
+
downloadPdf: typeof downloadPdf;
|
|
780
|
+
};
|
|
781
|
+
|
|
782
|
+
/**
|
|
783
|
+
* @module worker
|
|
784
|
+
* @category Utility
|
|
785
|
+
* @since 1.0.0-beta.0
|
|
786
|
+
* @description Web Worker helpers — create a worker from an inline function (no separate file needed), run a function off the main thread with a timeout, and a tiny pool for parallel map. Falls back to running synchronously on the main thread when Workers are unavailable (jsdom/SSR).
|
|
787
|
+
* @example
|
|
788
|
+
* const heavy = (n: number) => n * n;
|
|
789
|
+
* const result = await runInWorker(heavy, 5); // 25
|
|
790
|
+
*/
|
|
791
|
+
/** Create a Web Worker from an inline function. Returns the Worker, or null if unsupported. */
|
|
792
|
+
declare function createWorkerFromFn<T extends (...args: never[]) => unknown>(fn: T): Worker | null;
|
|
793
|
+
/** Run a pure function off the main thread. Falls back to in-thread execution when Workers are unavailable. */
|
|
794
|
+
declare function runInWorker<T extends (...args: never[]) => unknown>(fn: T, args: Parameters<T>, timeout?: number): Promise<ReturnType<T>>;
|
|
795
|
+
/** Run a map over an array with up to `concurrency` workers in parallel. */
|
|
796
|
+
declare function parallelMap<I, O>(items: I[], fn: (item: I, index: number) => O | Promise<O>, concurrency?: number): Promise<O[]>;
|
|
797
|
+
/** Backward-compat default export name — returns the helper bag. */
|
|
798
|
+
declare function worker(): {
|
|
799
|
+
createWorkerFromFn: typeof createWorkerFromFn;
|
|
800
|
+
runInWorker: typeof runInWorker;
|
|
801
|
+
parallelMap: typeof parallelMap;
|
|
802
|
+
};
|
|
803
|
+
|
|
804
|
+
export { type ApiClientConfig, type ApiError, ChaosI18nProvider, type CsvOptions, EventBus, type LogLevel, Modal, type ModalAlertOptions, type ModalConfirmOptions, type ModalKind, type Permission, type Role, type TreeNode, add, addDays, arrayToTree, buildPdf, chunk, cn, contrastRatio, cookie, countBy, createWorkerFromFn, crypto, cspHeaders, darken, date, diff, download, downloadPdf, endOfDay, eventBus, excel, findInTree, fromBase64, fromHex, generatePalette, getApiClient, getLeafNodes, getPathById, groupBy, hasAllPermissions, hasAnyPermission, hasPermission, hashFnv1a, hashString, hexToRgb, hslToRgb, isSameDay, isThisWeek, isToday, isValidDate, lighten, logger, luminance, meetsWCAGAA, openPdf, paginate, parallelMap, parseCSV, parseDate, patterns, pdf, randomBytes, randomColor, randomFloat, randomId, randomInt, randomPick, randomSample, randomString, randomToken, rgbToHex, rgbToHsl, runInWorker, safeRequest, sessionStorage, shuffle, sortBy, startOfDay, storage, subtle, toBase64, toCSV, toHex, toISODate, toSpreadsheetXml, treeToArray, unique, uniqueBy, uniqueSequence, url, uuid, validators, worker };
|