89 lines
2.4 KiB
JavaScript
89 lines
2.4 KiB
JavaScript
|
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),
|
||
|
};
|
||
|
}
|