84 lines
2.2 KiB
JavaScript
84 lines
2.2 KiB
JavaScript
import {
|
|
isIdentifier,
|
|
isLiteral,
|
|
isProperty,
|
|
isSpreadElement,
|
|
} from '@/astride/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 (isProperty(properties[i])) {
|
|
const {computed, key, value} = properties[i];
|
|
let k;
|
|
if (computed) {
|
|
k = evaluate(key, {scope});
|
|
}
|
|
else if (isIdentifier(key)) {
|
|
k = {value: key.name};
|
|
}
|
|
else if (isLiteral(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 {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),
|
|
};
|
|
}
|