jtcsv 2.1.3 → 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +60 -341
  3. package/bin/jtcsv.js +2462 -1372
  4. package/csv-to-json.js +35 -26
  5. package/dist/jtcsv.cjs.js +807 -133
  6. package/dist/jtcsv.cjs.js.map +1 -1
  7. package/dist/jtcsv.esm.js +800 -134
  8. package/dist/jtcsv.esm.js.map +1 -1
  9. package/dist/jtcsv.umd.js +807 -133
  10. package/dist/jtcsv.umd.js.map +1 -1
  11. package/errors.js +20 -0
  12. package/examples/browser-vanilla.html +37 -0
  13. package/examples/cli-batch-processing.js +38 -0
  14. package/examples/error-handling.js +324 -0
  15. package/examples/ndjson-processing.js +434 -0
  16. package/examples/react-integration.jsx +637 -0
  17. package/examples/schema-validation.js +640 -0
  18. package/examples/simple-usage.js +10 -7
  19. package/examples/typescript-example.ts +486 -0
  20. package/examples/web-workers-advanced.js +28 -0
  21. package/index.d.ts +2 -0
  22. package/json-save.js +2 -1
  23. package/json-to-csv.js +171 -131
  24. package/package.json +20 -4
  25. package/plugins/README.md +41 -467
  26. package/plugins/express-middleware/README.md +32 -274
  27. package/plugins/hono/README.md +16 -13
  28. package/plugins/nestjs/README.md +13 -11
  29. package/plugins/nextjs-api/README.md +28 -423
  30. package/plugins/nextjs-api/index.js +1 -2
  31. package/plugins/nextjs-api/route.js +1 -2
  32. package/plugins/nuxt/README.md +6 -7
  33. package/plugins/remix/README.md +9 -9
  34. package/plugins/sveltekit/README.md +8 -8
  35. package/plugins/trpc/README.md +8 -5
  36. package/src/browser/browser-functions.js +33 -3
  37. package/src/browser/csv-to-json-browser.js +269 -11
  38. package/src/browser/errors-browser.js +19 -1
  39. package/src/browser/index.js +39 -5
  40. package/src/browser/streams.js +393 -0
  41. package/src/browser/workers/csv-parser.worker.js +20 -2
  42. package/src/browser/workers/worker-pool.js +507 -447
  43. package/src/core/plugin-system.js +4 -0
  44. package/src/engines/fast-path-engine.js +31 -23
  45. package/src/errors.js +26 -0
  46. package/src/formats/ndjson-parser.js +54 -5
  47. package/src/formats/tsv-parser.js +4 -1
  48. package/src/utils/schema-validator.js +594 -0
  49. package/src/utils/transform-loader.js +205 -0
  50. package/src/web-server/index.js +683 -0
  51. package/stream-csv-to-json.js +16 -87
  52. package/stream-json-to-csv.js +18 -86
@@ -0,0 +1,640 @@
1
+ /**
2
+ * Schema Validation Examples for jtcsv
3
+ *
4
+ * jtcsv supports JSON Schema validation for ensuring
5
+ * data integrity during CSV/JSON conversions.
6
+ */
7
+
8
+ const {
9
+ jsonToCsv,
10
+ csvToJson,
11
+ ValidationError
12
+ } = require('jtcsv');
13
+
14
+ // =============================================================================
15
+ // Example 1: Basic Schema Validation
16
+ // =============================================================================
17
+
18
+ function basicSchemaValidation() {
19
+ console.log('\n=== Basic Schema Validation ===\n');
20
+
21
+ // Define schema for user data
22
+ const userSchema = {
23
+ type: 'object',
24
+ required: ['name', 'email'],
25
+ properties: {
26
+ name: {
27
+ type: 'string',
28
+ minLength: 1,
29
+ maxLength: 100
30
+ },
31
+ email: {
32
+ type: 'string',
33
+ pattern: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'
34
+ },
35
+ age: {
36
+ type: 'number',
37
+ minimum: 0,
38
+ maximum: 150
39
+ }
40
+ }
41
+ };
42
+
43
+ // Valid data
44
+ const validUsers = [
45
+ { name: 'John Doe', email: 'john@example.com', age: 30 },
46
+ { name: 'Jane Smith', email: 'jane@test.org', age: 25 }
47
+ ];
48
+
49
+ try {
50
+ const csv = jsonToCsv(validUsers, { schema: userSchema });
51
+ console.log('Valid data converted successfully:');
52
+ console.log(csv);
53
+ } catch (error) {
54
+ console.log('Unexpected error:', error.message);
55
+ }
56
+
57
+ // Invalid data
58
+ const invalidUsers = [
59
+ { name: '', email: 'john@example.com', age: 30 }, // Empty name
60
+ { name: 'Jane', email: 'invalid-email', age: -5 } // Bad email, negative age
61
+ ];
62
+
63
+ try {
64
+ jsonToCsv(invalidUsers, { schema: userSchema });
65
+ } catch (error) {
66
+ if (error instanceof ValidationError) {
67
+ console.log('\nValidation failed (expected):');
68
+ console.log('Error:', error.message);
69
+ }
70
+ }
71
+ }
72
+
73
+ // =============================================================================
74
+ // Example 2: Complex Nested Schema
75
+ // =============================================================================
76
+
77
+ function nestedSchemaValidation() {
78
+ console.log('\n=== Nested Schema Validation ===\n');
79
+
80
+ const orderSchema = {
81
+ type: 'object',
82
+ required: ['orderId', 'customer', 'total'],
83
+ properties: {
84
+ orderId: {
85
+ type: 'string',
86
+ pattern: '^ORD-[0-9]{6}$' // Format: ORD-123456
87
+ },
88
+ customer: {
89
+ type: 'object',
90
+ required: ['name', 'email'],
91
+ properties: {
92
+ name: { type: 'string', minLength: 1 },
93
+ email: { type: 'string' }
94
+ }
95
+ },
96
+ items: {
97
+ type: 'array',
98
+ minItems: 1,
99
+ items: {
100
+ type: 'object',
101
+ required: ['sku', 'quantity'],
102
+ properties: {
103
+ sku: { type: 'string' },
104
+ quantity: { type: 'number', minimum: 1 }
105
+ }
106
+ }
107
+ },
108
+ total: {
109
+ type: 'number',
110
+ minimum: 0
111
+ },
112
+ status: {
113
+ type: 'string',
114
+ enum: ['pending', 'processing', 'shipped', 'delivered']
115
+ }
116
+ }
117
+ };
118
+
119
+ const orders = [
120
+ {
121
+ orderId: 'ORD-123456',
122
+ customer: { name: 'John Doe', email: 'john@example.com' },
123
+ items: [
124
+ { sku: 'PROD-001', quantity: 2 },
125
+ { sku: 'PROD-002', quantity: 1 }
126
+ ],
127
+ total: 149.99,
128
+ status: 'processing'
129
+ }
130
+ ];
131
+
132
+ try {
133
+ const csv = jsonToCsv(orders, {
134
+ schema: orderSchema,
135
+ delimiter: ','
136
+ });
137
+ console.log('Order with nested data converted:');
138
+ console.log(csv);
139
+ } catch (error) {
140
+ console.log('Error:', error.message);
141
+ }
142
+ }
143
+
144
+ // =============================================================================
145
+ // Example 3: Schema with Custom Formats
146
+ // =============================================================================
147
+
148
+ function customFormatSchema() {
149
+ console.log('\n=== Custom Format Schema ===\n');
150
+
151
+ const eventSchema = {
152
+ type: 'object',
153
+ required: ['eventId', 'timestamp', 'eventType'],
154
+ properties: {
155
+ eventId: {
156
+ type: 'string',
157
+ pattern: '^EVT-[A-Z0-9]{8}$' // EVT-XXXXXXXX
158
+ },
159
+ timestamp: {
160
+ type: 'string',
161
+ pattern: '^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z$' // ISO 8601
162
+ },
163
+ eventType: {
164
+ type: 'string',
165
+ enum: ['click', 'view', 'purchase', 'signup', 'login', 'logout']
166
+ },
167
+ userId: {
168
+ type: 'string',
169
+ pattern: '^USR-\\d{6}$' // Optional but must match if present
170
+ },
171
+ metadata: {
172
+ type: 'object' // Allow any object structure
173
+ }
174
+ }
175
+ };
176
+
177
+ const events = [
178
+ {
179
+ eventId: 'EVT-A1B2C3D4',
180
+ timestamp: '2024-01-15T10:30:00.123Z',
181
+ eventType: 'purchase',
182
+ userId: 'USR-000123',
183
+ metadata: { productId: 'PRD-001', amount: 99.99 }
184
+ },
185
+ {
186
+ eventId: 'EVT-E5F6G7H8',
187
+ timestamp: '2024-01-15T10:31:00Z',
188
+ eventType: 'view',
189
+ metadata: { page: '/products', duration: 45 }
190
+ }
191
+ ];
192
+
193
+ try {
194
+ const csv = jsonToCsv(events, { schema: eventSchema });
195
+ console.log('Events validated and converted:');
196
+ console.log(csv);
197
+ } catch (error) {
198
+ console.log('Error:', error.message);
199
+ }
200
+ }
201
+
202
+ // =============================================================================
203
+ // Example 4: Array Validation
204
+ // =============================================================================
205
+
206
+ function arraySchemaValidation() {
207
+ console.log('\n=== Array Schema Validation ===\n');
208
+
209
+ const surveySchema = {
210
+ type: 'object',
211
+ required: ['respondentId', 'answers'],
212
+ properties: {
213
+ respondentId: {
214
+ type: 'number',
215
+ minimum: 1
216
+ },
217
+ answers: {
218
+ type: 'array',
219
+ minItems: 5,
220
+ maxItems: 10,
221
+ items: {
222
+ type: 'number',
223
+ minimum: 1,
224
+ maximum: 5 // Rating 1-5
225
+ }
226
+ },
227
+ comments: {
228
+ type: 'string',
229
+ maxLength: 500
230
+ }
231
+ }
232
+ };
233
+
234
+ const surveyResponses = [
235
+ {
236
+ respondentId: 1,
237
+ answers: [5, 4, 3, 5, 4],
238
+ comments: 'Great experience!'
239
+ },
240
+ {
241
+ respondentId: 2,
242
+ answers: [3, 3, 4, 4, 5, 4],
243
+ comments: ''
244
+ }
245
+ ];
246
+
247
+ try {
248
+ const csv = jsonToCsv(surveyResponses, { schema: surveySchema });
249
+ console.log('Survey responses validated:');
250
+ console.log(csv);
251
+ } catch (error) {
252
+ console.log('Error:', error.message);
253
+ }
254
+
255
+ // Test with invalid data
256
+ console.log('\nTesting invalid survey data:');
257
+ const invalidSurvey = [
258
+ {
259
+ respondentId: 1,
260
+ answers: [5, 4, 6, 5, 4], // 6 is out of range (max 5)
261
+ comments: 'Test'
262
+ }
263
+ ];
264
+
265
+ try {
266
+ jsonToCsv(invalidSurvey, { schema: surveySchema });
267
+ } catch (error) {
268
+ console.log('Validation error (expected):', error.message);
269
+ }
270
+ }
271
+
272
+ // =============================================================================
273
+ // Example 5: Conditional Schema (oneOf/anyOf)
274
+ // =============================================================================
275
+
276
+ function conditionalSchema() {
277
+ console.log('\n=== Conditional Schema ===\n');
278
+
279
+ // Schema where payment method determines required fields
280
+ const paymentSchema = {
281
+ type: 'object',
282
+ required: ['paymentId', 'method', 'amount'],
283
+ properties: {
284
+ paymentId: { type: 'string' },
285
+ method: {
286
+ type: 'string',
287
+ enum: ['credit_card', 'bank_transfer', 'crypto']
288
+ },
289
+ amount: {
290
+ type: 'number',
291
+ minimum: 0.01
292
+ },
293
+ // Credit card fields
294
+ cardLast4: {
295
+ type: 'string',
296
+ pattern: '^\\d{4}$'
297
+ },
298
+ // Bank transfer fields
299
+ bankAccount: {
300
+ type: 'string'
301
+ },
302
+ // Crypto fields
303
+ walletAddress: {
304
+ type: 'string',
305
+ pattern: '^0x[a-fA-F0-9]{40}$'
306
+ }
307
+ }
308
+ };
309
+
310
+ const payments = [
311
+ {
312
+ paymentId: 'PAY-001',
313
+ method: 'credit_card',
314
+ amount: 99.99,
315
+ cardLast4: '1234'
316
+ },
317
+ {
318
+ paymentId: 'PAY-002',
319
+ method: 'bank_transfer',
320
+ amount: 500.00,
321
+ bankAccount: 'GB82WEST12345698765432'
322
+ },
323
+ {
324
+ paymentId: 'PAY-003',
325
+ method: 'crypto',
326
+ amount: 250.00,
327
+ walletAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f8e21d'
328
+ }
329
+ ];
330
+
331
+ try {
332
+ const csv = jsonToCsv(payments, { schema: paymentSchema });
333
+ console.log('Payments validated:');
334
+ console.log(csv);
335
+ } catch (error) {
336
+ console.log('Error:', error.message);
337
+ }
338
+ }
339
+
340
+ // =============================================================================
341
+ // Example 6: Schema for Type Coercion Hints
342
+ // =============================================================================
343
+
344
+ function typeCoercionSchema() {
345
+ console.log('\n=== Schema for Type Hints ===\n');
346
+
347
+ // Schema that helps with proper type handling
348
+ const productSchema = {
349
+ type: 'object',
350
+ properties: {
351
+ sku: { type: 'string' },
352
+ name: { type: 'string' },
353
+ price: { type: 'number' },
354
+ quantity: { type: 'integer' },
355
+ isAvailable: { type: 'boolean' },
356
+ tags: {
357
+ type: 'array',
358
+ items: { type: 'string' }
359
+ },
360
+ dimensions: {
361
+ type: 'object',
362
+ properties: {
363
+ width: { type: 'number' },
364
+ height: { type: 'number' },
365
+ depth: { type: 'number' }
366
+ }
367
+ }
368
+ }
369
+ };
370
+
371
+ const products = [
372
+ {
373
+ sku: 'LAPTOP-001',
374
+ name: 'Pro Laptop 15"',
375
+ price: 1299.99,
376
+ quantity: 50,
377
+ isAvailable: true,
378
+ tags: ['electronics', 'computers', 'portable'],
379
+ dimensions: { width: 35.5, height: 1.8, depth: 24.0 }
380
+ }
381
+ ];
382
+
383
+ const csv = jsonToCsv(products, {
384
+ schema: productSchema,
385
+ delimiter: ','
386
+ });
387
+ console.log('Product with type hints:');
388
+ console.log(csv);
389
+ }
390
+
391
+ // =============================================================================
392
+ // Example 7: Validation Error Details
393
+ // =============================================================================
394
+
395
+ function validationErrorDetails() {
396
+ console.log('\n=== Validation Error Details ===\n');
397
+
398
+ const strictSchema = {
399
+ type: 'object',
400
+ additionalProperties: false, // No extra fields allowed
401
+ required: ['id', 'name', 'email', 'role'],
402
+ properties: {
403
+ id: {
404
+ type: 'integer',
405
+ minimum: 1
406
+ },
407
+ name: {
408
+ type: 'string',
409
+ minLength: 2,
410
+ maxLength: 50
411
+ },
412
+ email: {
413
+ type: 'string',
414
+ pattern: '^[^@]+@[^@]+\\.[^@]+$'
415
+ },
416
+ role: {
417
+ type: 'string',
418
+ enum: ['admin', 'user', 'guest']
419
+ }
420
+ }
421
+ };
422
+
423
+ // Data with multiple validation errors
424
+ const invalidData = [
425
+ {
426
+ id: 0, // Error: minimum is 1
427
+ name: 'A', // Error: minLength is 2
428
+ email: 'invalid', // Error: doesn't match pattern
429
+ role: 'superuser', // Error: not in enum
430
+ extra: 'field' // Error: additionalProperties false
431
+ }
432
+ ];
433
+
434
+ try {
435
+ jsonToCsv(invalidData, { schema: strictSchema });
436
+ } catch (error) {
437
+ if (error instanceof ValidationError) {
438
+ console.log('Multiple validation errors detected:');
439
+ console.log('Message:', error.message);
440
+ console.log('Code:', error.code);
441
+ }
442
+ }
443
+ }
444
+
445
+ // =============================================================================
446
+ // Example 8: Schema Validation with CSV Input
447
+ // =============================================================================
448
+
449
+ function schemaValidationOnCsvInput() {
450
+ console.log('\n=== Schema Validation on CSV Input ===\n');
451
+
452
+ const csv = `id,name,score,passed
453
+ 1,Alice,95,true
454
+ 2,Bob,87,true
455
+ 3,Charlie,45,false
456
+ 4,Diana,invalid,true`; // 'invalid' should be a number
457
+
458
+ // First parse CSV
459
+ const data = csvToJson(csv, {
460
+ parseNumbers: true,
461
+ parseBooleans: true
462
+ });
463
+
464
+ console.log('Parsed data:');
465
+ data.forEach(row => {
466
+ console.log(` ${row.name}: score=${row.score} (${typeof row.score})`);
467
+ });
468
+
469
+ // Now validate
470
+ const scoreSchema = {
471
+ type: 'object',
472
+ properties: {
473
+ id: { type: 'number' },
474
+ name: { type: 'string' },
475
+ score: { type: 'number', minimum: 0, maximum: 100 },
476
+ passed: { type: 'boolean' }
477
+ }
478
+ };
479
+
480
+ // Validate each row
481
+ console.log('\nValidation results:');
482
+ data.forEach((row, i) => {
483
+ const isValid = typeof row.score === 'number' &&
484
+ row.score >= 0 && row.score <= 100;
485
+ console.log(` Row ${i + 1} (${row.name}): ${isValid ? 'Valid' : 'Invalid'}`);
486
+ });
487
+ }
488
+
489
+ // =============================================================================
490
+ // Example 9: Reusable Schema Definitions
491
+ // =============================================================================
492
+
493
+ function reusableSchemaDefinitions() {
494
+ console.log('\n=== Reusable Schema Definitions ===\n');
495
+
496
+ // Common field definitions
497
+ const commonFields = {
498
+ id: { type: 'integer', minimum: 1 },
499
+ createdAt: { type: 'string' },
500
+ updatedAt: { type: 'string' }
501
+ };
502
+
503
+ const addressSchema = {
504
+ type: 'object',
505
+ required: ['street', 'city', 'country'],
506
+ properties: {
507
+ street: { type: 'string' },
508
+ city: { type: 'string' },
509
+ postalCode: { type: 'string' },
510
+ country: { type: 'string', minLength: 2, maxLength: 2 } // ISO country code
511
+ }
512
+ };
513
+
514
+ // Customer schema using common fields
515
+ const customerSchema = {
516
+ type: 'object',
517
+ required: ['id', 'name', 'email'],
518
+ properties: {
519
+ ...commonFields,
520
+ name: { type: 'string', minLength: 1 },
521
+ email: { type: 'string' },
522
+ phone: { type: 'string' },
523
+ billingAddress: addressSchema,
524
+ shippingAddress: addressSchema
525
+ }
526
+ };
527
+
528
+ const customers = [
529
+ {
530
+ id: 1,
531
+ name: 'John Doe',
532
+ email: 'john@example.com',
533
+ phone: '+1-555-1234',
534
+ billingAddress: {
535
+ street: '123 Main St',
536
+ city: 'New York',
537
+ postalCode: '10001',
538
+ country: 'US'
539
+ },
540
+ shippingAddress: {
541
+ street: '456 Oak Ave',
542
+ city: 'Brooklyn',
543
+ postalCode: '11201',
544
+ country: 'US'
545
+ },
546
+ createdAt: '2024-01-15T10:00:00Z',
547
+ updatedAt: '2024-01-15T10:00:00Z'
548
+ }
549
+ ];
550
+
551
+ try {
552
+ const csv = jsonToCsv(customers, { schema: customerSchema });
553
+ console.log('Customer data validated with reusable schema:');
554
+ console.log(csv);
555
+ } catch (error) {
556
+ console.log('Error:', error.message);
557
+ }
558
+ }
559
+
560
+ // =============================================================================
561
+ // Example 10: Schema Factory Pattern
562
+ // =============================================================================
563
+
564
+ function schemaFactoryPattern() {
565
+ console.log('\n=== Schema Factory Pattern ===\n');
566
+
567
+ // Schema factory for different entity types
568
+ const createEntitySchema = (entityType, customProperties = {}) => ({
569
+ type: 'object',
570
+ required: ['id', 'type', 'name'],
571
+ properties: {
572
+ id: { type: 'integer', minimum: 1 },
573
+ type: { type: 'string', enum: [entityType] },
574
+ name: { type: 'string', minLength: 1 },
575
+ description: { type: 'string' },
576
+ active: { type: 'boolean' },
577
+ metadata: { type: 'object' },
578
+ ...customProperties
579
+ }
580
+ });
581
+
582
+ // Create specific schemas
583
+ const productSchema = createEntitySchema('product', {
584
+ price: { type: 'number', minimum: 0 },
585
+ sku: { type: 'string', pattern: '^[A-Z]{3}-\\d{4}$' },
586
+ category: { type: 'string' }
587
+ });
588
+
589
+ const serviceSchema = createEntitySchema('service', {
590
+ hourlyRate: { type: 'number', minimum: 0 },
591
+ duration: { type: 'integer', minimum: 1 },
592
+ availability: { type: 'string', enum: ['available', 'busy', 'unavailable'] }
593
+ });
594
+
595
+ console.log('Product schema created:', Object.keys(productSchema.properties));
596
+ console.log('Service schema created:', Object.keys(serviceSchema.properties));
597
+
598
+ // Validate data
599
+ const product = {
600
+ id: 1,
601
+ type: 'product',
602
+ name: 'Widget Pro',
603
+ price: 29.99,
604
+ sku: 'WGT-0001',
605
+ category: 'widgets',
606
+ active: true
607
+ };
608
+
609
+ try {
610
+ const csv = jsonToCsv([product], { schema: productSchema });
611
+ console.log('\nProduct validated successfully');
612
+ } catch (error) {
613
+ console.log('Error:', error.message);
614
+ }
615
+ }
616
+
617
+ // =============================================================================
618
+ // Run All Examples
619
+ // =============================================================================
620
+
621
+ async function main() {
622
+ console.log('jtcsv Schema Validation Examples');
623
+ console.log('='.repeat(60));
624
+
625
+ basicSchemaValidation();
626
+ nestedSchemaValidation();
627
+ customFormatSchema();
628
+ arraySchemaValidation();
629
+ conditionalSchema();
630
+ typeCoercionSchema();
631
+ validationErrorDetails();
632
+ schemaValidationOnCsvInput();
633
+ reusableSchemaDefinitions();
634
+ schemaFactoryPattern();
635
+
636
+ console.log('\n' + '='.repeat(60));
637
+ console.log('All schema validation examples completed.');
638
+ }
639
+
640
+ main().catch(console.error);
@@ -8,6 +8,7 @@
8
8
  * @date 2026-01-22
9
9
  */
10
10
 
11
+ ;(async () => {
11
12
  console.log('🚀 JTCSV 2.1.0 - Демонстрация новых возможностей\n');
12
13
 
13
14
  // ============================================================================
@@ -17,7 +18,7 @@ console.log('🚀 JTCSV 2.1.0 - Демонстрация новых возмож
17
18
  console.log('1. 📦 Базовое использование (обратная совместимость)');
18
19
  console.log('='.repeat(60));
19
20
 
20
- const { jsonToCsv, csvToJson } = require('jtcsv
21
+ const { jsonToCsv, csvToJson } = require('jtcsv');
21
22
 
22
23
  const sampleData = [
23
24
  { id: 1, name: 'John Doe', age: 30, city: 'New York' },
@@ -44,7 +45,7 @@ console.log();
44
45
  console.log('\n2. ⚡ Fast-Path Engine (оптимизированный парсинг)');
45
46
  console.log('='.repeat(60));
46
47
 
47
- const { FastPathEngine } = require('../src/engines/fast-path-engine');
48
+ const FastPathEngine = require('../src/engines/fast-path-engine');
48
49
  const engine = new FastPathEngine();
49
50
 
50
51
  // Создаем тестовый CSV
@@ -87,7 +88,7 @@ console.log(` Hit rate: ${(stats.hitRate * 100).toFixed(1)}%`);
87
88
  console.log('\n3. 📝 NDJSON поддержка (потоковая обработка)');
88
89
  console.log('='.repeat(60));
89
90
 
90
- const { NdjsonParser } = require('../src/formats/ndjson-parser');
91
+ const NdjsonParser = require('../src/formats/ndjson-parser');
91
92
 
92
93
  // Конвертация в NDJSON
93
94
  const ndjson = NdjsonParser.toNdjson(sampleData, { space: 2 });
@@ -115,7 +116,7 @@ console.log(` Успешность: ${ndjsonStats.successRate}%`);
115
116
  console.log('\n4. 🔌 Plugin System (расширяемость)');
116
117
  console.log('='.repeat(60));
117
118
 
118
- const { PluginManager } = require('../src/core/plugin-system');
119
+ const PluginManager = require('../src/core/plugin-system');
119
120
 
120
121
  // Создаем простой плагин для логирования
121
122
  const loggingPlugin = {
@@ -265,7 +266,7 @@ console.log('3. Попробуйте примеры: npm run example:plugins');
265
266
  console.log('4. Создайте свой плагин!');
266
267
 
267
268
  console.log('\n💡 Совет: Для production используйте:');
268
- console.log(' const jtcsv = require("jtcsv.create();');
269
+ console.log(' const jtcsv = require("jtcsv/plugins").create();');
269
270
  console.log(' jtcsv.use("your-plugin", yourPluginConfig);');
270
271
 
271
272
  console.log('\n📚 Документация: https://github.com/Linol-Hamelton/jtcsv');
@@ -275,5 +276,7 @@ console.log('⭐ Star на GitHub если понравилось!');
275
276
  console.log('\n' + '✨'.repeat(30));
276
277
  console.log('✨ JTCSV 2.1.0 - Next Generation JSON/CSV Converter ✨');
277
278
  console.log('✨'.repeat(30));
278
-
279
-
279
+ })().catch((error) => {
280
+ console.error('Demo failed:', error);
281
+ process.exitCode = 1;
282
+ });