import { isComputed, isIdentifier, isKeyValueProperty, isNumericLiteral, isSpreadElement, isStringLiteral, } from '@/swcx/types.js'; export default function(node, {evaluate, scope}) { const {properties} = node; let isAsync = false; const entries = []; for (let i = 0; i < properties.length; i++) { if (isKeyValueProperty(properties[i])) { const {key, value} = properties[i]; let k; if (isComputed(key)) { k = evaluate(key, {scope}); } else if (isIdentifier(key)) { k = {value: key.value}; } else if (isNumericLiteral(key)) { k = {value: key.value}; } else if (isStringLiteral(key)) { k = {value: key.value}; } /* v8 ignore next 3 */ else { throw new Error(`property key type ${key.type} not implemented`); } const v = evaluate(value, {scope}); isAsync ||= k.async || v.async; if (k.async || v.async) { entries.push(Promise.all([k.value, v.value])); } else { entries.push([k.value, v.value]); } } if (isSpreadElement(properties[i])) { const {arguments: argument} = properties[i]; const spreading = evaluate(argument, {scope}); isAsync ||= spreading.async; if (spreading.async) { entries.push(Promise.resolve(spreading.value).then((spreading) => { const entries = []; const keys = Object.keys(spreading); for (let i = 0; i < keys.length; ++i) { const key = keys[i]; entries.push([key, spreading[key]]); } return entries; })); } else { const keys = Object.keys(spreading.value); for (let i = 0; i < keys.length; ++i) { const key = keys[i]; entries.push([key, spreading.value[key]]); } } } } return { async: !!isAsync, value: isAsync ? Promise.all(entries) .then((entries) => { const flat = []; for (let i = 0; i < entries.length; ++i) { const entry = entries[i]; if (Array.isArray(entry[0])) { for (let j = 0; j < entry.length; j++) { flat.push(entry[j]); } } else { flat.push(entry); } } return Object.fromEntries(flat); }) : Object.fromEntries(entries), }; }