jtcsv 2.2.7 → 3.0.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 (140) hide show
  1. package/README.md +31 -1
  2. package/bin/jtcsv.js +891 -821
  3. package/bin/jtcsv.ts +2534 -0
  4. package/csv-to-json.js +168 -145
  5. package/dist/jtcsv-core.cjs.js +1407 -0
  6. package/dist/jtcsv-core.cjs.js.map +1 -0
  7. package/dist/jtcsv-core.esm.js +1379 -0
  8. package/dist/jtcsv-core.esm.js.map +1 -0
  9. package/dist/jtcsv-core.umd.js +1413 -0
  10. package/dist/jtcsv-core.umd.js.map +1 -0
  11. package/dist/jtcsv-full.cjs.js +1912 -0
  12. package/dist/jtcsv-full.cjs.js.map +1 -0
  13. package/dist/jtcsv-full.esm.js +1880 -0
  14. package/dist/jtcsv-full.esm.js.map +1 -0
  15. package/dist/jtcsv-full.umd.js +1918 -0
  16. package/dist/jtcsv-full.umd.js.map +1 -0
  17. package/dist/jtcsv-workers.esm.js +759 -0
  18. package/dist/jtcsv-workers.esm.js.map +1 -0
  19. package/dist/jtcsv-workers.umd.js +773 -0
  20. package/dist/jtcsv-workers.umd.js.map +1 -0
  21. package/dist/jtcsv.cjs.js +61 -19
  22. package/dist/jtcsv.cjs.js.map +1 -1
  23. package/dist/jtcsv.esm.js +61 -19
  24. package/dist/jtcsv.esm.js.map +1 -1
  25. package/dist/jtcsv.umd.js +61 -19
  26. package/dist/jtcsv.umd.js.map +1 -1
  27. package/errors.js +188 -2
  28. package/examples/advanced/conditional-transformations.js +446 -0
  29. package/examples/advanced/conditional-transformations.ts +446 -0
  30. package/examples/advanced/csv-parser.worker.js +89 -0
  31. package/examples/advanced/csv-parser.worker.ts +89 -0
  32. package/examples/advanced/nested-objects-example.js +306 -0
  33. package/examples/advanced/nested-objects-example.ts +306 -0
  34. package/examples/advanced/performance-optimization.js +504 -0
  35. package/examples/advanced/performance-optimization.ts +504 -0
  36. package/examples/advanced/run-demo-server.js +116 -0
  37. package/examples/advanced/run-demo-server.ts +116 -0
  38. package/examples/advanced/web-worker-usage.html +874 -0
  39. package/examples/async-multithreaded-example.ts +335 -0
  40. package/examples/cli-advanced-usage.md +288 -0
  41. package/examples/cli-batch-processing.ts +38 -0
  42. package/examples/cli-tool.js +0 -3
  43. package/examples/cli-tool.ts +183 -0
  44. package/examples/error-handling.js +21 -7
  45. package/examples/error-handling.ts +356 -0
  46. package/examples/express-api.js +0 -3
  47. package/examples/express-api.ts +164 -0
  48. package/examples/large-dataset-example.js +0 -3
  49. package/examples/large-dataset-example.ts +204 -0
  50. package/examples/ndjson-processing.js +1 -1
  51. package/examples/ndjson-processing.ts +456 -0
  52. package/examples/plugin-excel-exporter.js +3 -4
  53. package/examples/plugin-excel-exporter.ts +406 -0
  54. package/examples/react-integration.tsx +637 -0
  55. package/examples/schema-validation.ts +640 -0
  56. package/examples/simple-usage.js +254 -254
  57. package/examples/simple-usage.ts +194 -0
  58. package/examples/streaming-example.js +4 -5
  59. package/examples/streaming-example.ts +419 -0
  60. package/examples/web-workers-advanced.ts +28 -0
  61. package/index.d.ts +1 -3
  62. package/index.js +15 -1
  63. package/json-save.js +9 -3
  64. package/json-to-csv.js +168 -21
  65. package/package.json +69 -10
  66. package/plugins/express-middleware/README.md +21 -2
  67. package/plugins/express-middleware/example.js +3 -4
  68. package/plugins/express-middleware/example.ts +135 -0
  69. package/plugins/express-middleware/index.d.ts +1 -1
  70. package/plugins/express-middleware/index.js +270 -118
  71. package/plugins/express-middleware/index.ts +557 -0
  72. package/plugins/fastify-plugin/index.js +2 -4
  73. package/plugins/fastify-plugin/index.ts +443 -0
  74. package/plugins/hono/index.ts +226 -0
  75. package/plugins/nestjs/index.ts +201 -0
  76. package/plugins/nextjs-api/examples/ConverterComponent.tsx +386 -0
  77. package/plugins/nextjs-api/examples/api-convert.js +0 -2
  78. package/plugins/nextjs-api/examples/api-convert.ts +67 -0
  79. package/plugins/nextjs-api/index.tsx +339 -0
  80. package/plugins/nextjs-api/route.js +2 -3
  81. package/plugins/nextjs-api/route.ts +370 -0
  82. package/plugins/nuxt/index.ts +94 -0
  83. package/plugins/nuxt/runtime/composables/useJtcsv.ts +100 -0
  84. package/plugins/nuxt/runtime/plugin.ts +71 -0
  85. package/plugins/remix/index.js +1 -1
  86. package/plugins/remix/index.ts +260 -0
  87. package/plugins/sveltekit/index.js +1 -1
  88. package/plugins/sveltekit/index.ts +301 -0
  89. package/plugins/trpc/index.ts +267 -0
  90. package/src/browser/browser-functions.ts +402 -0
  91. package/src/browser/core.js +92 -0
  92. package/src/browser/core.ts +152 -0
  93. package/src/browser/csv-to-json-browser.d.ts +3 -0
  94. package/src/browser/csv-to-json-browser.js +36 -14
  95. package/src/browser/csv-to-json-browser.ts +264 -0
  96. package/src/browser/errors-browser.ts +303 -0
  97. package/src/browser/extensions/plugins.js +92 -0
  98. package/src/browser/extensions/plugins.ts +93 -0
  99. package/src/browser/extensions/workers.js +39 -0
  100. package/src/browser/extensions/workers.ts +39 -0
  101. package/src/browser/globals.d.ts +5 -0
  102. package/src/browser/index.ts +192 -0
  103. package/src/browser/json-to-csv-browser.d.ts +3 -0
  104. package/src/browser/json-to-csv-browser.js +13 -3
  105. package/src/browser/json-to-csv-browser.ts +262 -0
  106. package/src/browser/streams.js +12 -2
  107. package/src/browser/streams.ts +336 -0
  108. package/src/browser/workers/csv-parser.worker.ts +377 -0
  109. package/src/browser/workers/worker-pool.ts +548 -0
  110. package/src/core/delimiter-cache.js +22 -8
  111. package/src/core/delimiter-cache.ts +310 -0
  112. package/src/core/node-optimizations.ts +449 -0
  113. package/src/core/plugin-system.js +29 -11
  114. package/src/core/plugin-system.ts +400 -0
  115. package/src/core/transform-hooks.ts +558 -0
  116. package/src/engines/fast-path-engine-new.ts +347 -0
  117. package/src/engines/fast-path-engine.ts +854 -0
  118. package/src/errors.ts +72 -0
  119. package/src/formats/ndjson-parser.ts +469 -0
  120. package/src/formats/tsv-parser.ts +334 -0
  121. package/src/index-with-plugins.js +16 -9
  122. package/src/index-with-plugins.ts +395 -0
  123. package/src/types/index.ts +255 -0
  124. package/src/utils/bom-utils.js +259 -0
  125. package/src/utils/bom-utils.ts +373 -0
  126. package/src/utils/encoding-support.js +124 -0
  127. package/src/utils/encoding-support.ts +155 -0
  128. package/src/utils/schema-validator.js +19 -19
  129. package/src/utils/schema-validator.ts +819 -0
  130. package/src/utils/transform-loader.js +1 -1
  131. package/src/utils/transform-loader.ts +389 -0
  132. package/src/utils/zod-adapter.js +170 -0
  133. package/src/utils/zod-adapter.ts +280 -0
  134. package/src/web-server/index.js +10 -10
  135. package/src/web-server/index.ts +683 -0
  136. package/src/workers/csv-multithreaded.ts +310 -0
  137. package/src/workers/csv-parser.worker.ts +227 -0
  138. package/src/workers/worker-pool.ts +409 -0
  139. package/stream-csv-to-json.js +26 -8
  140. package/stream-json-to-csv.js +1 -0
@@ -0,0 +1,456 @@
1
+ /**
2
+ * NDJSON Processing Examples for jtcsv
3
+ *
4
+ * NDJSON (Newline Delimited JSON) is a format where each line
5
+ * is a valid JSON object. It's ideal for streaming large datasets
6
+ * and log processing.
7
+ */
8
+
9
+ import {
10
+ jsonToNdjson,
11
+ ndjsonToJson,
12
+ parseNdjsonStream,
13
+ createNdjsonToCsvStream,
14
+ createCsvToNdjsonStream,
15
+ getNdjsonStats,
16
+ jsonToCsv,
17
+ csvToJson
18
+ } from '../index';
19
+
20
+ import fs from 'fs';
21
+ import path from 'path';
22
+ import { Readable, PassThrough } from 'stream';
23
+
24
+ // Типы для NDJSON
25
+ interface LogEntry {
26
+ level: string;
27
+ message: string;
28
+ ts: number;
29
+ }
30
+
31
+ interface NdjsonStats {
32
+ totalLines: number;
33
+ validLines: number;
34
+ errorLines: number;
35
+ totalBytes: number;
36
+ successRate: number;
37
+ errors: Array<{line: number, error: string}>;
38
+ }
39
+
40
+ // =============================================================================
41
+ // Example 1: Basic NDJSON Conversion
42
+ // =============================================================================
43
+
44
+ function basicNdjsonConversion() {
45
+ console.log('\n=== Basic NDJSON Conversion ===\n');
46
+
47
+ const data = [
48
+ { id: 1, event: 'login', user: 'john', timestamp: '2024-01-15T10:30:00Z' },
49
+ { id: 2, event: 'click', user: 'john', timestamp: '2024-01-15T10:30:15Z' },
50
+ { id: 3, event: 'purchase', user: 'john', timestamp: '2024-01-15T10:31:00Z' },
51
+ { id: 4, event: 'logout', user: 'john', timestamp: '2024-01-15T10:35:00Z' }
52
+ ];
53
+
54
+ // Convert to NDJSON
55
+ const ndjson = jsonToNdjson(data);
56
+ console.log('NDJSON output:');
57
+ console.log(ndjson);
58
+
59
+ // Parse back to JSON
60
+ const parsed = ndjsonToJson(ndjson);
61
+ console.log('\nParsed back:', parsed.length, 'records');
62
+ }
63
+
64
+ // =============================================================================
65
+ // Example 2: NDJSON with Transform and Filter
66
+ // =============================================================================
67
+
68
+ function ndjsonWithTransformAndFilter() {
69
+ console.log('\n=== NDJSON with Transform and Filter ===\n');
70
+
71
+ const logEntries = [
72
+ { level: 'info', message: 'Application started', ts: 1705312200 },
73
+ { level: 'debug', message: 'Connecting to database', ts: 1705312201 },
74
+ { level: 'error', message: 'Connection failed', ts: 1705312202 },
75
+ { level: 'info', message: 'Retry connection', ts: 1705312203 },
76
+ { level: 'info', message: 'Connected successfully', ts: 1705312204 },
77
+ { level: 'debug', message: 'Query executed', ts: 1705312205 }
78
+ ];
79
+
80
+ // Convert with transform - add formatted timestamp
81
+ const ndjson = jsonToNdjson(logEntries, {
82
+ transform: (obj: LogEntry, index: number) => ({
83
+ ...obj,
84
+ index,
85
+ formattedTime: new Date(obj.ts * 1000).toISOString()
86
+ })
87
+ });
88
+ console.log('Transformed NDJSON:');
89
+ console.log(ndjson);
90
+
91
+ // Parse back with filter - only errors and info
92
+ const filtered = ndjsonToJson(ndjson, {
93
+ filter: (obj: any) => obj.level === 'error' || obj.level === 'info'
94
+ });
95
+ console.log('\nFiltered entries (error + info only):', filtered.length);
96
+ filtered.forEach(e => console.log(` [${e.level}] ${e.message}`));
97
+ }
98
+
99
+ // =============================================================================
100
+ // Example 3: NDJSON Error Handling
101
+ // =============================================================================
102
+
103
+ function ndjsonErrorHandling() {
104
+ console.log('\n=== NDJSON Error Handling ===\n');
105
+
106
+ // NDJSON with some invalid lines
107
+ const mixedNdjson = `{"id": 1, "valid": true}
108
+ {"id": 2, "valid": true}
109
+ {invalid json here}
110
+ {"id": 3, "valid": true}
111
+ not json at all
112
+ {"id": 4, "valid": true}`;
113
+
114
+ const errors: Array<{lineNumber: number, error: string, content: string}> = [];
115
+
116
+ const result = ndjsonToJson(mixedNdjson, {
117
+ onError: (error: Error, line: string, lineNumber: number) => {
118
+ errors.push({
119
+ lineNumber,
120
+ error: error.message,
121
+ content: line.substring(0, 30) + (line.length > 30 ? '...' : '')
122
+ });
123
+ }
124
+ });
125
+
126
+ console.log('Valid records:', result.length);
127
+ console.log('Errors encountered:', errors.length);
128
+ errors.forEach(e => {
129
+ console.log(` Line ${e.lineNumber}: ${e.error}`);
130
+ console.log(` Content: ${e.content}`);
131
+ });
132
+ }
133
+
134
+ // =============================================================================
135
+ // Example 4: Streaming NDJSON Processing
136
+ // =============================================================================
137
+
138
+ async function streamingNdjsonProcessing() {
139
+ console.log('\n=== Streaming NDJSON Processing ===\n');
140
+
141
+ // Create a stream from NDJSON string
142
+ const ndjsonContent = `{"type": "user", "name": "Alice", "age": 28}
143
+ {"type": "user", "name": "Bob", "age": 35}
144
+ {"type": "product", "name": "Laptop", "price": 999}
145
+ {"type": "user", "name": "Charlie", "age": 42}
146
+ {"type": "product", "name": "Phone", "price": 599}`;
147
+
148
+ // Create readable stream
149
+ const stream = Readable.from([ndjsonContent]);
150
+
151
+ // Process stream with async iterator
152
+ const users: any[] = [];
153
+ const products: any[] = [];
154
+
155
+ // parseNdjsonStream принимает string или ReadableStream, преобразуем
156
+ const ndjsonString = ndjsonContent;
157
+ const parsed = ndjsonToJson(ndjsonString);
158
+
159
+ for (const obj of parsed) {
160
+ if (obj.type === 'user') {
161
+ users.push(obj);
162
+ } else if (obj.type === 'product') {
163
+ products.push(obj);
164
+ }
165
+ }
166
+
167
+ console.log('Users found:', users.length);
168
+ users.forEach(u => console.log(` - ${u.name}, ${u.age} years old`));
169
+
170
+ console.log('\nProducts found:', products.length);
171
+ products.forEach(p => console.log(` - ${p.name}: $${p.price}`));
172
+ }
173
+
174
+ // =============================================================================
175
+ // Example 5: NDJSON to CSV Conversion
176
+ // =============================================================================
177
+
178
+ async function ndjsonToCsvConversion() {
179
+ console.log('\n=== NDJSON to CSV Conversion ===\n');
180
+
181
+ const ndjson = `{"name": "Alice", "department": "Engineering", "salary": 85000}
182
+ {"name": "Bob", "department": "Marketing", "salary": 65000}
183
+ {"name": "Charlie", "department": "Engineering", "salary": 90000}
184
+ {"name": "Diana", "department": "Sales", "salary": 70000}`;
185
+
186
+ // Create NDJSON to CSV transform stream
187
+ const transformStream = createNdjsonToCsvStream({
188
+ delimiter: ',',
189
+ includeHeaders: true
190
+ });
191
+
192
+ // Collect CSV output
193
+ const csvOutput = '';
194
+ transformStream.writable.getWriter();
195
+
196
+ // Manual stream processing for demo
197
+ const lines = ndjson.split('\n');
198
+ const objects = lines.map(line => JSON.parse(line));
199
+
200
+ // Convert to CSV manually for this example
201
+ const csv = jsonToCsv(objects, { delimiter: ',' });
202
+
203
+ console.log('Converted CSV:');
204
+ console.log(csv);
205
+ }
206
+
207
+ // =============================================================================
208
+ // Example 6: CSV to NDJSON Conversion
209
+ // =============================================================================
210
+
211
+ function csvToNdjsonConversion() {
212
+ console.log('\n=== CSV to NDJSON Conversion ===\n');
213
+
214
+ const csv = `id,name,email,active
215
+ 1,John Doe,john@example.com,true
216
+ 2,Jane Smith,jane@example.com,false
217
+ 3,Bob Wilson,bob@example.com,true`;
218
+
219
+ // Parse CSV first
220
+ const data = csvToJson(csv, {
221
+ parseNumbers: true,
222
+ parseBooleans: true
223
+ });
224
+
225
+ // Convert to NDJSON
226
+ const ndjson = jsonToNdjson(data);
227
+ console.log('NDJSON output:');
228
+ console.log(ndjson);
229
+ }
230
+
231
+ // =============================================================================
232
+ // Example 7: NDJSON Statistics
233
+ // =============================================================================
234
+
235
+ async function ndjsonStatistics() {
236
+ console.log('\n=== NDJSON Statistics ===\n');
237
+
238
+ const ndjson = `{"id": 1, "type": "event"}
239
+ {"id": 2, "type": "event"}
240
+ {invalid}
241
+ {"id": 3, "type": "event"}
242
+ not json
243
+ {"id": 4, "type": "event"}
244
+ {"id": 5, "type": "event"}`;
245
+
246
+ const stats = await getNdjsonStats(ndjson) as NdjsonStats;
247
+
248
+ console.log('NDJSON Statistics:');
249
+ console.log(' Total lines:', stats.totalLines);
250
+ console.log(' Valid lines:', stats.validLines);
251
+ console.log(' Error lines:', stats.errorLines);
252
+ console.log(' Total bytes:', stats.totalBytes);
253
+ console.log(' Success rate:', (stats.successRate * 100).toFixed(1) + '%');
254
+
255
+ if (stats.errors.length > 0) {
256
+ console.log('\nErrors:');
257
+ stats.errors.forEach(e => {
258
+ console.log(` Line ${e.line}: ${e.error}`);
259
+ });
260
+ }
261
+ }
262
+
263
+ // =============================================================================
264
+ // Example 8: Large NDJSON Processing with Memory Efficiency
265
+ // =============================================================================
266
+
267
+ async function largeNdjsonProcessing() {
268
+ console.log('\n=== Large NDJSON Processing ===\n');
269
+
270
+ // Simulate large NDJSON data
271
+ const generateLargeNdjson = (count: number) => {
272
+ const lines = [];
273
+ for (let i = 0; i < count; i++) {
274
+ lines.push(JSON.stringify({
275
+ id: i,
276
+ timestamp: Date.now() + i,
277
+ value: Math.random() * 100,
278
+ category: ['A', 'B', 'C'][i % 3]
279
+ }));
280
+ }
281
+ return lines.join('\n');
282
+ };
283
+
284
+ const largeNdjson = generateLargeNdjson(10000);
285
+ console.log(`Generated ${largeNdjson.split('\n').length} NDJSON lines`);
286
+
287
+ // Process with aggregation
288
+ const stats = {
289
+ count: 0,
290
+ sum: 0,
291
+ categories: {} as Record<string, number>
292
+ };
293
+
294
+ const startTime = Date.now();
295
+
296
+ // Используем ndjsonToJson вместо parseNdjsonStream для простоты
297
+ const parsed = ndjsonToJson(largeNdjson);
298
+ for (const obj of parsed) {
299
+ stats.count++;
300
+ stats.sum += obj.value;
301
+ stats.categories[obj.category] = (stats.categories[obj.category] || 0) + 1;
302
+ }
303
+
304
+ const endTime = Date.now();
305
+
306
+ console.log('\nAggregation results:');
307
+ console.log(' Records processed:', stats.count);
308
+ console.log(' Average value:', (stats.sum / stats.count).toFixed(2));
309
+ console.log(' Categories:', stats.categories);
310
+ console.log(' Processing time:', endTime - startTime, 'ms');
311
+ console.log(' Throughput:', Math.round(stats.count / ((endTime - startTime) / 1000)), 'records/sec');
312
+ }
313
+
314
+ // =============================================================================
315
+ // Example 9: NDJSON Log Processing Pipeline
316
+ // =============================================================================
317
+
318
+ async function logProcessingPipeline() {
319
+ console.log('\n=== NDJSON Log Processing Pipeline ===\n');
320
+
321
+ // Simulated log entries
322
+ const logs = `{"ts": "2024-01-15T10:00:00Z", "level": "info", "service": "api", "msg": "Request received", "duration_ms": 50}
323
+ {"ts": "2024-01-15T10:00:01Z", "level": "debug", "service": "api", "msg": "Processing request", "duration_ms": 0}
324
+ {"ts": "2024-01-15T10:00:02Z", "level": "warn", "service": "db", "msg": "Slow query detected", "duration_ms": 1500}
325
+ {"ts": "2024-01-15T10:00:03Z", "level": "error", "service": "api", "msg": "Request failed", "duration_ms": 100, "error": "Timeout"}
326
+ {"ts": "2024-01-15T10:00:04Z", "level": "info", "service": "api", "msg": "Request completed", "duration_ms": 45}
327
+ {"ts": "2024-01-15T10:00:05Z", "level": "error", "service": "db", "msg": "Connection lost", "duration_ms": 0, "error": "Network error"}`;
328
+
329
+ // Pipeline stages
330
+ const pipeline = {
331
+ errors: [] as Array<{time: string, service: string, message: string, error?: string}>,
332
+ warnings: [] as Array<{time: string, service: string, message: string}>,
333
+ slowRequests: [] as Array<{time: string, service: string, duration: number}>,
334
+ serviceStats: {} as Record<string, {count: number, errors: number}>
335
+ };
336
+
337
+ // Process logs
338
+ const parsedLogs = ndjsonToJson(logs);
339
+ for (const log of parsedLogs) {
340
+ // Collect errors
341
+ if (log.level === 'error') {
342
+ pipeline.errors.push({
343
+ time: log.ts,
344
+ service: log.service,
345
+ message: log.msg,
346
+ error: log.error
347
+ });
348
+ }
349
+
350
+ // Collect warnings
351
+ if (log.level === 'warn') {
352
+ pipeline.warnings.push({
353
+ time: log.ts,
354
+ service: log.service,
355
+ message: log.msg
356
+ });
357
+ }
358
+
359
+ // Track slow requests (> 1000ms)
360
+ if (log.duration_ms > 1000) {
361
+ pipeline.slowRequests.push({
362
+ time: log.ts,
363
+ service: log.service,
364
+ duration: log.duration_ms
365
+ });
366
+ }
367
+
368
+ // Aggregate by service
369
+ if (!pipeline.serviceStats[log.service]) {
370
+ pipeline.serviceStats[log.service] = { count: 0, errors: 0 };
371
+ }
372
+ pipeline.serviceStats[log.service].count++;
373
+ if (log.level === 'error') {
374
+ pipeline.serviceStats[log.service].errors++;
375
+ }
376
+ }
377
+
378
+ // Report
379
+ console.log('Log Analysis Report:');
380
+ console.log('\nErrors:', pipeline.errors.length);
381
+ pipeline.errors.forEach(e => {
382
+ console.log(` [${e.service}] ${e.message} - ${e.error}`);
383
+ });
384
+
385
+ console.log('\nWarnings:', pipeline.warnings.length);
386
+ pipeline.warnings.forEach(w => {
387
+ console.log(` [${w.service}] ${w.message}`);
388
+ });
389
+
390
+ console.log('\nSlow Requests (>1s):', pipeline.slowRequests.length);
391
+ pipeline.slowRequests.forEach(s => {
392
+ console.log(` [${s.service}] ${s.duration}ms`);
393
+ });
394
+
395
+ console.log('\nService Statistics:');
396
+ Object.entries(pipeline.serviceStats).forEach(([service, stats]) => {
397
+ const errorRate = ((stats.errors / stats.count) * 100).toFixed(1);
398
+ console.log(` ${service}: ${stats.count} requests, ${stats.errors} errors (${errorRate}%)`);
399
+ });
400
+ }
401
+
402
+ // =============================================================================
403
+ // Example 10: NDJSON Pretty Print and Compact
404
+ // =============================================================================
405
+
406
+ function ndjsonFormatting() {
407
+ console.log('\n=== NDJSON Formatting Options ===\n');
408
+
409
+ const data = [
410
+ { name: 'Test', nested: { a: 1, b: 2 }, array: [1, 2, 3] }
411
+ ];
412
+
413
+ // Compact (default)
414
+ const compact = jsonToNdjson(data);
415
+ console.log('Compact:');
416
+ console.log(compact);
417
+
418
+ // With custom replacer (filter out 'array' field)
419
+ const filtered = jsonToNdjson(data, {
420
+ replacer: (key: string, value: any) => key === 'array' ? undefined : value
421
+ });
422
+ console.log('\nFiltered (no array):');
423
+ console.log(filtered);
424
+
425
+ // With space for readability (not standard NDJSON but useful for debugging)
426
+ const pretty = jsonToNdjson(data, {
427
+ space: 0 // Standard NDJSON should have no space
428
+ });
429
+ console.log('\nStandard NDJSON:');
430
+ console.log(pretty);
431
+ }
432
+
433
+ // =============================================================================
434
+ // Run All Examples
435
+ // =============================================================================
436
+
437
+ async function main() {
438
+ console.log('jtcsv NDJSON Processing Examples');
439
+ console.log('='.repeat(60));
440
+
441
+ basicNdjsonConversion();
442
+ ndjsonWithTransformAndFilter();
443
+ ndjsonErrorHandling();
444
+ await streamingNdjsonProcessing();
445
+ await ndjsonToCsvConversion();
446
+ csvToNdjsonConversion();
447
+ await ndjsonStatistics();
448
+ await largeNdjsonProcessing();
449
+ await logProcessingPipeline();
450
+ ndjsonFormatting();
451
+
452
+ console.log('\n' + '='.repeat(60));
453
+ console.log('All NDJSON examples completed.');
454
+ }
455
+
456
+ main().catch(console.error);
@@ -249,7 +249,9 @@ async function importFromExcel(filePath, options = {}) {
249
249
  let headers = [];
250
250
 
251
251
  worksheet.eachRow((row, rowNumber) => {
252
- if (rowNumber <= skipRows) return;
252
+ if (rowNumber <= skipRows) {
253
+ return;
254
+ }
253
255
 
254
256
  if (hasHeaders && rowNumber === skipRows + 1) {
255
257
  // Первая строка - заголовки
@@ -402,6 +404,3 @@ module.exports = {
402
404
  if (require.main === module) {
403
405
  exampleUsage().catch(console.error);
404
406
  }
405
-
406
-
407
-