@becodesroslovakia/toon-parser
v1.0.0
Published
A lightweight parser and serializer for TOON format - a compact alternative to JSON with Express and NestJS support
Maintainers
Readme
@becodesroslovakia/toon-parser 🎨
A lightweight, type-safe parser and serializer for TOON format - a compact alternative to JSON that combines the structure of JSON with the simplicity of CSV.
@becodesroslovakia/toon-parser provides a clean, efficient way to work with tabular data. Perfect for APIs, data processing, and anywhere you need a more readable format than JSON arrays.
📑 Table of Contents
- Features
- What is TOON?
- Installation
- Quick Start
- API Reference
- Express Middleware
- NestJS Integration
- Type Support
- Error Handling
- Examples
- Development
- Contributing
- License
✨ Features
- 🚀 Fast & Lightweight - Zero dependencies (except Express for middleware)
- 📦 Type-Safe - Full TypeScript support with comprehensive type definitions
- 🔌 Framework Integration - Express middleware and NestJS pipe included
- 🎯 Type Inference - Automatically detects numbers, booleans, null, and strings
- 🛡️ Robust Error Handling - Descriptive error messages for easy debugging
- ✅ Well Tested - Comprehensive test suite with high coverage
- 📚 Well Documented - Extensive documentation and examples
What is TOON?
TOON is a compact data notation that combines the structure of JSON with the simplicity of CSV. It's perfect for tabular data where you want a more readable format than JSON arrays.
Example
TOON format:
reviews[3]{ id, customer, rating, comment, verified }:
201, Rahul Shah, 5, Fantastic!, true
202, Priya Mehta, 4, Game changer, true
203, Karan Desai, 4, Average, falseEquivalent JSON:
{
"reviews": [
{ "id": 201, "customer": "Rahul Shah", "rating": 5, "comment": "Fantastic!", "verified": true },
{ "id": 202, "customer": "Priya Mehta", "rating": 4, "comment": "Game changer", "verified": true },
{ "id": 203, "customer": "Karan Desai", "rating": 4, "comment": "Average", "verified": false }
]
}📦 Installation
npm install @becodesroslovakia/toon-parserFor Express Integration
npm install @becodesroslovakia/toon-parser expressFor NestJS Integration
npm install @becodesroslovakia/toon-parser @nestjs/common @nestjs/core reflect-metadata rxjs🚀 Quick Start
Basic Usage
import { parse, serialize } from '@becodesroslovakia/toon-parser';
// Parse TOON to JSON
const toon = `reviews[2]{ id, customer, rating }:
201, Rahul Shah, 5
202, Priya Mehta, 4`;
const json = parse(toon);
console.log(json);
// { reviews: [{ id: 201, customer: "Rahul Shah", rating: 5 }, ...] }
// Serialize JSON to TOON
const data = {
reviews: [
{ id: 201, customer: 'Rahul Shah', rating: 5 },
{ id: 202, customer: 'Priya Mehta', rating: 4 }
]
};
const toonOutput = serialize(data);
console.log(toonOutput);
// reviews[2]{ id, customer, rating }:
// 201, Rahul Shah, 5
// 202, Priya Mehta, 4📖 API Reference
Core Functions
parse(toonString, options?)
Parses a TOON formatted string into a JavaScript object.
Parameters:
toonString(string): The TOON formatted string to parseoptions(object, optional):validateCount(boolean, default:true): Whether to validate row count matches header counttrimValues(boolean, default:true): Whether to trim whitespace from values
Returns: An object with the dataset name as key and array of objects as value
Throws: Error if TOON format is invalid
Example:
const result = parse(`users[2]{ name, age }:
John, 30
Jane, 25`, { validateCount: true });
// { users: [{ name: "John", age: 30 }, { name: "Jane", age: 25 }] }serialize(data, options?)
Serializes a JavaScript object to TOON format.
Parameters:
data(object): Must have exactly one key with an array valueoptions(object, optional):quoteStrings(boolean, default:true): Whether to quote strings containing commasspaceAfterComma(boolean, default:true): Whether to include spaces after commas
Returns: A TOON formatted string
Throws: Error if data structure is invalid
Example:
const toon = serialize({
products: [
{ id: 1, name: 'Apple', price: 1.99 },
{ id: 2, name: 'Banana', price: 0.99 }
]
});🔌 Express Middleware
Automatically parse TOON request bodies in Express applications. The middleware detects TOON payloads by Content-Type header and seamlessly integrates with your Express routes.
Setup
import express from 'express';
import { toonMiddleware } from '@becodesroslovakia/toon-parser/express';
const app = express();
// Add TOON middleware
app.use(toonMiddleware());
// Or with custom options
app.use(toonMiddleware({
contentType: 'application/toon',
strictContentType: true,
validateCount: true
}));Usage
app.post('/api/reviews', (req, res) => {
// req.body is automatically parsed from TOON format
console.log(req.body);
// { reviews: [{ id: 201, customer: "Rahul Shah", ... }] }
res.json({ success: true, data: req.body });
});Options
contentType(string | string[], default:'application/toon'): Content-Type(s) to matchstrictContentType(boolean, default:true): Only parse if Content-Type matchesvalidateCount(boolean, default:true): Validate row count matches headertrimValues(boolean, default:true): Trim whitespace from values
Error Handling
The middleware returns a 400 Bad Request response if TOON parsing fails:
{
"error": "TOON Parse Error",
"message": "Invalid TOON header format: ..."
}🎯 NestJS Integration
Parse and validate TOON data in NestJS applications with full DTO support. The ToonPipe integrates seamlessly with NestJS's validation and transformation pipeline.
Setup
import { Module } from '@nestjs/common';
import { ToonModule } from '@becodesroslovakia/toon-parser/nest';
@Module({
imports: [ToonModule],
})
export class AppModule {}Usage with Pipe
import { Controller, Post, Body } from '@nestjs/common';
import { ToonPipe } from '@becodesroslovakia/toon-parser/nest';
@Controller('reviews')
export class ReviewsController {
@Post()
create(@Body(ToonPipe) data: any) {
return data;
}
}Usage with DTO
import { Controller, Post, Body } from '@nestjs/common';
import { ToonPipe, ToonPipeOptions } from '@becodesroslovakia/toon-parser/nest';
class ReviewDto {
id: number;
customer: string;
rating: number;
comment: string;
verified: boolean;
}
class CreateReviewsDto {
reviews: ReviewDto[];
}
@Controller('reviews')
export class ReviewsController {
@Post()
create(@Body(new ToonPipe({ transformTo: CreateReviewsDto })) data: CreateReviewsDto) {
// data is an instance of CreateReviewsDto
return data.reviews;
}
}Options
validateCount(boolean, default:true): Validate row count matches headertrimValues(boolean, default:true): Trim whitespace from valuestransformTo(class, optional): DTO class to transform parsed data into
🎨 Type Support
TOON automatically infers types from values, making it easy to work with mixed data types:
- Numbers:
42,3.14,-10 - Booleans:
true,false - Null:
null - Strings: Everything else, or quoted strings:
"Hello, World"
Quoted Strings
Use quotes for strings containing commas or special characters:
items[1]{ name, description }:
"Apple, Red", "Sweet, juicy fruit"Escaped quotes:
quotes[1]{ text }:
"He said ""Hello"" to me"⚠️ Error Handling
All parsing functions throw descriptive errors to help you debug issues quickly:
try {
const result = parse(invalidToon);
} catch (error) {
console.error(error.message);
// "Invalid TOON header format: ..."
// "Row count mismatch: header specifies 3 rows, but found 2 rows"
// "Row 1 has 2 values, but header specifies 3 fields"
}🧪 Development
Running Tests
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverageBuilding
npm run buildThis compiles TypeScript to JavaScript in the dist/ directory.
Linting
npm run lintFormatting
npm run format🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development Setup
# Clone the repository
git clone https://github.com/VladimirTomko/toon-parser.git
cd toon-parser
# Install dependencies
npm install
# Run tests
npm test
# Build the project
npm run build📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- Inspired by the need for a more readable format for tabular data
- Built with TypeScript for type safety
- Tested with Jest for reliability
📚 Additional Resources
- Usage Guide - Detailed usage examples and best practices
- Contributing Guide - How to contribute to the project
- Changelog - Version history and changes
- Examples - Code examples
💡 Examples
Round-trip Conversion
import { parse, serialize } from '@becodesroslovakia/toon-parser';
const original = {
products: [
{ id: 1, name: 'Apple', price: 1.99, inStock: true },
{ id: 2, name: 'Banana', price: 0.99, inStock: false }
]
};
// Convert to TOON
const toon = serialize(original);
// Convert back to JSON
const restored = parse(toon);
// original and restored are equivalent
console.log(JSON.stringify(original) === JSON.stringify(restored)); // trueHandling Empty Datasets
const empty = { items: [] };
const toon = serialize(empty);
// items[0]{ }:
const parsed = parse(toon, { validateCount: false });
// { items: [] }Custom Serialization Options
// Compact format (no spaces after commas)
const compact = serialize(data, { spaceAfterComma: false });
// reviews[2]{ id, name }:
// 201,John
// 202,Jane
// Don't quote strings (use with caution - commas in values will break parsing)
const unquoted = serialize(data, { quoteStrings: false });🗺️ Roadmap
Future enhancements planned for @becodesroslovakia/toon-parser:
- [ ] Support for nested objects
- [ ] Support for arrays within rows
- [ ] Streaming parser for large datasets
- [ ] CLI tool for file conversion
- [ ] Schema validation
- [ ] Performance optimizations
- [ ] Browser support (ESM build)
See CHANGELOG.md for version history.
⭐ Show Your Support
If you find this project useful, please consider giving it a star on GitHub!
📞 Support
Made with ❤️ by the toon-parser contributors
