Skip to content

Instantly share code, notes, and snippets.

@omranjamal
Created June 8, 2024 08:28
Show Gist options
  • Save omranjamal/90d5caac6516225c5fb6026393274c59 to your computer and use it in GitHub Desktop.
Save omranjamal/90d5caac6516225c5fb6026393274c59 to your computer and use it in GitHub Desktop.
Building JSON structures with JSX
/** @jsx jsonx */
/** @jsxFrag null */
const property = (key: string | number, ...children: any) =>
jsonxobject({
[key]: jsonx(null, undefined, ...children),
});
class JSONXObject extends Object {}
const jsonxobject = (obj: any) => Object.assign(new JSONXObject(), obj);
const fragment = (...children: any[]) =>
children.length > 1
? children.some((child) => child instanceof JSONXObject)
? jsonxobject(
children
.filter((child) => child instanceof JSONXObject)
.concat(
children
.filter(
(child) => !(child instanceof JSONXObject),
)
.map((value, i) => {
return {[i]: value};
}),
)
.reduce((a, b) => {
return {...a, ...b};
}, {}),
)
: children
: children[0];
const plain = (obj: any) =>
Array.isArray(obj)
? obj.map((item) => plain(item))
: obj instanceof JSONXObject
? Object.fromEntries(
Object.entries(obj).map(([key, value]) => [key, plain(value)]),
)
: obj;
const jsonx = (
t: 'prop' | 'array' | 'item' | string,
props: {key: string | number} | never,
...children: any[]
): any =>
!t
? fragment(...children)
: t === 'prop'
? property(props.key, ...children)
: t === 'array'
? children
: t === 'item'
? children[0]
: t === 'plain'
? plain(children[0])
: property(t, ...children);
const obj = (
<>
<name>Omran Jamal</name>
<age>{32}</age>
<prop key={32}>Engine</prop>
<friends>
<array>
<item>
<name>Adnan Khan</name>
</item>
<item>Nahiyan</item>
<>Mahir</>
<>
<name>Afra</name>
<age>27</age>
</>
</array>
</friends>
<favoriteFoods>
<item>Orange</item>
<item>Mango</item>
</favoriteFoods>
<>
<react>js</react>
<>
<nigga>js</nigga>
<>
<pot>is bad</pot>
<tomato>
<item>fruit</item>
<>red</>
<>round</>
</tomato>
</>
</>
</>
</>
);
console.log(obj);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment