UNPKG

serialize-as-code

Version:

Serialize any Javascript object as its source code

136 lines (106 loc) 5.03 kB
const NOP = () => undefined; const __getTypeOfObject = o => Object.prototype.toString.call(o).split(' ')[1].slice(0, -1); const __serializeProp = (key, value, custom, serialized) => typeof value === 'string' ? `${key}="${value}"` : `${key}={${__serialize(value, custom, serialized)}}`; const __serializeProps = (o, custom, serialized) => { const elemProps = o.props; const props = []; Object.entries(elemProps).forEach(([k, v]) => { if (v !== undefined && k !== 'children') props.push(__serializeProp(k, v, custom, serialized)); }); if (o.key) props.push(__serializeProp('key', o.key, custom, serialized)); if (o.ref) props.push(__serializeProp('ref', o.ref, custom, serialized)); if (!props.length) return ''; return ' ' + props.join(' '); }; const __serializeChildren = (o, custom, serialized) => { const children = o.props.children; if (!children) return ''; if (typeof children === 'string') return children; return Array.isArray(children) ? children.map(v => __serialize(v, custom, serialized)).join('') : __serialize(children, custom, serialized); }; const __reactTypeNameReader = { String: type => type, Function: type => type.name, Symbol: type => Symbol.keyFor(type) === 'react.fragment' && 'Fragment' || undefined }; const getTypeName = type => (__reactTypeNameReader[__getTypeOfObject(type)] || NOP)(type); const __serializeReactElement = (o, custom, serialized) => { const type = getTypeName(o.type) || 'UNKNOWN'; const children = __serializeChildren(o, custom, serialized); return `<${type}${__serializeProps(o, custom, serialized)}${children ? `>${children}</${type}>` : ' />'}`; }; const __serializeReact = (o, custom, serialized) => { const symbolKey = Symbol.keyFor(o.$$typeof); switch (symbolKey) { case 'react.element': return __serializeReactElement(o, custom, serialized); default: return; } }; const __serializeIfReact = (o, custom, serialized) => { if ('$$typeof' in o && Object.prototype.toString.call(o.$$typeof) === '[object Symbol]') { const key = Symbol.keyFor(o.$$typeof); if (key && key.indexOf('react.') === 0) return __serializeReact(o, custom, serialized); } }; const __serializerByType = { BigInt: o => `${String(o)}n`, RegExp: o => `/${String(o)}/`, String: o => o.indexOf('"') === -1 && o.indexOf("'") !== -1 ? `"${o}"` : `'${o}'`, Function: o => o.name || 'Function', AsyncFunction: o => o.name || 'AsyncFunction', Date: o => `new Date(${Number(o)})`, Number: o => String(o), Boolean: o => String(o), Set: o => `new Set(${__serializeArray([...o.keys()], undefined, [])})`, Map: o => `new Map(${__serializeArray([...o.entries()], undefined, [])})`, Symbol: o => Symbol.keyFor(o) === undefined ? o.toString() : `Symbol.for('${Symbol.keyFor(o)}')`, Error: o => `new ${o.name}('${o.message}')`, Window: () => `window`, Document: () => `document` }; const __serializeArray = (o, custom, serialized) => { const results = []; for (let i = 0; i < o.length; i++) { results.push(__serialize(o[i], custom, serialized)); } return `[${results.join(', ')}]`; }; const __serializeOptArray = (o, custom, serialized) => { if (Array.isArray(o)) return __serializeArray(o, custom, serialized); }; const __serializeHTML = o => { var _o$constructor; const objectType = (_o$constructor = o.constructor) == null ? void 0 : _o$constructor.name; if (/^HTML[a-zA-Z]*Element$/.test(objectType)) return objectType; }; const __serializeObject = (o, custom, serialized) => { var _o$constructor2; const oKeys = Object.keys(o); oKeys.sort(); const results = []; for (let i = 0; i < oKeys.length; i++) { const key = oKeys[i]; results.push(`${key}: ${__serialize(o[key], custom, serialized)}`); } const objectType = (_o$constructor2 = o.constructor) == null ? void 0 : _o$constructor2.name; const displayedType = objectType === 'Object' ? '' : objectType; return `${displayedType}{${results.join(', ')}}`; }; const Serialize = { custom: (o, custom) => custom && custom(o), undefOrNull: o => o === undefined && 'undefined' || o === null && 'null' || undefined, flat: o => (__serializerByType[__getTypeOfObject(o)] || NOP)(o), cyclomatic: (o, _, serialized) => serialized.indexOf(o) !== -1 && '>CYCLOMATIC<' || undefined, react: __serializeIfReact, array: __serializeOptArray, HTML: __serializeHTML }; const __serialize = (o, custom, serialized) => Serialize.custom(o, custom, serialized) || Serialize.undefOrNull(o, custom, serialized) || Serialize.flat(o, custom, serialized) || Serialize.cyclomatic(o, custom, serialized) || (nextSerialized => Serialize.react(o, custom, nextSerialized) || Serialize.array(o, custom, nextSerialized) || Serialize.HTML(o, custom, nextSerialized) || __serializeObject(o, custom, nextSerialized))([...serialized, o]); const _serialize = (o, custom) => __serialize(o, custom, []); const Serializer = { run: o => _serialize(o), create: custom => o => _serialize(o, custom) }; export { Serializer };