toon-formatter 1.1.1 → 2.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.
- package/CHANGELOG.md +95 -0
- package/README.md +532 -5
- package/package.json +11 -4
- package/src/encryptor.js +244 -0
- package/src/index.js +350 -10
- package/src/json.js +9 -7
- package/.github/FUNDING.yml +0 -15
- package/ENHANCEMENTS.md +0 -124
- package/test/basic.test.js +0 -139
- package/test/converters.test.js +0 -135
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [2.0.0] - 2025-12-08
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **🔐 End-to-End Encryption Support**
|
|
12
|
+
- New `Encryptor` class with AES-256-GCM, XOR, and Base64 algorithms
|
|
13
|
+
- `Encryptor.generateKey()` static method for secure key generation
|
|
14
|
+
- Instance-based `ToonConverter` API with encryption support
|
|
15
|
+
- Four conversion modes: `no_encryption`, `middleware`, `ingestion`, `export`
|
|
16
|
+
- Comprehensive encryption documentation and examples
|
|
17
|
+
|
|
18
|
+
- **New Features**
|
|
19
|
+
- `returnJson` parameter for `toJson()` and `toJsonAsync()` methods
|
|
20
|
+
- Support for encrypted data pipelines
|
|
21
|
+
- Key rotation capabilities
|
|
22
|
+
- Authentication tag validation (AES-256-GCM)
|
|
23
|
+
|
|
24
|
+
- **Testing**
|
|
25
|
+
- 33 new encryption unit tests
|
|
26
|
+
- 32 new integration tests
|
|
27
|
+
- 8 backward compatibility tests
|
|
28
|
+
- Total: 96 tests (all passing)
|
|
29
|
+
|
|
30
|
+
- **Documentation**
|
|
31
|
+
- Complete encryption guide in README
|
|
32
|
+
- Security best practices
|
|
33
|
+
- Real-world examples
|
|
34
|
+
- Migration guide
|
|
35
|
+
- API reference for Encryptor and ToonConverter
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
- `ToonConverter` now supports both static methods (backward compatible) and instance methods (with encryption)
|
|
39
|
+
- `toonToJsonSync()` and `toonToJson()` now accept optional `returnJson` parameter
|
|
40
|
+
- Updated package description to mention encryption support
|
|
41
|
+
- Enhanced package keywords for better discoverability
|
|
42
|
+
|
|
43
|
+
### Backward Compatibility
|
|
44
|
+
- ✅ All existing static methods work exactly as before
|
|
45
|
+
- ✅ Default behavior unchanged (`returnJson=false`)
|
|
46
|
+
- ✅ No breaking changes for existing users
|
|
47
|
+
- ✅ Full backward compatibility maintained
|
|
48
|
+
|
|
49
|
+
### Security
|
|
50
|
+
- AES-256-GCM encryption with random IV per operation
|
|
51
|
+
- Authentication tag prevents data tampering
|
|
52
|
+
- Secure key generation using Node.js crypto
|
|
53
|
+
- No external cryptographic dependencies
|
|
54
|
+
|
|
55
|
+
## [1.1.1] - Previous Release
|
|
56
|
+
|
|
57
|
+
### Features
|
|
58
|
+
- JSON, YAML, XML, CSV conversion support
|
|
59
|
+
- Mixed text extraction
|
|
60
|
+
- Synchronous and asynchronous APIs
|
|
61
|
+
- TOON validation
|
|
62
|
+
- Comprehensive test suite
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Migration Guide
|
|
67
|
+
|
|
68
|
+
### From v1.x to v2.0
|
|
69
|
+
|
|
70
|
+
**No changes required!** Version 2.0 is fully backward compatible.
|
|
71
|
+
|
|
72
|
+
**To use new encryption features:**
|
|
73
|
+
|
|
74
|
+
```javascript
|
|
75
|
+
// Old code (still works)
|
|
76
|
+
import { ToonConverter } from 'toon-formatter';
|
|
77
|
+
const toon = ToonConverter.fromJson(data);
|
|
78
|
+
|
|
79
|
+
// New code (with encryption)
|
|
80
|
+
import { ToonConverter, Encryptor } from 'toon-formatter';
|
|
81
|
+
const key = Encryptor.generateKey();
|
|
82
|
+
const encryptor = new Encryptor(key, 'aes-256-gcm');
|
|
83
|
+
const converter = new ToonConverter(encryptor);
|
|
84
|
+
const encrypted = converter.fromJson(data, { conversionMode: 'export' });
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**To use returnJson parameter:**
|
|
88
|
+
|
|
89
|
+
```javascript
|
|
90
|
+
// Returns object (default, backward compatible)
|
|
91
|
+
const obj = ToonConverter.toJson(toonString);
|
|
92
|
+
|
|
93
|
+
// Returns JSON string (new feature)
|
|
94
|
+
const jsonString = ToonConverter.toJson(toonString, true);
|
|
95
|
+
```
|
package/README.md
CHANGED
|
@@ -288,9 +288,374 @@ console.log(converted);
|
|
|
288
288
|
// price: 29.99
|
|
289
289
|
```
|
|
290
290
|
|
|
291
|
+
```
|
|
292
|
+
|
|
291
293
|
---
|
|
292
294
|
|
|
293
|
-
##
|
|
295
|
+
## 🔐 Encryption Support
|
|
296
|
+
|
|
297
|
+
**NEW in v2.0.0**: The TOON Converter now supports end-to-end encryption for secure data transmission and storage!
|
|
298
|
+
|
|
299
|
+
### Overview
|
|
300
|
+
|
|
301
|
+
The encryption feature allows you to:
|
|
302
|
+
- **Encrypt data before transmission** to protect sensitive information
|
|
303
|
+
- **Store encrypted TOON data** securely
|
|
304
|
+
- **Process encrypted data** without exposing plaintext
|
|
305
|
+
- **Support multiple encryption algorithms**: AES-256-GCM, XOR, Base64
|
|
306
|
+
|
|
307
|
+
### Quick Start with Encryption
|
|
308
|
+
|
|
309
|
+
```javascript
|
|
310
|
+
import { ToonConverter, Encryptor } from 'toon-formatter';
|
|
311
|
+
|
|
312
|
+
// 1. Generate a secure encryption key
|
|
313
|
+
const key = Encryptor.generateKey(); // 32-byte key for AES-256-GCM
|
|
314
|
+
|
|
315
|
+
// 2. Create an encryptor
|
|
316
|
+
const encryptor = new Encryptor(key, 'aes-256-gcm');
|
|
317
|
+
|
|
318
|
+
// 3. Create a converter with encryption support
|
|
319
|
+
const converter = new ToonConverter(encryptor);
|
|
320
|
+
|
|
321
|
+
// 4. Convert and encrypt data
|
|
322
|
+
const data = { user: "Alice", role: "admin" };
|
|
323
|
+
const encryptedToon = converter.fromJson(data, {
|
|
324
|
+
conversionMode: 'export'
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
console.log(encryptedToon); // Encrypted string
|
|
328
|
+
|
|
329
|
+
// 5. Decrypt and convert back
|
|
330
|
+
const decrypted = encryptor.decrypt(encryptedToon);
|
|
331
|
+
console.log(decrypted); // Plain TOON string
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Encryption Algorithms
|
|
335
|
+
|
|
336
|
+
#### AES-256-GCM (Recommended)
|
|
337
|
+
High-security authenticated encryption with Galois/Counter Mode.
|
|
338
|
+
|
|
339
|
+
```javascript
|
|
340
|
+
const key = Encryptor.generateKey(); // Generates 32-byte key
|
|
341
|
+
const encryptor = new Encryptor(key, 'aes-256-gcm');
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
**Features:**
|
|
345
|
+
- ✅ Military-grade encryption
|
|
346
|
+
- ✅ Authentication tag prevents tampering
|
|
347
|
+
- ✅ Random IV for each encryption
|
|
348
|
+
- ✅ No external dependencies (uses Node.js crypto)
|
|
349
|
+
|
|
350
|
+
#### XOR Cipher
|
|
351
|
+
Simple obfuscation (not cryptographically secure).
|
|
352
|
+
|
|
353
|
+
```javascript
|
|
354
|
+
const encryptor = new Encryptor('my-secret-key', 'xor');
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
**Use cases:**
|
|
358
|
+
- Quick obfuscation
|
|
359
|
+
- Non-sensitive data
|
|
360
|
+
- Deterministic encryption
|
|
361
|
+
|
|
362
|
+
#### Base64 Encoding
|
|
363
|
+
Simple encoding (not encryption).
|
|
364
|
+
|
|
365
|
+
```javascript
|
|
366
|
+
const encryptor = new Encryptor(null, 'base64');
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
**Use cases:**
|
|
370
|
+
- Data encoding
|
|
371
|
+
- Testing
|
|
372
|
+
- Non-sensitive transformations
|
|
373
|
+
|
|
374
|
+
### Conversion Modes
|
|
375
|
+
|
|
376
|
+
The encryption system supports **4 conversion modes** for different data flow scenarios:
|
|
377
|
+
|
|
378
|
+
#### 1. `no_encryption` (Default)
|
|
379
|
+
No encryption applied - standard conversion.
|
|
380
|
+
|
|
381
|
+
```javascript
|
|
382
|
+
const converter = new ToonConverter(encryptor);
|
|
383
|
+
const toon = converter.fromJson(data); // Plain TOON
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
#### 2. `middleware` Mode
|
|
387
|
+
**Encrypted → Encrypted** (Decrypt → Convert → Re-encrypt)
|
|
388
|
+
|
|
389
|
+
Perfect for middleware services that need to convert format without exposing data.
|
|
390
|
+
|
|
391
|
+
```javascript
|
|
392
|
+
// Input: Encrypted JSON
|
|
393
|
+
const encryptedJson = '...'; // From client
|
|
394
|
+
|
|
395
|
+
// Convert to encrypted TOON (never see plaintext)
|
|
396
|
+
const encryptedToon = converter.fromJson(encryptedJson, {
|
|
397
|
+
conversionMode: 'middleware'
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
// Output: Encrypted TOON (can be stored or forwarded)
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
**Use case:** API gateway converting encrypted client data to encrypted storage format.
|
|
404
|
+
|
|
405
|
+
#### 3. `ingestion` Mode
|
|
406
|
+
**Encrypted → Plain** (Decrypt → Convert)
|
|
407
|
+
|
|
408
|
+
For ingesting encrypted data into your system.
|
|
409
|
+
|
|
410
|
+
```javascript
|
|
411
|
+
// Input: Encrypted JSON from external source
|
|
412
|
+
const encryptedJson = '...';
|
|
413
|
+
|
|
414
|
+
// Convert to plain TOON for processing
|
|
415
|
+
const plainToon = converter.fromJson(encryptedJson, {
|
|
416
|
+
conversionMode: 'ingestion'
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
// Output: Plain TOON (ready for processing)
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
**Use case:** Receiving encrypted data from clients and converting to internal format.
|
|
423
|
+
|
|
424
|
+
#### 4. `export` Mode
|
|
425
|
+
**Plain → Encrypted** (Convert → Encrypt)
|
|
426
|
+
|
|
427
|
+
For exporting data securely.
|
|
428
|
+
|
|
429
|
+
```javascript
|
|
430
|
+
// Input: Plain JSON data
|
|
431
|
+
const data = { user: "Alice", role: "admin" };
|
|
432
|
+
|
|
433
|
+
// Convert and encrypt for transmission
|
|
434
|
+
const encryptedToon = converter.fromJson(data, {
|
|
435
|
+
conversionMode: 'export'
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
// Output: Encrypted TOON (safe to transmit)
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
**Use case:** Sending data to external systems or clients securely.
|
|
442
|
+
|
|
443
|
+
### Real-World Example: Secure API Pipeline
|
|
444
|
+
|
|
445
|
+
```javascript
|
|
446
|
+
import { ToonConverter, Encryptor } from 'toon-formatter';
|
|
447
|
+
|
|
448
|
+
// Setup (same key on client and server)
|
|
449
|
+
const key = Encryptor.generateKey();
|
|
450
|
+
const encryptor = new Encryptor(key, 'aes-256-gcm');
|
|
451
|
+
|
|
452
|
+
// CLIENT SIDE
|
|
453
|
+
// ============
|
|
454
|
+
const clientConverter = new ToonConverter(encryptor);
|
|
455
|
+
|
|
456
|
+
// 1. User submits sensitive data
|
|
457
|
+
const userData = {
|
|
458
|
+
ssn: "123-45-6789",
|
|
459
|
+
creditCard: "4111-1111-1111-1111",
|
|
460
|
+
email: "alice@example.com"
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
// 2. Encrypt before sending
|
|
464
|
+
const encryptedPayload = encryptor.encrypt(JSON.stringify(userData));
|
|
465
|
+
|
|
466
|
+
// 3. Send to server
|
|
467
|
+
await fetch('/api/user', {
|
|
468
|
+
method: 'POST',
|
|
469
|
+
body: encryptedPayload
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
// SERVER SIDE (Middleware)
|
|
473
|
+
// =========================
|
|
474
|
+
const serverConverter = new ToonConverter(encryptor);
|
|
475
|
+
|
|
476
|
+
// 4. Receive encrypted data
|
|
477
|
+
const encryptedJson = await request.text();
|
|
478
|
+
|
|
479
|
+
// 5. Convert to encrypted TOON for storage (middleware mode)
|
|
480
|
+
const encryptedToon = serverConverter.fromJson(encryptedJson, {
|
|
481
|
+
conversionMode: 'middleware'
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
// 6. Store encrypted TOON in database
|
|
485
|
+
await db.save(encryptedToon);
|
|
486
|
+
|
|
487
|
+
// SERVER SIDE (Processing)
|
|
488
|
+
// =========================
|
|
489
|
+
// 7. Retrieve encrypted TOON
|
|
490
|
+
const storedToon = await db.get(userId);
|
|
491
|
+
|
|
492
|
+
// 8. Convert back to plain JSON for processing (ingestion mode)
|
|
493
|
+
const plainData = serverConverter.toJson(storedToon, {
|
|
494
|
+
conversionMode: 'ingestion',
|
|
495
|
+
returnJson: true
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
// 9. Process data
|
|
499
|
+
const user = JSON.parse(plainData);
|
|
500
|
+
console.log(user.email); // alice@example.com
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
### Working with `returnJson` Parameter
|
|
504
|
+
|
|
505
|
+
By default, `toJson()` returns a JavaScript object. For encryption modes, you need a string. Use `returnJson: true`:
|
|
506
|
+
|
|
507
|
+
```javascript
|
|
508
|
+
// Returns object (default)
|
|
509
|
+
const obj = converter.toJson(toonString);
|
|
510
|
+
console.log(obj); // { name: "Alice" }
|
|
511
|
+
|
|
512
|
+
// Returns JSON string (for encryption)
|
|
513
|
+
const jsonString = converter.toJson(toonString, { returnJson: true });
|
|
514
|
+
console.log(jsonString); // '{"name":"Alice"}'
|
|
515
|
+
|
|
516
|
+
// With encryption
|
|
517
|
+
const encrypted = converter.toJson(toonString, {
|
|
518
|
+
conversionMode: 'export',
|
|
519
|
+
returnJson: true // Required for encryption!
|
|
520
|
+
});
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
### Key Management Best Practices
|
|
524
|
+
|
|
525
|
+
#### 🔑 Generating Keys
|
|
526
|
+
|
|
527
|
+
```javascript
|
|
528
|
+
// Generate a secure random key
|
|
529
|
+
const key = Encryptor.generateKey();
|
|
530
|
+
|
|
531
|
+
// Store as Base64 (e.g., in environment variables)
|
|
532
|
+
const keyBase64 = key.toString('base64');
|
|
533
|
+
process.env.ENCRYPTION_KEY = keyBase64;
|
|
534
|
+
|
|
535
|
+
// Load from storage
|
|
536
|
+
const loadedKey = Buffer.from(process.env.ENCRYPTION_KEY, 'base64');
|
|
537
|
+
const encryptor = new Encryptor(loadedKey, 'aes-256-gcm');
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
#### 🔒 Security Best Practices
|
|
541
|
+
|
|
542
|
+
1. **Never hardcode keys** in source code
|
|
543
|
+
2. **Use environment variables** or secure key management systems
|
|
544
|
+
3. **Rotate keys periodically** for long-term security
|
|
545
|
+
4. **Use AES-256-GCM** for production (not XOR or Base64)
|
|
546
|
+
5. **Protect keys at rest** with proper file permissions
|
|
547
|
+
6. **Use HTTPS** for transmitting encrypted data
|
|
548
|
+
7. **Implement key rotation** strategy
|
|
549
|
+
|
|
550
|
+
#### 🔄 Key Rotation Example
|
|
551
|
+
|
|
552
|
+
```javascript
|
|
553
|
+
// Old system
|
|
554
|
+
const oldKey = Buffer.from(process.env.OLD_KEY, 'base64');
|
|
555
|
+
const oldEncryptor = new Encryptor(oldKey, 'aes-256-gcm');
|
|
556
|
+
|
|
557
|
+
// New system
|
|
558
|
+
const newKey = Encryptor.generateKey();
|
|
559
|
+
const newEncryptor = new Encryptor(newKey, 'aes-256-gcm');
|
|
560
|
+
|
|
561
|
+
// Migrate data
|
|
562
|
+
const encryptedData = await db.getAllEncrypted();
|
|
563
|
+
|
|
564
|
+
for (const item of encryptedData) {
|
|
565
|
+
// Decrypt with old key
|
|
566
|
+
const plaintext = oldEncryptor.decrypt(item.data);
|
|
567
|
+
|
|
568
|
+
// Re-encrypt with new key
|
|
569
|
+
const reEncrypted = newEncryptor.encrypt(plaintext);
|
|
570
|
+
|
|
571
|
+
// Update database
|
|
572
|
+
await db.update(item.id, reEncrypted);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
// Update environment variable
|
|
576
|
+
process.env.ENCRYPTION_KEY = newKey.toString('base64');
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
### Error Handling
|
|
580
|
+
|
|
581
|
+
```javascript
|
|
582
|
+
try {
|
|
583
|
+
const encrypted = encryptor.encrypt(data);
|
|
584
|
+
const decrypted = encryptor.decrypt(encrypted);
|
|
585
|
+
} catch (error) {
|
|
586
|
+
if (error.message.includes('decryption failed')) {
|
|
587
|
+
console.error('Wrong key or tampered data');
|
|
588
|
+
} else if (error.message.includes('Invalid encrypted data format')) {
|
|
589
|
+
console.error('Corrupted ciphertext');
|
|
590
|
+
} else {
|
|
591
|
+
console.error('Encryption error:', error.message);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
### Async Encryption
|
|
597
|
+
|
|
598
|
+
All encryption operations work with async methods:
|
|
599
|
+
|
|
600
|
+
```javascript
|
|
601
|
+
const converter = new ToonConverter(encryptor);
|
|
602
|
+
|
|
603
|
+
// Async conversion with encryption
|
|
604
|
+
const encrypted = await converter.fromJsonAsync(data, {
|
|
605
|
+
conversionMode: 'export'
|
|
606
|
+
});
|
|
607
|
+
|
|
608
|
+
const decrypted = await converter.toJsonAsync(encrypted, {
|
|
609
|
+
conversionMode: 'ingestion',
|
|
610
|
+
returnJson: true
|
|
611
|
+
});
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
### Migration Guide
|
|
615
|
+
|
|
616
|
+
#### From Static to Instance API
|
|
617
|
+
|
|
618
|
+
**Before (no encryption):**
|
|
619
|
+
```javascript
|
|
620
|
+
import { ToonConverter } from 'toon-formatter';
|
|
621
|
+
|
|
622
|
+
const toon = ToonConverter.fromJson(data);
|
|
623
|
+
const json = ToonConverter.toJson(toon);
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
**After (with encryption):**
|
|
627
|
+
```javascript
|
|
628
|
+
import { ToonConverter, Encryptor } from 'toon-formatter';
|
|
629
|
+
|
|
630
|
+
// Create encryptor
|
|
631
|
+
const key = Encryptor.generateKey();
|
|
632
|
+
const encryptor = new Encryptor(key, 'aes-256-gcm');
|
|
633
|
+
|
|
634
|
+
// Create converter instance
|
|
635
|
+
const converter = new ToonConverter(encryptor);
|
|
636
|
+
|
|
637
|
+
// Use instance methods
|
|
638
|
+
const encrypted = converter.fromJson(data, { conversionMode: 'export' });
|
|
639
|
+
const plain = converter.toJson(encrypted, { conversionMode: 'ingestion' });
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
**Note:** Static methods still work for backward compatibility (no encryption).
|
|
643
|
+
|
|
644
|
+
### Performance Considerations
|
|
645
|
+
|
|
646
|
+
- **AES-256-GCM**: ~0.5-1ms per operation (recommended)
|
|
647
|
+
- **XOR**: ~0.1ms per operation (fast but insecure)
|
|
648
|
+
- **Base64**: ~0.05ms per operation (fastest, no security)
|
|
649
|
+
|
|
650
|
+
For high-throughput applications, consider:
|
|
651
|
+
- Batch processing
|
|
652
|
+
- Caching decrypted data (with proper TTL)
|
|
653
|
+
- Using middleware mode to avoid double encryption/decryption
|
|
654
|
+
|
|
655
|
+
---
|
|
656
|
+
|
|
657
|
+
## 📚 API Reference
|
|
658
|
+
|
|
294
659
|
|
|
295
660
|
### JSON Converters
|
|
296
661
|
|
|
@@ -335,25 +700,27 @@ Converts JSON data to TOON format (asynchronous).
|
|
|
335
700
|
|
|
336
701
|
**Returns:** `Promise<string>` - TOON formatted string
|
|
337
702
|
|
|
338
|
-
#### `toonToJsonSync(toonString)`
|
|
703
|
+
#### `toonToJsonSync(toonString, returnJson?)`
|
|
339
704
|
Converts TOON string to JSON (synchronous).
|
|
340
705
|
|
|
341
706
|
**Supports:** ❌ Pure TOON data only (no mixed text)
|
|
342
707
|
|
|
343
708
|
**Parameters:**
|
|
344
709
|
- `toonString` (string): TOON formatted string
|
|
710
|
+
- `returnJson` (boolean, optional): If `true`, returns JSON string; if `false` (default), returns object
|
|
345
711
|
|
|
346
|
-
**Returns:** `any` - Parsed JSON data
|
|
712
|
+
**Returns:** `any | string` - Parsed JSON data (object by default, string if `returnJson=true`)
|
|
347
713
|
|
|
348
|
-
#### `toonToJson(toonString)`
|
|
714
|
+
#### `toonToJson(toonString, returnJson?)`
|
|
349
715
|
Converts TOON string to JSON (asynchronous).
|
|
350
716
|
|
|
351
717
|
**Supports:** ❌ Pure TOON data only (no mixed text)
|
|
352
718
|
|
|
353
719
|
**Parameters:**
|
|
354
720
|
- `toonString` (string): TOON formatted string
|
|
721
|
+
- `returnJson` (boolean, optional): If `true`, returns JSON string; if `false` (default), returns object
|
|
355
722
|
|
|
356
|
-
**Returns:** `Promise<any>` - Parsed JSON data
|
|
723
|
+
**Returns:** `Promise<any | string>` - Parsed JSON data (object by default, string if `returnJson=true`)
|
|
357
724
|
|
|
358
725
|
---
|
|
359
726
|
|
|
@@ -554,6 +921,166 @@ Validates a TOON string for syntax and structural correctness (asynchronous).
|
|
|
554
921
|
|
|
555
922
|
---
|
|
556
923
|
|
|
924
|
+
|
|
925
|
+
---
|
|
926
|
+
|
|
927
|
+
### Encryptor Class
|
|
928
|
+
|
|
929
|
+
The `Encryptor` class provides encryption and decryption capabilities.
|
|
930
|
+
|
|
931
|
+
#### `new Encryptor(key, algorithm)`
|
|
932
|
+
Creates a new Encryptor instance.
|
|
933
|
+
|
|
934
|
+
**Parameters:**
|
|
935
|
+
- `key` (Buffer | string | null): Encryption key
|
|
936
|
+
- For `aes-256-gcm`: 32-byte Buffer (use `Encryptor.generateKey()`)
|
|
937
|
+
- For `xor`: String or Buffer
|
|
938
|
+
- For `base64`: null (no key needed)
|
|
939
|
+
- `algorithm` (string): Encryption algorithm - `'aes-256-gcm'`, `'xor'`, or `'base64'`
|
|
940
|
+
|
|
941
|
+
**Example:**
|
|
942
|
+
```javascript
|
|
943
|
+
// AES-256-GCM (recommended)
|
|
944
|
+
const key = Encryptor.generateKey();
|
|
945
|
+
const encryptor = new Encryptor(key, 'aes-256-gcm');
|
|
946
|
+
|
|
947
|
+
// XOR
|
|
948
|
+
const xorEncryptor = new Encryptor('my-secret-key', 'xor');
|
|
949
|
+
|
|
950
|
+
// Base64
|
|
951
|
+
const base64Encryptor = new Encryptor(null, 'base64');
|
|
952
|
+
```
|
|
953
|
+
|
|
954
|
+
#### `Encryptor.generateKey()`
|
|
955
|
+
Static method to generate a secure 32-byte encryption key for AES-256-GCM.
|
|
956
|
+
|
|
957
|
+
**Returns:** `Buffer` - 32-byte random key
|
|
958
|
+
|
|
959
|
+
**Example:**
|
|
960
|
+
```javascript
|
|
961
|
+
const key = Encryptor.generateKey();
|
|
962
|
+
console.log(key.length); // 32
|
|
963
|
+
|
|
964
|
+
// Store as Base64
|
|
965
|
+
const keyBase64 = key.toString('base64');
|
|
966
|
+
process.env.ENCRYPTION_KEY = keyBase64;
|
|
967
|
+
|
|
968
|
+
// Load from Base64
|
|
969
|
+
const loadedKey = Buffer.from(process.env.ENCRYPTION_KEY, 'base64');
|
|
970
|
+
```
|
|
971
|
+
|
|
972
|
+
#### `encryptor.encrypt(data)`
|
|
973
|
+
Encrypts a string.
|
|
974
|
+
|
|
975
|
+
**Parameters:**
|
|
976
|
+
- `data` (string): Plaintext string to encrypt
|
|
977
|
+
|
|
978
|
+
**Returns:** `string` - Encrypted string (hex-encoded for AES-256-GCM and XOR, Base64 for base64)
|
|
979
|
+
|
|
980
|
+
**Throws:** Error if data is not a string or key is missing (for AES/XOR)
|
|
981
|
+
|
|
982
|
+
**Example:**
|
|
983
|
+
```javascript
|
|
984
|
+
const encrypted = encryptor.encrypt('Hello, World!');
|
|
985
|
+
console.log(encrypted); // Hex string (AES-256-GCM)
|
|
986
|
+
```
|
|
987
|
+
|
|
988
|
+
#### `encryptor.decrypt(encryptedData)`
|
|
989
|
+
Decrypts an encrypted string.
|
|
990
|
+
|
|
991
|
+
**Parameters:**
|
|
992
|
+
- `encryptedData` (string): Encrypted string
|
|
993
|
+
|
|
994
|
+
**Returns:** `string` - Decrypted plaintext
|
|
995
|
+
|
|
996
|
+
**Throws:** Error if decryption fails, wrong key, or tampered data
|
|
997
|
+
|
|
998
|
+
**Example:**
|
|
999
|
+
```javascript
|
|
1000
|
+
const decrypted = encryptor.decrypt(encrypted);
|
|
1001
|
+
console.log(decrypted); // 'Hello, World!'
|
|
1002
|
+
```
|
|
1003
|
+
|
|
1004
|
+
---
|
|
1005
|
+
|
|
1006
|
+
### ToonConverter Class (with Encryption)
|
|
1007
|
+
|
|
1008
|
+
The `ToonConverter` class now supports both static methods (backward compatible) and instance methods (with encryption).
|
|
1009
|
+
|
|
1010
|
+
#### `new ToonConverter(encryptor?)`
|
|
1011
|
+
Creates a new ToonConverter instance.
|
|
1012
|
+
|
|
1013
|
+
**Parameters:**
|
|
1014
|
+
- `encryptor` (Encryptor | null, optional): Encryptor instance for encryption support
|
|
1015
|
+
|
|
1016
|
+
**Example:**
|
|
1017
|
+
```javascript
|
|
1018
|
+
// Without encryption
|
|
1019
|
+
const converter = new ToonConverter();
|
|
1020
|
+
|
|
1021
|
+
// With encryption
|
|
1022
|
+
const key = Encryptor.generateKey();
|
|
1023
|
+
const encryptor = new Encryptor(key, 'aes-256-gcm');
|
|
1024
|
+
const converter = new ToonConverter(encryptor);
|
|
1025
|
+
```
|
|
1026
|
+
|
|
1027
|
+
#### Instance Methods with Encryption Support
|
|
1028
|
+
|
|
1029
|
+
All instance methods accept an `options` object with:
|
|
1030
|
+
- `conversionMode` (string): `'no_encryption'` (default), `'middleware'`, `'ingestion'`, or `'export'`
|
|
1031
|
+
- `returnJson` (boolean, for `toJson` methods): If `true`, returns JSON string; if `false` (default), returns object
|
|
1032
|
+
|
|
1033
|
+
**Example:**
|
|
1034
|
+
```javascript
|
|
1035
|
+
// fromJson with encryption
|
|
1036
|
+
const encrypted = converter.fromJson(data, {
|
|
1037
|
+
conversionMode: 'export'
|
|
1038
|
+
});
|
|
1039
|
+
|
|
1040
|
+
// toJson with encryption and JSON string output
|
|
1041
|
+
const jsonString = converter.toJson(toonString, {
|
|
1042
|
+
conversionMode: 'ingestion',
|
|
1043
|
+
returnJson: true
|
|
1044
|
+
});
|
|
1045
|
+
|
|
1046
|
+
// fromYaml with middleware mode
|
|
1047
|
+
const encryptedToon = converter.fromYaml(encryptedYaml, {
|
|
1048
|
+
conversionMode: 'middleware'
|
|
1049
|
+
});
|
|
1050
|
+
```
|
|
1051
|
+
|
|
1052
|
+
**Available instance methods:**
|
|
1053
|
+
- `fromJson(data, options?)` / `fromJsonAsync(data, options?)`
|
|
1054
|
+
- `toJson(toonString, options?)` / `toJsonAsync(toonString, options?)`
|
|
1055
|
+
- `fromYaml(yamlString, options?)` / `fromYamlAsync(yamlString, options?)`
|
|
1056
|
+
- `toYaml(toonString, options?)` / `toYamlAsync(toonString, options?)`
|
|
1057
|
+
- `fromXml(xmlString, options?)` / `fromXmlAsync(xmlString, options?)`
|
|
1058
|
+
- `toXml(toonString, options?)` / `toXmlAsync(toonString, options?)`
|
|
1059
|
+
- `fromCsv(csvString, options?)` / `fromCsvAsync(csvString, options?)`
|
|
1060
|
+
- `toCsv(toonString, options?)` / `toCsvAsync(toonString, options?)`
|
|
1061
|
+
- `validate(toonString)` / `validateAsync(toonString)`
|
|
1062
|
+
|
|
1063
|
+
#### Static Methods (Backward Compatible)
|
|
1064
|
+
|
|
1065
|
+
Static methods work exactly as before, with no encryption support:
|
|
1066
|
+
|
|
1067
|
+
```javascript
|
|
1068
|
+
// Static usage (no encryption)
|
|
1069
|
+
const toon = ToonConverter.fromJson(data);
|
|
1070
|
+
const json = ToonConverter.toJson(toon);
|
|
1071
|
+
|
|
1072
|
+
// Static with returnJson parameter
|
|
1073
|
+
const jsonString = ToonConverter.toJson(toon, true);
|
|
1074
|
+
```
|
|
1075
|
+
|
|
1076
|
+
**Note:** For `toJson` and `toJsonAsync` static methods, you can pass `returnJson` as the second parameter:
|
|
1077
|
+
```javascript
|
|
1078
|
+
ToonConverter.toJson(toonString, returnJson?)
|
|
1079
|
+
ToonConverter.toJsonAsync(toonString, returnJson?)
|
|
1080
|
+
```
|
|
1081
|
+
|
|
1082
|
+
---
|
|
1083
|
+
|
|
557
1084
|
## 🎨 TOON Format Guide
|
|
558
1085
|
|
|
559
1086
|
### Primitives
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toon-formatter",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"funding": {
|
|
5
5
|
"type": "github",
|
|
6
6
|
"url": "https://github.com/sponsors/ankitpal181"
|
|
7
7
|
},
|
|
8
|
-
"description": "A lightweight library to convert between TOON (Token-Oriented Object Notation) and popular data formats (JSON, YAML, XML, CSV). Reduce LLM token costs by up to 40%.",
|
|
8
|
+
"description": "A lightweight library to convert between TOON (Token-Oriented Object Notation) and popular data formats (JSON, YAML, XML, CSV) with end-to-end encryption support. Reduce LLM token costs by up to 40%.",
|
|
9
9
|
"main": "src/index.js",
|
|
10
10
|
"type": "module",
|
|
11
11
|
"scripts": {
|
|
@@ -24,7 +24,13 @@
|
|
|
24
24
|
"optimization",
|
|
25
25
|
"data-format",
|
|
26
26
|
"serialization",
|
|
27
|
-
"formatter"
|
|
27
|
+
"formatter",
|
|
28
|
+
"encryption",
|
|
29
|
+
"aes-256-gcm",
|
|
30
|
+
"security",
|
|
31
|
+
"crypto",
|
|
32
|
+
"secure-data",
|
|
33
|
+
"end-to-end-encryption"
|
|
28
34
|
],
|
|
29
35
|
"author": "Ankit Pal",
|
|
30
36
|
"license": "MIT",
|
|
@@ -53,6 +59,7 @@
|
|
|
53
59
|
"./xml": "./src/xml.js",
|
|
54
60
|
"./csv": "./src/csv.js",
|
|
55
61
|
"./validator": "./src/validator.js",
|
|
56
|
-
"./utils": "./src/utils.js"
|
|
62
|
+
"./utils": "./src/utils.js",
|
|
63
|
+
"./encryptor": "./src/encryptor.js"
|
|
57
64
|
}
|
|
58
65
|
}
|