Вот коротко:
const result = Object.values(data.reduce((acc, { id, color }) => (
(acc[id] ??= { id, colors: [] }).colors.push(color),
acc
), {}));
Но если вдруг краткость не основной приоритет, то можно исполнить группировку данных в более общем виде:
function group(data, key, val = n => n) {
const getKey = key instanceof Function ? key : n => n[key];
const getVal = val instanceof Function ? val : n => n[val];
const result = new Map;
for (const n of data) {
const k = getKey(n);
result.set(k, result.get(k) ?? []).get(k).push(getVal(n));
}
return result;
}
const result = Array.from(
group(data, 'id', 'color'),
([ id, colors ]) => ({ id, colors })
);