@gzl10/ts-helpers 4.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +320 -0
- package/README.md +233 -0
- package/USAGE-GUIDE.md +800 -0
- package/dist/browser/async.js +15 -0
- package/dist/browser/async.js.map +1 -0
- package/dist/browser/chunk-4O7ZPIJN.js +383 -0
- package/dist/browser/chunk-4O7ZPIJN.js.map +1 -0
- package/dist/browser/chunk-75XNTC34.js +60 -0
- package/dist/browser/chunk-75XNTC34.js.map +1 -0
- package/dist/browser/chunk-C3D7YZVE.js +299 -0
- package/dist/browser/chunk-C3D7YZVE.js.map +1 -0
- package/dist/browser/chunk-CZL6C2EI.js +452 -0
- package/dist/browser/chunk-CZL6C2EI.js.map +1 -0
- package/dist/browser/chunk-D4FZFIVA.js +240 -0
- package/dist/browser/chunk-D4FZFIVA.js.map +1 -0
- package/dist/browser/chunk-IL7NG7IC.js +72 -0
- package/dist/browser/chunk-IL7NG7IC.js.map +1 -0
- package/dist/browser/chunk-NSBPE2FW.js +17 -0
- package/dist/browser/chunk-NSBPE2FW.js.map +1 -0
- package/dist/browser/chunk-SLQVNPTH.js +27 -0
- package/dist/browser/chunk-SLQVNPTH.js.map +1 -0
- package/dist/browser/chunk-WG7ILCUB.js +195 -0
- package/dist/browser/chunk-WG7ILCUB.js.map +1 -0
- package/dist/browser/chunk-WJA4JDMZ.js +278 -0
- package/dist/browser/chunk-WJA4JDMZ.js.map +1 -0
- package/dist/browser/chunk-ZFVYLUTT.js +65 -0
- package/dist/browser/chunk-ZFVYLUTT.js.map +1 -0
- package/dist/browser/chunk-ZYTSVMTI.js +263 -0
- package/dist/browser/chunk-ZYTSVMTI.js.map +1 -0
- package/dist/browser/dates.js +78 -0
- package/dist/browser/dates.js.map +1 -0
- package/dist/browser/environment-detection.js +21 -0
- package/dist/browser/environment-detection.js.map +1 -0
- package/dist/browser/environment.js +34 -0
- package/dist/browser/environment.js.map +1 -0
- package/dist/browser/errors.js +18 -0
- package/dist/browser/errors.js.map +1 -0
- package/dist/browser/index.js +412 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/math.js +51 -0
- package/dist/browser/math.js.map +1 -0
- package/dist/browser/number.js +10 -0
- package/dist/browser/number.js.map +1 -0
- package/dist/browser/objects.js +31 -0
- package/dist/browser/objects.js.map +1 -0
- package/dist/browser/strings.js +80 -0
- package/dist/browser/strings.js.map +1 -0
- package/dist/browser/validation-core.js +54 -0
- package/dist/browser/validation-core.js.map +1 -0
- package/dist/browser/validation-crypto.js +28 -0
- package/dist/browser/validation-crypto.js.map +1 -0
- package/dist/browser/validators.js +98 -0
- package/dist/browser/validators.js.map +1 -0
- package/dist/cjs/async.js +86 -0
- package/dist/cjs/async.js.map +1 -0
- package/dist/cjs/dates.js +285 -0
- package/dist/cjs/dates.js.map +1 -0
- package/dist/cjs/environment-detection.js +84 -0
- package/dist/cjs/environment-detection.js.map +1 -0
- package/dist/cjs/environment.js +261 -0
- package/dist/cjs/environment.js.map +1 -0
- package/dist/cjs/errors.js +80 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/index.js +2035 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/math.js +388 -0
- package/dist/cjs/math.js.map +1 -0
- package/dist/cjs/number.js +37 -0
- package/dist/cjs/number.js.map +1 -0
- package/dist/cjs/objects.js +249 -0
- package/dist/cjs/objects.js.map +1 -0
- package/dist/cjs/strings.js +253 -0
- package/dist/cjs/strings.js.map +1 -0
- package/dist/cjs/validation.js +450 -0
- package/dist/cjs/validation.js.map +1 -0
- package/dist/esm/async.js +15 -0
- package/dist/esm/async.js.map +1 -0
- package/dist/esm/chunk-4O7ZPIJN.js +383 -0
- package/dist/esm/chunk-4O7ZPIJN.js.map +1 -0
- package/dist/esm/chunk-75XNTC34.js +60 -0
- package/dist/esm/chunk-75XNTC34.js.map +1 -0
- package/dist/esm/chunk-BDOBKBKA.js +72 -0
- package/dist/esm/chunk-BDOBKBKA.js.map +1 -0
- package/dist/esm/chunk-C3D7YZVE.js +299 -0
- package/dist/esm/chunk-C3D7YZVE.js.map +1 -0
- package/dist/esm/chunk-CZL6C2EI.js +452 -0
- package/dist/esm/chunk-CZL6C2EI.js.map +1 -0
- package/dist/esm/chunk-EBLSTOEC.js +263 -0
- package/dist/esm/chunk-EBLSTOEC.js.map +1 -0
- package/dist/esm/chunk-NSBPE2FW.js +17 -0
- package/dist/esm/chunk-NSBPE2FW.js.map +1 -0
- package/dist/esm/chunk-SLQVNPTH.js +27 -0
- package/dist/esm/chunk-SLQVNPTH.js.map +1 -0
- package/dist/esm/chunk-WG7ILCUB.js +195 -0
- package/dist/esm/chunk-WG7ILCUB.js.map +1 -0
- package/dist/esm/chunk-WJA4JDMZ.js +278 -0
- package/dist/esm/chunk-WJA4JDMZ.js.map +1 -0
- package/dist/esm/chunk-ZFVYLUTT.js +65 -0
- package/dist/esm/chunk-ZFVYLUTT.js.map +1 -0
- package/dist/esm/dates.js +78 -0
- package/dist/esm/dates.js.map +1 -0
- package/dist/esm/environment-detection.js +21 -0
- package/dist/esm/environment-detection.js.map +1 -0
- package/dist/esm/environment.js +34 -0
- package/dist/esm/environment.js.map +1 -0
- package/dist/esm/errors.js +18 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/index.js +380 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/math.js +51 -0
- package/dist/esm/math.js.map +1 -0
- package/dist/esm/number.js +10 -0
- package/dist/esm/number.js.map +1 -0
- package/dist/esm/objects.js +31 -0
- package/dist/esm/objects.js.map +1 -0
- package/dist/esm/strings.js +80 -0
- package/dist/esm/strings.js.map +1 -0
- package/dist/esm/validation.js +54 -0
- package/dist/esm/validation.js.map +1 -0
- package/dist/node/async.js +93 -0
- package/dist/node/async.js.map +1 -0
- package/dist/node/csv.js +102 -0
- package/dist/node/csv.js.map +1 -0
- package/dist/node/data.js +880 -0
- package/dist/node/data.js.map +1 -0
- package/dist/node/dates.js +324 -0
- package/dist/node/dates.js.map +1 -0
- package/dist/node/environment.js +278 -0
- package/dist/node/environment.js.map +1 -0
- package/dist/node/errors.js +89 -0
- package/dist/node/errors.js.map +1 -0
- package/dist/node/index.js +3151 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/json.js +107 -0
- package/dist/node/json.js.map +1 -0
- package/dist/node/math.js +413 -0
- package/dist/node/math.js.map +1 -0
- package/dist/node/number.js +42 -0
- package/dist/node/number.js.map +1 -0
- package/dist/node/objects.js +264 -0
- package/dist/node/objects.js.map +1 -0
- package/dist/node/strings.js +293 -0
- package/dist/node/strings.js.map +1 -0
- package/dist/node/tree.js +89 -0
- package/dist/node/tree.js.map +1 -0
- package/dist/node/validation-core.js +477 -0
- package/dist/node/validation-core.js.map +1 -0
- package/dist/node/validation-crypto.js +179 -0
- package/dist/node/validation-crypto.js.map +1 -0
- package/dist/node/validation.js +677 -0
- package/dist/node/validation.js.map +1 -0
- package/dist/node/validators.js +123 -0
- package/dist/node/validators.js.map +1 -0
- package/dist/node-esm/async.js +15 -0
- package/dist/node-esm/async.js.map +1 -0
- package/dist/node-esm/chunk-3YOF7NPT.js +299 -0
- package/dist/node-esm/chunk-3YOF7NPT.js.map +1 -0
- package/dist/node-esm/chunk-64TBXJQS.js +263 -0
- package/dist/node-esm/chunk-64TBXJQS.js.map +1 -0
- package/dist/node-esm/chunk-75XNTC34.js +60 -0
- package/dist/node-esm/chunk-75XNTC34.js.map +1 -0
- package/dist/node-esm/chunk-C4PKXIPB.js +278 -0
- package/dist/node-esm/chunk-C4PKXIPB.js.map +1 -0
- package/dist/node-esm/chunk-CMDFZME3.js +452 -0
- package/dist/node-esm/chunk-CMDFZME3.js.map +1 -0
- package/dist/node-esm/chunk-DZZPUYMP.js +74 -0
- package/dist/node-esm/chunk-DZZPUYMP.js.map +1 -0
- package/dist/node-esm/chunk-HTSEHRHI.js +195 -0
- package/dist/node-esm/chunk-HTSEHRHI.js.map +1 -0
- package/dist/node-esm/chunk-JCAUVOPH.js +27 -0
- package/dist/node-esm/chunk-JCAUVOPH.js.map +1 -0
- package/dist/node-esm/chunk-KBHE3K2F.js +505 -0
- package/dist/node-esm/chunk-KBHE3K2F.js.map +1 -0
- package/dist/node-esm/chunk-LYTET5NX.js +65 -0
- package/dist/node-esm/chunk-LYTET5NX.js.map +1 -0
- package/dist/node-esm/chunk-PZ5AY32C.js +10 -0
- package/dist/node-esm/chunk-PZ5AY32C.js.map +1 -0
- package/dist/node-esm/chunk-UKGXL2QO.js +383 -0
- package/dist/node-esm/chunk-UKGXL2QO.js.map +1 -0
- package/dist/node-esm/chunk-XAEYT23H.js +164 -0
- package/dist/node-esm/chunk-XAEYT23H.js.map +1 -0
- package/dist/node-esm/csv.js +63 -0
- package/dist/node-esm/csv.js.map +1 -0
- package/dist/node-esm/data.js +32 -0
- package/dist/node-esm/data.js.map +1 -0
- package/dist/node-esm/dates.js +78 -0
- package/dist/node-esm/dates.js.map +1 -0
- package/dist/node-esm/environment.js +34 -0
- package/dist/node-esm/environment.js.map +1 -0
- package/dist/node-esm/errors.js +18 -0
- package/dist/node-esm/errors.js.map +1 -0
- package/dist/node-esm/index.js +426 -0
- package/dist/node-esm/index.js.map +1 -0
- package/dist/node-esm/json.js +68 -0
- package/dist/node-esm/json.js.map +1 -0
- package/dist/node-esm/math.js +51 -0
- package/dist/node-esm/math.js.map +1 -0
- package/dist/node-esm/number.js +10 -0
- package/dist/node-esm/number.js.map +1 -0
- package/dist/node-esm/objects.js +31 -0
- package/dist/node-esm/objects.js.map +1 -0
- package/dist/node-esm/strings.js +80 -0
- package/dist/node-esm/strings.js.map +1 -0
- package/dist/node-esm/tree.js +8 -0
- package/dist/node-esm/tree.js.map +1 -0
- package/dist/node-esm/validation-core.js +54 -0
- package/dist/node-esm/validation-core.js.map +1 -0
- package/dist/node-esm/validation-crypto.js +26 -0
- package/dist/node-esm/validation-crypto.js.map +1 -0
- package/dist/node-esm/validation.js +606 -0
- package/dist/node-esm/validation.js.map +1 -0
- package/dist/node-esm/validators.js +98 -0
- package/dist/node-esm/validators.js.map +1 -0
- package/dist/types/async-C8gvbSG-.d.ts +453 -0
- package/dist/types/async.d.ts +1 -0
- package/dist/types/csv.d.ts +226 -0
- package/dist/types/data.d.ts +1561 -0
- package/dist/types/dates-hTiE0Z11.d.ts +298 -0
- package/dist/types/dates.d.ts +1 -0
- package/dist/types/environment-B8eLS7KT.d.ts +420 -0
- package/dist/types/environment-detection.d.ts +102 -0
- package/dist/types/environment.d.ts +1 -0
- package/dist/types/errors.d.ts +147 -0
- package/dist/types/index.d.ts +211 -0
- package/dist/types/json.d.ts +284 -0
- package/dist/types/math-BQ9Lwdp7.d.ts +2060 -0
- package/dist/types/math.d.ts +1 -0
- package/dist/types/number-CYnQfLWj.d.ts +44 -0
- package/dist/types/number.d.ts +1 -0
- package/dist/types/objects-BohS8GCS.d.ts +1185 -0
- package/dist/types/objects.d.ts +1 -0
- package/dist/types/strings-CiqRPYLL.d.ts +1349 -0
- package/dist/types/strings.d.ts +1 -0
- package/dist/types/tree.d.ts +284 -0
- package/dist/types/validation-core-DfHF8rCG.d.ts +238 -0
- package/dist/types/validation-crypto-browser.d.ts +56 -0
- package/dist/types/validation-crypto-node.d.ts +31 -0
- package/dist/types/validation.d.ts +1 -0
- package/dist/types/validators.d.ts +216 -0
- package/package.json +253 -0
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asynchronous utilities and operations
|
|
3
|
+
* Consolidated from core/async module
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Creates an asynchronous delay for the specified number of milliseconds
|
|
7
|
+
*
|
|
8
|
+
* Pauses async execution without blocking the event loop. Uses Promise with setTimeout
|
|
9
|
+
* internally to schedule resumption after the specified delay.
|
|
10
|
+
*
|
|
11
|
+
* Common use cases:
|
|
12
|
+
* - Rate limiting API calls
|
|
13
|
+
* - Retry delays with exponential backoff
|
|
14
|
+
* - Animation/transition timing
|
|
15
|
+
* - Polling intervals
|
|
16
|
+
* - Debouncing operations
|
|
17
|
+
*
|
|
18
|
+
* @param ms - Milliseconds to sleep (delay duration)
|
|
19
|
+
* @returns Promise that resolves after the specified delay
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* // Basic delay
|
|
24
|
+
* console.log('Starting...')
|
|
25
|
+
* await sleep(2000) // Wait 2 seconds
|
|
26
|
+
* console.log('Done!')
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* // Real-world: Rate-limited API calls
|
|
32
|
+
* async function fetchAllUsers(userIds: string[]): Promise<User[]> {
|
|
33
|
+
* const users: User[] = []
|
|
34
|
+
*
|
|
35
|
+
* for (const id of userIds) {
|
|
36
|
+
* const user = await api.getUser(id)
|
|
37
|
+
* users.push(user)
|
|
38
|
+
*
|
|
39
|
+
* // Rate limit: 100ms between requests (max 10 req/sec)
|
|
40
|
+
* await sleep(100)
|
|
41
|
+
* }
|
|
42
|
+
*
|
|
43
|
+
* return users
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* // Real-world: Exponential backoff retry
|
|
50
|
+
* async function fetchWithRetry(url: string, maxRetries = 3): Promise<Response> {
|
|
51
|
+
* let lastError: Error | null = null
|
|
52
|
+
*
|
|
53
|
+
* for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
54
|
+
* try {
|
|
55
|
+
* return await fetch(url)
|
|
56
|
+
* } catch (error) {
|
|
57
|
+
* lastError = error as Error
|
|
58
|
+
* const delay = Math.pow(2, attempt) * 1000 // 1s, 2s, 4s
|
|
59
|
+
* console.log(`Retry ${attempt + 1}/${maxRetries} in ${delay}ms`)
|
|
60
|
+
* await sleep(delay)
|
|
61
|
+
* }
|
|
62
|
+
* }
|
|
63
|
+
*
|
|
64
|
+
* throw lastError
|
|
65
|
+
* }
|
|
66
|
+
* ```
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* // Real-world: Polling with timeout
|
|
71
|
+
* async function pollUntilReady(
|
|
72
|
+
* checkFn: () => Promise<boolean>,
|
|
73
|
+
* timeoutMs = 30000
|
|
74
|
+
* ): Promise<boolean> {
|
|
75
|
+
* const startTime = Date.now()
|
|
76
|
+
*
|
|
77
|
+
* while (Date.now() - startTime < timeoutMs) {
|
|
78
|
+
* if (await checkFn()) {
|
|
79
|
+
* return true
|
|
80
|
+
* }
|
|
81
|
+
* await sleep(1000) // Poll every second
|
|
82
|
+
* }
|
|
83
|
+
*
|
|
84
|
+
* throw new Error('Timeout waiting for ready state')
|
|
85
|
+
* }
|
|
86
|
+
*
|
|
87
|
+
* // Usage: Wait for service to be ready
|
|
88
|
+
* await pollUntilReady(async () => {
|
|
89
|
+
* const response = await fetch('/health')
|
|
90
|
+
* return response.ok
|
|
91
|
+
* })
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* // Real-world: Animated progress bar
|
|
97
|
+
* async function animateProgress(element: HTMLElement): Promise<void> {
|
|
98
|
+
* for (let i = 0; i <= 100; i += 5) {
|
|
99
|
+
* element.style.width = `${i}%`
|
|
100
|
+
* await sleep(50) // 50ms per step = 1 second total
|
|
101
|
+
* }
|
|
102
|
+
* }
|
|
103
|
+
* ```
|
|
104
|
+
*
|
|
105
|
+
* @see {@link wait} for alias with same functionality
|
|
106
|
+
* @see {@link runBatch} for controlled concurrent execution
|
|
107
|
+
*/
|
|
108
|
+
declare const sleep: (ms: number) => Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* Simple alias for sleep - Pauses execution for specified milliseconds
|
|
111
|
+
*
|
|
112
|
+
* Identical to {@link sleep}, provided for semantic clarity in code.
|
|
113
|
+
* Use `wait` when the context emphasizes waiting for a condition or event.
|
|
114
|
+
*
|
|
115
|
+
* @param ms - Milliseconds to wait
|
|
116
|
+
* @returns Promise that resolves after the specified delay
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```typescript
|
|
120
|
+
* // Semantically clearer in some contexts
|
|
121
|
+
* await wait(1000) // Wait 1 second before continuing
|
|
122
|
+
*
|
|
123
|
+
* // vs sleep (implies intentional delay)
|
|
124
|
+
* await sleep(1000) // Sleep for 1 second
|
|
125
|
+
* ```
|
|
126
|
+
*
|
|
127
|
+
* @see {@link sleep} for full documentation and examples
|
|
128
|
+
*/
|
|
129
|
+
declare const wait: (ms: number) => Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Executes an array of Promises in batches to control concurrency
|
|
132
|
+
*
|
|
133
|
+
* Processes promises in sequential batches, waiting for each batch to complete before
|
|
134
|
+
* starting the next. Prevents overwhelming systems with too many concurrent requests.
|
|
135
|
+
*
|
|
136
|
+
* Algorithm:
|
|
137
|
+
* 1. Divide promises into batches of size `batchSize`
|
|
138
|
+
* 2. Execute each batch with Promise.all (parallel within batch)
|
|
139
|
+
* 3. Wait for batch completion before starting next batch
|
|
140
|
+
* 4. Collect and return all results in original order
|
|
141
|
+
*
|
|
142
|
+
* Use cases:
|
|
143
|
+
* - Rate-limited API calls (respect API quotas)
|
|
144
|
+
* - Database bulk operations (avoid connection pool exhaustion)
|
|
145
|
+
* - File system operations (prevent file descriptor limits)
|
|
146
|
+
* - Memory-intensive operations (control memory usage)
|
|
147
|
+
*
|
|
148
|
+
* @param jobs - Array of Promises to execute
|
|
149
|
+
* @param batchSize - Number of promises to execute concurrently per batch (default: 50)
|
|
150
|
+
* @returns Promise resolving to array of all results in original order
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```typescript
|
|
154
|
+
* // Basic batch processing
|
|
155
|
+
* const urls = ['url1', 'url2', ..., 'url100'] // 100 URLs
|
|
156
|
+
* const fetchPromises = urls.map(url => fetch(url))
|
|
157
|
+
*
|
|
158
|
+
* // Execute 10 at a time instead of all 100 simultaneously
|
|
159
|
+
* const responses = await runBatch(fetchPromises, 10)
|
|
160
|
+
* // Batch 1: urls 0-9 (parallel)
|
|
161
|
+
* // Batch 2: urls 10-19 (parallel) - starts after batch 1 completes
|
|
162
|
+
* // ... 10 batches total
|
|
163
|
+
* ```
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```typescript
|
|
167
|
+
* // Real-world: Bulk user data fetch respecting API rate limits
|
|
168
|
+
* async function fetchUsersInBatches(userIds: string[]): Promise<User[]> {
|
|
169
|
+
* console.log(`Fetching ${userIds.length} users in batches of 20...`)
|
|
170
|
+
*
|
|
171
|
+
* const fetchPromises = userIds.map(id =>
|
|
172
|
+
* fetch(`/api/users/${id}`).then(res => res.json())
|
|
173
|
+
* )
|
|
174
|
+
*
|
|
175
|
+
* const users = await runBatch(fetchPromises, 20)
|
|
176
|
+
*
|
|
177
|
+
* console.log(`✅ Fetched ${users.length} users`)
|
|
178
|
+
* return users
|
|
179
|
+
* }
|
|
180
|
+
*
|
|
181
|
+
* // Fetches 1000 users: 50 batches of 20, not 1000 simultaneous requests
|
|
182
|
+
* const allUsers = await fetchUsersInBatches(userIdArray)
|
|
183
|
+
* ```
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```typescript
|
|
187
|
+
* // Real-world: Database bulk insert with connection pool limits
|
|
188
|
+
* async function bulkInsertUsers(users: User[]): Promise<void> {
|
|
189
|
+
* // Database pool has 10 connections, use batch size of 5 for safety
|
|
190
|
+
* const insertPromises = users.map(user =>
|
|
191
|
+
* db.query('INSERT INTO users VALUES ($1, $2)', [user.name, user.email])
|
|
192
|
+
* )
|
|
193
|
+
*
|
|
194
|
+
* await runBatch(insertPromises, 5)
|
|
195
|
+
* console.log(`✅ Inserted ${users.length} users`)
|
|
196
|
+
* }
|
|
197
|
+
* ```
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```typescript
|
|
201
|
+
* // Real-world: Image processing pipeline
|
|
202
|
+
* async function processImages(imagePaths: string[]): Promise<Buffer[]> {
|
|
203
|
+
* console.log(`Processing ${imagePaths.length} images...`)
|
|
204
|
+
*
|
|
205
|
+
* const processingPromises = imagePaths.map(async path => {
|
|
206
|
+
* const img = await loadImage(path)
|
|
207
|
+
* const resized = await resize(img, { width: 800, height: 600 })
|
|
208
|
+
* const compressed = await compress(resized, { quality: 80 })
|
|
209
|
+
* return compressed
|
|
210
|
+
* })
|
|
211
|
+
*
|
|
212
|
+
* // Process 3 images at a time to avoid memory exhaustion
|
|
213
|
+
* const processed = await runBatch(processingPromises, 3)
|
|
214
|
+
*
|
|
215
|
+
* console.log(`✅ Processed ${processed.length} images`)
|
|
216
|
+
* return processed
|
|
217
|
+
* }
|
|
218
|
+
* ```
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* ```typescript
|
|
222
|
+
* // Real-world: Parallel file uploads with progress tracking
|
|
223
|
+
* async function uploadFilesWithProgress(
|
|
224
|
+
* files: File[]
|
|
225
|
+
* ): Promise<UploadResult[]> {
|
|
226
|
+
* let completed = 0
|
|
227
|
+
*
|
|
228
|
+
* const uploadPromises = files.map(async file => {
|
|
229
|
+
* const result = await uploadToS3(file)
|
|
230
|
+
* completed++
|
|
231
|
+
* console.log(`Progress: ${completed}/${files.length} (${((completed/files.length)*100).toFixed(1)}%)`)
|
|
232
|
+
* return result
|
|
233
|
+
* })
|
|
234
|
+
*
|
|
235
|
+
* // Upload 5 files at a time
|
|
236
|
+
* return await runBatch(uploadPromises, 5)
|
|
237
|
+
* }
|
|
238
|
+
* ```
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```typescript
|
|
242
|
+
* // Real-world: Scraping with politeness delay
|
|
243
|
+
* async function scrapeWebsites(urls: string[]): Promise<ScrapedData[]> {
|
|
244
|
+
* const scrapePromises = urls.map(async url => {
|
|
245
|
+
* const html = await fetch(url).then(r => r.text())
|
|
246
|
+
* const data = parseHTML(html)
|
|
247
|
+
*
|
|
248
|
+
* // Polite delay between requests in same batch
|
|
249
|
+
* await sleep(200)
|
|
250
|
+
*
|
|
251
|
+
* return data
|
|
252
|
+
* })
|
|
253
|
+
*
|
|
254
|
+
* // Only 3 concurrent requests to avoid overwhelming target server
|
|
255
|
+
* return await runBatch(scrapePromises, 3)
|
|
256
|
+
* }
|
|
257
|
+
* ```
|
|
258
|
+
*
|
|
259
|
+
* @see {@link sleep} for adding delays between operations
|
|
260
|
+
* @see {@link handleOperation} for dynamic operation execution
|
|
261
|
+
*/
|
|
262
|
+
declare function runBatch<T>(jobs: Promise<T>[], batchSize?: number): Promise<T[]>;
|
|
263
|
+
/**
|
|
264
|
+
* Dynamically executes an operation on a target object by name
|
|
265
|
+
*
|
|
266
|
+
* Invokes methods on objects using string-based operation names. Supports nested
|
|
267
|
+
* method access using 'parent/child' slash notation for organized operation namespacing.
|
|
268
|
+
*
|
|
269
|
+
* Features:
|
|
270
|
+
* - Dynamic method invocation by string name
|
|
271
|
+
* - Nested method access with '/' separator (e.g., 'api/getUser')
|
|
272
|
+
* - Automatic error handling with descriptive messages
|
|
273
|
+
* - Type-safe return value with generics
|
|
274
|
+
*
|
|
275
|
+
* Use cases:
|
|
276
|
+
* - Dynamic API route handlers
|
|
277
|
+
* - Plugin architectures with string-based commands
|
|
278
|
+
* - RPC (Remote Procedure Call) implementations
|
|
279
|
+
* - Command pattern implementations
|
|
280
|
+
* - Configuration-driven operations
|
|
281
|
+
*
|
|
282
|
+
* @param target - Object containing methods to execute
|
|
283
|
+
* @param operation - Method name or 'parent/child' path to execute
|
|
284
|
+
* @param args - Arguments to pass to the operation
|
|
285
|
+
* @returns Promise resolving to operation result
|
|
286
|
+
* @throws {TsHelpersError} If operation doesn't exist on target
|
|
287
|
+
*
|
|
288
|
+
* @example
|
|
289
|
+
* ```typescript
|
|
290
|
+
* // Basic operation execution
|
|
291
|
+
* const api = {
|
|
292
|
+
* getUser: async (id: string) => ({ id, name: 'John' }),
|
|
293
|
+
* createUser: async (data: any) => ({ id: '123', ...data })
|
|
294
|
+
* }
|
|
295
|
+
*
|
|
296
|
+
* const user = await handleOperation<User>(api, 'getUser', 'user-123')
|
|
297
|
+
* // { id: 'user-123', name: 'John' }
|
|
298
|
+
* ```
|
|
299
|
+
*
|
|
300
|
+
* @example
|
|
301
|
+
* ```typescript
|
|
302
|
+
* // Nested operations with slash notation
|
|
303
|
+
* const service = {
|
|
304
|
+
* users: {
|
|
305
|
+
* list: async () => [{ id: '1' }, { id: '2' }],
|
|
306
|
+
* create: async (data: any) => ({ id: 'new', ...data }),
|
|
307
|
+
* delete: async (id: string) => ({ success: true })
|
|
308
|
+
* },
|
|
309
|
+
* posts: {
|
|
310
|
+
* list: async () => [{ id: 'post-1' }],
|
|
311
|
+
* create: async (data: any) => ({ id: 'new-post', ...data })
|
|
312
|
+
* }
|
|
313
|
+
* }
|
|
314
|
+
*
|
|
315
|
+
* // Execute nested operation
|
|
316
|
+
* const users = await handleOperation(service, 'users/list')
|
|
317
|
+
* const newUser = await handleOperation(service, 'users/create', { name: 'Alice' })
|
|
318
|
+
* ```
|
|
319
|
+
*
|
|
320
|
+
* @example
|
|
321
|
+
* ```typescript
|
|
322
|
+
* // Real-world: Dynamic API router
|
|
323
|
+
* interface ApiRequest {
|
|
324
|
+
* operation: string
|
|
325
|
+
* params: any[]
|
|
326
|
+
* }
|
|
327
|
+
*
|
|
328
|
+
* const apiHandlers = {
|
|
329
|
+
* user: {
|
|
330
|
+
* get: async (id: string) => db.users.findById(id),
|
|
331
|
+
* create: async (data: UserInput) => db.users.create(data),
|
|
332
|
+
* update: async (id: string, data: Partial<UserInput>) =>
|
|
333
|
+
* db.users.update(id, data),
|
|
334
|
+
* delete: async (id: string) => db.users.delete(id)
|
|
335
|
+
* },
|
|
336
|
+
* product: {
|
|
337
|
+
* search: async (query: string) => db.products.search(query),
|
|
338
|
+
* list: async (page: number) => db.products.list(page)
|
|
339
|
+
* }
|
|
340
|
+
* }
|
|
341
|
+
*
|
|
342
|
+
* async function handleApiRequest(req: ApiRequest): Promise<any> {
|
|
343
|
+
* try {
|
|
344
|
+
* return await handleOperation(
|
|
345
|
+
* apiHandlers,
|
|
346
|
+
* req.operation,
|
|
347
|
+
* ...req.params
|
|
348
|
+
* )
|
|
349
|
+
* } catch (error) {
|
|
350
|
+
* console.error(`Failed to execute ${req.operation}:`, error)
|
|
351
|
+
* throw error
|
|
352
|
+
* }
|
|
353
|
+
* }
|
|
354
|
+
*
|
|
355
|
+
* // Usage
|
|
356
|
+
* await handleApiRequest({ operation: 'user/get', params: ['user-123'] })
|
|
357
|
+
* await handleApiRequest({ operation: 'product/search', params: ['laptop'] })
|
|
358
|
+
* ```
|
|
359
|
+
*
|
|
360
|
+
* @example
|
|
361
|
+
* ```typescript
|
|
362
|
+
* // Real-world: Plugin system with dynamic commands
|
|
363
|
+
* interface Plugin {
|
|
364
|
+
* name: string
|
|
365
|
+
* commands: Record<string, (...args: any[]) => Promise<any>>
|
|
366
|
+
* }
|
|
367
|
+
*
|
|
368
|
+
* class PluginManager {
|
|
369
|
+
* private plugins: Map<string, Plugin> = new Map()
|
|
370
|
+
*
|
|
371
|
+
* register(plugin: Plugin): void {
|
|
372
|
+
* this.plugins.set(plugin.name, plugin)
|
|
373
|
+
* }
|
|
374
|
+
*
|
|
375
|
+
* async executeCommand(
|
|
376
|
+
* pluginName: string,
|
|
377
|
+
* command: string,
|
|
378
|
+
* ...args: any[]
|
|
379
|
+
* ): Promise<any> {
|
|
380
|
+
* const plugin = this.plugins.get(pluginName)
|
|
381
|
+
* if (!plugin) throw new Error(`Plugin ${pluginName} not found`)
|
|
382
|
+
*
|
|
383
|
+
* return handleOperation(plugin.commands, command, ...args)
|
|
384
|
+
* }
|
|
385
|
+
* }
|
|
386
|
+
*
|
|
387
|
+
* // Register plugins
|
|
388
|
+
* const manager = new PluginManager()
|
|
389
|
+
* manager.register({
|
|
390
|
+
* name: 'fileOps',
|
|
391
|
+
* commands: {
|
|
392
|
+
* read: async (path: string) => fs.readFile(path, 'utf-8'),
|
|
393
|
+
* write: async (path: string, content: string) =>
|
|
394
|
+
* fs.writeFile(path, content)
|
|
395
|
+
* }
|
|
396
|
+
* })
|
|
397
|
+
*
|
|
398
|
+
* // Execute plugin commands dynamically
|
|
399
|
+
* await manager.executeCommand('fileOps', 'read', './config.json')
|
|
400
|
+
* ```
|
|
401
|
+
*
|
|
402
|
+
* @example
|
|
403
|
+
* ```typescript
|
|
404
|
+
* // Real-world: RPC-style service calls
|
|
405
|
+
* const rpcService = {
|
|
406
|
+
* math: {
|
|
407
|
+
* add: async (a: number, b: number) => a + b,
|
|
408
|
+
* multiply: async (a: number, b: number) => a * b
|
|
409
|
+
* },
|
|
410
|
+
* string: {
|
|
411
|
+
* reverse: async (s: string) => s.split('').reverse().join(''),
|
|
412
|
+
* uppercase: async (s: string) => s.toUpperCase()
|
|
413
|
+
* }
|
|
414
|
+
* }
|
|
415
|
+
*
|
|
416
|
+
* async function rpcCall(method: string, ...params: any[]): Promise<any> {
|
|
417
|
+
* console.log(`RPC Call: ${method}(${params.join(', ')})`)
|
|
418
|
+
* const result = await handleOperation(rpcService, method, ...params)
|
|
419
|
+
* console.log(`RPC Result: ${result}`)
|
|
420
|
+
* return result
|
|
421
|
+
* }
|
|
422
|
+
*
|
|
423
|
+
* await rpcCall('math/add', 5, 3) // RPC Result: 8
|
|
424
|
+
* await rpcCall('string/reverse', 'hello') // RPC Result: olleh
|
|
425
|
+
* ```
|
|
426
|
+
*
|
|
427
|
+
* @example
|
|
428
|
+
* ```typescript
|
|
429
|
+
* // Error handling
|
|
430
|
+
* try {
|
|
431
|
+
* await handleOperation(api, 'nonexistent/method')
|
|
432
|
+
* } catch (error) {
|
|
433
|
+
* console.error(error.message)
|
|
434
|
+
* // "Operation [nonexistent/method] does not exist"
|
|
435
|
+
* console.error(error.code)
|
|
436
|
+
* // TsHelpersErrorCode.INVALID_OPERATION
|
|
437
|
+
* }
|
|
438
|
+
* ```
|
|
439
|
+
*
|
|
440
|
+
* @see {@link TsHelpersError} for error structure
|
|
441
|
+
* @see {@link TsHelpersErrorCode} for error codes
|
|
442
|
+
*/
|
|
443
|
+
declare function handleOperation<T>(target: Record<string, any>, operation: string, ...args: any[]): Promise<T>;
|
|
444
|
+
|
|
445
|
+
declare const async_handleOperation: typeof handleOperation;
|
|
446
|
+
declare const async_runBatch: typeof runBatch;
|
|
447
|
+
declare const async_sleep: typeof sleep;
|
|
448
|
+
declare const async_wait: typeof wait;
|
|
449
|
+
declare namespace async {
|
|
450
|
+
export { async_handleOperation as handleOperation, async_runBatch as runBatch, async_sleep as sleep, async_wait as wait };
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
export { async as a, handleOperation as h, runBatch as r, sleep as s, wait as w };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { h as handleOperation, r as runBatch, s as sleep, w as wait } from './async-C8gvbSG-.js';
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSV Import/Export utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides reliable CSV operations for both Node.js and Browser environments using PapaParse.
|
|
5
|
+
* Features:
|
|
6
|
+
* - UTF-8 BOM encoding for Excel compatibility
|
|
7
|
+
* - Semicolon delimiter by default (European standard)
|
|
8
|
+
* - Automatic header detection
|
|
9
|
+
* - Dual-mode: filesystem (Node.js) vs download trigger (Browser)
|
|
10
|
+
*
|
|
11
|
+
* @module csv
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Exports data as CSV file with UTF-8 BOM encoding
|
|
15
|
+
*
|
|
16
|
+
* Works in both Node.js (writes to filesystem) and Browser (triggers download).
|
|
17
|
+
* Uses PapaParse library for reliable CSV generation with proper escaping and formatting.
|
|
18
|
+
*
|
|
19
|
+
* Features:
|
|
20
|
+
* - UTF-8 BOM prepended (\\ufeff) for Excel compatibility
|
|
21
|
+
* - Semicolon delimiter by default (European/Spanish standard)
|
|
22
|
+
* - Automatic header row from object keys
|
|
23
|
+
* - Custom delimiters and options via PapaParse config
|
|
24
|
+
*
|
|
25
|
+
* Environment behavior:
|
|
26
|
+
* - **Node.js**: Writes file to filesystem at specified path
|
|
27
|
+
* - **Browser**: Triggers automatic download with filename extracted from path
|
|
28
|
+
*
|
|
29
|
+
* @param data - Array of objects or array of arrays to export as CSV
|
|
30
|
+
* @param filePath - File path (Node.js) or download filename (Browser)
|
|
31
|
+
* @param options - PapaParse unparse options (optional)
|
|
32
|
+
* @param options.delimiter - Column separator (default: ';' semicolon)
|
|
33
|
+
* @param options.header - Include header row (default: true)
|
|
34
|
+
* @param options.quotes - Quote all fields (default: false)
|
|
35
|
+
* @param options.newline - Line ending (default: '\\r\\n')
|
|
36
|
+
* @returns Promise that resolves when export completes
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* // Basic export - Array of objects
|
|
41
|
+
* const users = [
|
|
42
|
+
* { name: 'Alice', age: 30, city: 'Madrid' },
|
|
43
|
+
* { name: 'Bob', age: 25, city: 'Barcelona' },
|
|
44
|
+
* { name: 'Carlos', age: 35, city: 'Valencia' }
|
|
45
|
+
* ]
|
|
46
|
+
*
|
|
47
|
+
* // Node.js - Write to file
|
|
48
|
+
* await exportCSV(users, './reports/users.csv')
|
|
49
|
+
* // Creates: ./reports/users.csv with BOM and semicolon delimiter
|
|
50
|
+
*
|
|
51
|
+
* // Browser - Trigger download
|
|
52
|
+
* await exportCSV(users, 'users.csv')
|
|
53
|
+
* // Downloads: users.csv to browser's download folder
|
|
54
|
+
*
|
|
55
|
+
* // Custom delimiter (comma for international)
|
|
56
|
+
* await exportCSV(users, 'users_intl.csv', { delimiter: ',' })
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* // Array of arrays (no header auto-detection)
|
|
62
|
+
* const matrix = [
|
|
63
|
+
* ['Name', 'Age', 'City'], // Header row
|
|
64
|
+
* ['Alice', 30, 'Madrid'],
|
|
65
|
+
* ['Bob', 25, 'Barcelona']
|
|
66
|
+
* ]
|
|
67
|
+
* await exportCSV(matrix, 'matrix.csv')
|
|
68
|
+
*
|
|
69
|
+
* // Without header row
|
|
70
|
+
* const data = [['A1', 'B1'], ['A2', 'B2']]
|
|
71
|
+
* await exportCSV(data, 'no_header.csv', { header: false })
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* // Real-world: Export sales report
|
|
77
|
+
* async function exportSalesReport(sales: Sale[]) {
|
|
78
|
+
* const reportData = sales.map(sale => ({
|
|
79
|
+
* Fecha: formatDate(sale.date),
|
|
80
|
+
* Cliente: sale.customerName,
|
|
81
|
+
* Producto: sale.productName,
|
|
82
|
+
* Cantidad: sale.quantity,
|
|
83
|
+
* Total: `${sale.total.toFixed(2)}€`
|
|
84
|
+
* }))
|
|
85
|
+
*
|
|
86
|
+
* const filename = `ventas_${new Date().toISOString().split('T')[0]}.csv`
|
|
87
|
+
* await exportCSV(reportData, filename)
|
|
88
|
+
* }
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* // Custom PapaParse options
|
|
94
|
+
* await exportCSV(data, 'quotes.csv', {
|
|
95
|
+
* delimiter: ',',
|
|
96
|
+
* quotes: true, // Quote all fields
|
|
97
|
+
* quoteChar: '"',
|
|
98
|
+
* escapeChar: '"',
|
|
99
|
+
* newline: '\\n' // Unix line endings
|
|
100
|
+
* })
|
|
101
|
+
* ```
|
|
102
|
+
*
|
|
103
|
+
* @throws {Error} If file write fails in Node.js
|
|
104
|
+
* @see {@link importCSV} for importing CSV files
|
|
105
|
+
* @see {@link https://www.papaparse.com/docs#unparse PapaParse Unparse Documentation}
|
|
106
|
+
*/
|
|
107
|
+
declare function exportCSV(data: any[], filePath: string, options?: any): Promise<void>;
|
|
108
|
+
/**
|
|
109
|
+
* Imports CSV file and parses it to array of objects
|
|
110
|
+
*
|
|
111
|
+
* Reads CSV file from filesystem (Node.js only) and parses using PapaParse.
|
|
112
|
+
* Automatically detects headers and converts rows to objects.
|
|
113
|
+
*
|
|
114
|
+
* Features:
|
|
115
|
+
* - Automatic header detection from first row
|
|
116
|
+
* - Semicolon delimiter by default (European standard)
|
|
117
|
+
* - Empty line skipping
|
|
118
|
+
* - Type inference for numbers and booleans
|
|
119
|
+
* - UTF-8 BOM handling
|
|
120
|
+
*
|
|
121
|
+
* ⚠️ BROWSER LIMITATION: File reading from filesystem is not supported in browsers
|
|
122
|
+
* for security reasons. For browser file uploads, use `readFileAsText()` with a File object
|
|
123
|
+
* obtained from an input[type="file"] element.
|
|
124
|
+
*
|
|
125
|
+
* @param filePath - Path to CSV file (Node.js only)
|
|
126
|
+
* @param options - PapaParse parse options (optional)
|
|
127
|
+
* @param options.delimiter - Column separator (default: ';' semicolon)
|
|
128
|
+
* @param options.header - Parse first row as headers (default: true)
|
|
129
|
+
* @param options.skipEmptyLines - Skip empty rows (default: true)
|
|
130
|
+
* @param options.dynamicTyping - Convert numeric/boolean values (default: false)
|
|
131
|
+
* @returns Promise<Array<Object>> Array of objects with keys from header row
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```typescript
|
|
135
|
+
* // Basic import - Node.js only
|
|
136
|
+
* const users = await importCSV('./data/users.csv')
|
|
137
|
+
* // Returns: [
|
|
138
|
+
* // { name: 'Alice', age: '30', city: 'Madrid' },
|
|
139
|
+
* // { name: 'Bob', age: '25', city: 'Barcelona' }
|
|
140
|
+
* // ]
|
|
141
|
+
*
|
|
142
|
+
* // Custom delimiter (comma)
|
|
143
|
+
* const intlData = await importCSV('./data/users_intl.csv', {
|
|
144
|
+
* delimiter: ','
|
|
145
|
+
* })
|
|
146
|
+
*
|
|
147
|
+
* // With type conversion
|
|
148
|
+
* const typed = await importCSV('./data/sales.csv', {
|
|
149
|
+
* dynamicTyping: true // Converts '123' → 123, 'true' → true
|
|
150
|
+
* })
|
|
151
|
+
* // Returns: { quantity: 10, total: 299.99, active: true }
|
|
152
|
+
* ```
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* ```typescript
|
|
156
|
+
* // Real-world: Import and process sales data
|
|
157
|
+
* async function importSalesReport(filePath: string) {
|
|
158
|
+
* try {
|
|
159
|
+
* const sales = await importCSV(filePath, {
|
|
160
|
+
* delimiter: ';',
|
|
161
|
+
* dynamicTyping: true,
|
|
162
|
+
* skipEmptyLines: true
|
|
163
|
+
* })
|
|
164
|
+
*
|
|
165
|
+
* // Process imported data
|
|
166
|
+
* const totalSales = sales.reduce((sum, sale) =>
|
|
167
|
+
* sum + (sale.total || 0), 0
|
|
168
|
+
* )
|
|
169
|
+
*
|
|
170
|
+
* console.log(`Imported ${sales.length} sales, total: €${totalSales}`)
|
|
171
|
+
* return sales
|
|
172
|
+
* } catch (error) {
|
|
173
|
+
* console.error('Failed to import CSV:', error)
|
|
174
|
+
* throw error
|
|
175
|
+
* }
|
|
176
|
+
* }
|
|
177
|
+
* ```
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```typescript
|
|
181
|
+
* // Browser alternative using File API
|
|
182
|
+
* // HTML: <input type="file" id="csvFile" accept=".csv">
|
|
183
|
+
*
|
|
184
|
+
* document.getElementById('csvFile').addEventListener('change', async (e) => {
|
|
185
|
+
* const file = e.target.files[0]
|
|
186
|
+
*
|
|
187
|
+
* // Read file content
|
|
188
|
+
* const content = await readFileAsText(file)
|
|
189
|
+
*
|
|
190
|
+
* // Parse with PapaParse
|
|
191
|
+
* const parsed = Papa.parse(content, {
|
|
192
|
+
* header: true,
|
|
193
|
+
* delimiter: ';',
|
|
194
|
+
* skipEmptyLines: true
|
|
195
|
+
* })
|
|
196
|
+
*
|
|
197
|
+
* const data = parsed.data
|
|
198
|
+
* console.log('Imported data:', data)
|
|
199
|
+
* })
|
|
200
|
+
* ```
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* ```typescript
|
|
204
|
+
* // Handle parsing errors
|
|
205
|
+
* const result = await importCSV('./malformed.csv')
|
|
206
|
+
* .catch(error => {
|
|
207
|
+
* if (error.message.includes('not supported in browser')) {
|
|
208
|
+
* console.error('Use File API for browser uploads')
|
|
209
|
+
* } else if (error.code === 'ENOENT') {
|
|
210
|
+
* console.error('File not found')
|
|
211
|
+
* } else {
|
|
212
|
+
* console.error('CSV parsing failed:', error)
|
|
213
|
+
* }
|
|
214
|
+
* return [] // Return empty array as fallback
|
|
215
|
+
* })
|
|
216
|
+
* ```
|
|
217
|
+
*
|
|
218
|
+
* @throws {Error} 'CSV import not supported in browser' when called in browser environment
|
|
219
|
+
* @throws {Error} File system errors (ENOENT, EACCES, etc.) in Node.js
|
|
220
|
+
* @see {@link exportCSV} for exporting CSV files
|
|
221
|
+
* @see {@link readFileAsText} for browser file reading
|
|
222
|
+
* @see {@link https://www.papaparse.com/docs#parse PapaParse Parse Documentation}
|
|
223
|
+
*/
|
|
224
|
+
declare function importCSV(filePath: string, options?: any): Promise<any[]>;
|
|
225
|
+
|
|
226
|
+
export { exportCSV, importCSV };
|