@sonatel-os/json-sculpt
v1.3.0
Published
Declarative JSON transformation engine that reshapes and maps complex data structures with nested resolution, type casting, recursion, and more. Ideal for APIs, SDKs, and frontend shaping.
Maintainers
Readme
🎨 JSON Sculptor — Mapping Made Declarative
Your API responses deserve better than res.data?.items?.[0]?.name. Let’s sculpt them into shape — predictably, declaratively, and with joy."
🚀 What Is It?
@sonatel-os/json-sculpt is a minimalist mapping engine that reshapes any JSON into any structure you define — with support for:
- 📌 Declarative templates
- 🧠 Nested paths
- 🧰 Array transformations
- 🧪 Inline type casting (::type)
- ⚙️ Default/fallback values — NEW!
- 🧱 Dynamic keys — NEW!
- 🔁 Recursive mappings — NEW!
- 🧩 Flattened output via $spread — NEW!
- ⚡ Combined transformation modes
📦 Installation
Install via npm:
npm install @sonatel-os/json-sculpt
# or
yarn add @sonatel-os/json-sculpt📖 Basics
🛠 Basic Usage
import { sculpt } from '@sonatel-os/json-sculpt';
const template = {
name: '@link.user.name',
email: '@link.user.email',
city: '@link.address.city',
};
const input = {
user: { name: 'Alice', email: '[email protected]' },
address: { city: 'Wonderland' },
};
const result = sculpt.data({ data: input, to: template });
console.log(result);
// { name: 'Alice', email: '[email protected]', city: 'Wonderland' }🧪 Type Casting with ::type
const template = {
age: '@link.profile.age::number',
isActive: '@link.flags.subscribed::boolean',
registeredAt: '@link.meta.createdAt::date',
};✅ Supported types: string, number, boolean, date, array, object
📚 Array Mapping
const template = {
product: '@link.name',
variants: {
$map: '@link.variants',
$transform: {
color: '@link.color',
inStock: '@link.stock::boolean',
}
},
flatColors: {
$map: '@link.variants',
$extract: '@link.color'
}
};🧠 Advanced Features
🧱 Dynamic Keys — NEW!
const template = {
product: '@link.name',
['@link.sku']: '@link.name',
variants: {
$map: '@link.variants',
$transform: {
['@link.color']: '@link.stock::boolean',
}
}
};- ✅ Works anywhere — top-level or nested
- ✅ No special syntax needed
🧩 Flattened Mapped Output ($spread) — NEW!
const template = {
product: '@link.name',
variantsInStock: {
$map: '@link.variants',
$spread: {
['@link.color']: '@link.stock::boolean'
}
}
};🔁 Recursive Mapping — NEW!
const template = {
components: {
$map: '@link.content',
$transform: {
name: '@link.type',
props: '@link.props',
children: {
$recursive: {
$track: '#content',
$rename: 'children',
name: '@link.type',
props: '@link.props'
}
}
}
}
};🌀 Dynamic Path Resolution (Fallbacks) — NEW!
const template = {
username: ['@link.user.username', '@link.user.email', '[email protected]'],
};🧪 Pro Tip: Function-Based $op
Extend Sculptor with custom operators for ultra-specific transforms.
sculpt.registry('toCamelCase', (carriers, args, parent, ctx) => {})
const template = {
airlineNames: {
$op: 'toCamelCase',
$from: '@link.carriers'
}
};🤝 Contribute
Have an idea or feature request? Open a GitHub issue or submit a PR!
🏷 License
Licensed under the MIT License.
👨🎨 Author
Mohamed Johnson (LPIX-11)
Crafting clean, smart tools for devs who care.
