Comprehensive examples demonstrating all FlatFormatter capabilities.
import { FlatFormatter } from 'llm-middleware';
const user = {
name: 'Alice Johnson',
email: 'alice@example.com',
role: 'Senior Engineer',
department: 'Engineering'
};
const formatted = FlatFormatter.flatten(user);
console.log(formatted);Output:
name: Alice Johnson
email: alice@example.com
role: Senior Engineer
department: Engineering
const product = {
name: 'Wireless Mouse',
price: 29.99,
category: 'Electronics',
inStock: true
};
FlatFormatter.flatten(product, { format: 'numbered' });Output:
1. name: Wireless Mouse
2. price: 29.99
3. category: Electronics
4. inStock: true
FlatFormatter.flatten(product, { format: 'bulleted' });Output:
• name: Wireless Mouse
• price: 29.99
• category: Electronics
• inStock: true
FlatFormatter.flatten(product, {
format: 'sections',
itemPrefix: '=== ',
itemSuffix: ' ==='
});Output:
=== name ===
Wireless Mouse
=== price ===
29.99
=== category ===
Electronics
=== inStock ===
true
FlatFormatter.flatten(product, { format: 'table' });Output:
| name | Wireless Mouse |
| price | 29.99 |
| category | Electronics |
| inStock | true |
const users = [
{ name: 'Alice', role: 'Engineer' },
{ name: 'Bob', role: 'Designer' },
{ name: 'Charlie', role: 'Manager' }
];
FlatFormatter.flatten(users, {
format: 'numbered',
entryTitleKey: 'name'
});Output:
1. Alice
role: Engineer
2. Bob
role: Designer
3. Charlie
role: Manager
const largeList = Array.from({ length: 100 }, (_, i) => ({
id: i + 1,
name: `Item ${i + 1}`
}));
// Show only first 5 items
FlatFormatter.flatten(largeList, {
format: 'numbered',
arraySliceStart: 0,
arraySliceEnd: 5,
entryTitleKey: 'name',
ignoredKeys: ['id']
});Output:
1. Item 1
2. Item 2
3. Item 3
4. Item 4
5. Item 5
const person = {
firstName: 'Alice',
lastName: 'Johnson',
birthYear: 1993,
salary: 95000
};
FlatFormatter.flatten(person, {
computedFields: {
fullName: (p) => `${p.firstName} ${p.lastName}`,
age: (p) => new Date().getFullYear() - p.birthYear,
salaryFormatted: (p) => `$${p.salary.toLocaleString()}`
},
ignoredKeys: ['firstName', 'lastName', 'salary']
});Output:
birthYear: 1993
fullName: Alice Johnson
age: 32
salaryFormatted: $95,000
const order = {
orderNumber: 'ORD-12345',
items: [
{ name: 'Widget A', price: 25.00, quantity: 2 },
{ name: 'Widget B', price: 15.00, quantity: 3 }
],
shippingCost: 5.00
};
FlatFormatter.flatten(order, {
computedFields: {
itemCount: (o) => o.items.length,
subtotal: (o) => o.items.reduce((sum, i) => sum + (i.price * i.quantity), 0),
total: (o) => {
const subtotal = o.items.reduce((sum, i) => sum + (i.price * i.quantity), 0);
return (subtotal + o.shippingCost).toFixed(2);
}
},
ignoredKeys: ['items']
});Output:
orderNumber: ORD-12345
shippingCost: 5.00
itemCount: 3
subtotal: 95.00
total: 100.00
import { BasePreset } from 'llm-middleware';
interface SimpleProduct {
name?: string;
price?: number;
inStock?: boolean;
}
interface ProcessedSimpleProduct {
[key: string]: string | number | boolean;
Name: string;
Price: string;
Availability: string;
}
class SimpleProductPreset extends BasePreset<SimpleProduct, ProcessedSimpleProduct> {
constructor() {
super('SimpleProduct');
}
protected preprocessEntity(product: SimpleProduct): ProcessedSimpleProduct {
return {
'Name': product.name || 'Unknown',
'Price': product.price ? `$${product.price.toFixed(2)}` : 'N/A',
'Availability': product.inStock ? 'In Stock ✓' : 'Out of Stock ✗'
};
}
}The middleware includes ProductPreset demonstrating advanced techniques:
import { productPreset, Product } from 'llm-middleware';
const product: Product = {
name: 'Wireless Gaming Mouse',
description: 'High-precision wireless mouse designed for gaming',
category: 'Gaming Accessories',
// Nested object - pricing
pricing: {
basePrice: 79.99,
currency: 'USD',
discountPercent: 20,
taxRate: 0.08
},
// Arrays
features: [
'RGB lighting',
'16,000 DPI sensor',
'Programmable buttons',
'Wireless charging'
],
tags: ['gaming', 'wireless', 'rgb', 'esports'],
// Nested object with arrays
metadata: {
manufacturer: 'GameTech Pro',
origin: 'Taiwan',
certifications: ['CE', 'FCC', 'RoHS', 'USB-IF']
},
// Array of objects
reviews: [
{
rating: 5,
comment: 'Best gaming mouse I\'ve ever owned!',
author: 'ProGamer123'
},
{
rating: 5,
comment: 'Incredible precision and comfort',
author: 'StreamerAce'
},
{
rating: 4,
comment: 'Great mouse, battery life could be better'
}
],
inStock: true,
quantity: 127
};
const formatted = productPreset.formatForLLM(product, "## PRODUCT DETAILS:");
console.log(formatted);Output:
## PRODUCT DETAILS:
Name: Wireless Gaming Mouse
Description: High-precision wireless mouse designed for gaming
Category: Gaming Accessories
Price: 79.99 USD
Discount: 20% OFF
Final Price: 63.99 USD
Features: RGB lighting, 16,000 DPI sensor, Programmable buttons, Wireless charging
Tags: gaming, wireless, rgb, esports
Manufacturer: GameTech Pro
Origin: Taiwan
Certifications: CE, FCC, RoHS, USB-IF
Average Rating: 4.7 / 5
Review Count: 3 reviews
Sample Reviews: "Best gaming mouse I've ever owned!" (5/5) - ProGamer123; "Incredible precision and comfort" (5/5) - StreamerAce
Availability: In Stock (127 units available)
What the preprocessing does:
- Flattens nested objects:
pricing.basePrice→'Price' - Calculates values: Discount applied to get final price
- Joins arrays:
featuresarray → comma-separated string - Aggregates data: Reviews → average rating + sample comments
- Formats strings: Combines quantity with availability text
- Handles optionals: All fields have fallbacks
All preset examples are located in src/examples/flat-formatter-demo/.
The middleware core only provides:
BasePreset- Abstract base classGenericEntity- Base entity interfaceProcessedEntity- Base processed interfaceFlatFormatter- Core formatting utility
You create your own domain-specific presets by extending BasePreset.
const apiResponse = {
status: 'success',
data: {
user: {
id: 'user-123',
username: 'alice_j',
email: 'alice@example.com',
createdAt: '2023-01-15T10:30:00Z'
},
permissions: ['read', 'write', 'admin']
},
metadata: {
requestId: 'req-abc-123',
timestamp: Date.now()
}
};
// Format for LLM context
const context = FlatFormatter.flatten(apiResponse.data.user, {
format: 'sections',
ignoredKeys: ['id', 'createdAt'],
computedFields: {
accountAge: (u) => {
const created = new Date(u.createdAt);
const days = Math.floor((Date.now() - created.getTime()) / (1000 * 60 * 60 * 24));
return `${days} days`;
}
}
});const queryResults = [
{ id: 1, name: 'Project Alpha', status: 'active', priority: 'high' },
{ id: 2, name: 'Project Beta', status: 'completed', priority: 'medium' },
{ id: 3, name: 'Project Gamma', status: 'active', priority: 'low' }
];
const formatted = FlatFormatter.flatten(queryResults, {
format: 'numbered',
entryTitleKey: 'name',
ignoredKeys: ['id'],
itemPrefix: '📋 PROJECT:',
keyValueSeparator: ' → '
});Output:
1. 📋 PROJECT: Project Alpha
status → active
priority → high
2. 📋 PROJECT: Project Beta
status → completed
priority → medium
3. 📋 PROJECT: Project Gamma
status → active
priority → low
const config = {
server: {
host: 'localhost',
port: 3000,
ssl: false
},
database: {
host: 'db.example.com',
port: 5432,
name: 'myapp'
},
features: {
authentication: true,
analytics: true,
caching: false
}
};
// Flatten nested config
const serverConfig = FlatFormatter.flatten(config.server, {
format: 'table',
keyValueSeparator: ' : '
});
const dbConfig = FlatFormatter.flatten(config.database, {
format: 'table',
keyValueSeparator: ' : '
});// Single objects: sections or separator
FlatFormatter.flatten(singleEntity, { format: 'sections' });
// Lists: numbered or bulleted
FlatFormatter.flatten(listItems, { format: 'numbered' });
// Comparison: table
FlatFormatter.flatten(comparisonData, { format: 'table' });// ✅ Good - compute on-the-fly
FlatFormatter.flatten(data, {
computedFields: {
summary: (d) => `${d.count} items totaling $${d.sum}`
}
});
// ❌ Avoid - mutating source data
data.summary = `${data.count} items totaling $${data.sum}`;
FlatFormatter.flatten(data);FlatFormatter.flatten(entity, {
ignoredKeys: [
'id', // Internal IDs
'_internal', // Private fields
'__typename', // GraphQL metadata
'createdAt', // Timestamps (unless relevant)
'updatedAt'
]
});// If you format the same entity type frequently,
// create a preset once and reuse it:
const formatted1 = myPreset.formatForLLM(entity1);
const formatted2 = myPreset.formatForLLM(entity2);
const formatted3 = myPreset.formatForLLM(entity3);