mirror of
https://github.com/github/codeql-action.git
synced 2025-12-28 02:00:12 +08:00
43 lines
1.3 KiB
JavaScript
43 lines
1.3 KiB
JavaScript
const isPrimitive = value => value === null || typeof value !== 'object';
|
|
|
|
export function isLikeSelector(selector) {
|
|
// Require selector to be an array or plain object.
|
|
if (
|
|
isPrimitive(selector)
|
|
|| (!Array.isArray(selector) && Reflect.getPrototypeOf(selector) !== Object.prototype)
|
|
) {
|
|
return false;
|
|
}
|
|
|
|
// Also require at least one enumerable property.
|
|
const descriptors = Object.getOwnPropertyDescriptors(selector);
|
|
return Reflect.ownKeys(descriptors).some(key => descriptors[key].enumerable === true);
|
|
}
|
|
|
|
export const CIRCULAR_SELECTOR = new Error('Encountered a circular selector');
|
|
|
|
export function selectComparable(actual, selector, circular = [selector]) {
|
|
if (isPrimitive(actual)) {
|
|
return actual;
|
|
}
|
|
|
|
const comparable = Array.isArray(selector) ? [] : {};
|
|
const enumerableKeys = Reflect.ownKeys(selector).filter(key => Reflect.getOwnPropertyDescriptor(selector, key).enumerable);
|
|
for (const key of enumerableKeys) {
|
|
const subselector = Reflect.get(selector, key);
|
|
if (isLikeSelector(subselector)) {
|
|
if (circular.includes(subselector)) {
|
|
throw CIRCULAR_SELECTOR;
|
|
}
|
|
|
|
circular.push(subselector);
|
|
comparable[key] = selectComparable(Reflect.get(actual, key), subselector, circular);
|
|
circular.pop();
|
|
} else {
|
|
comparable[key] = Reflect.get(actual, key);
|
|
}
|
|
}
|
|
|
|
return comparable;
|
|
}
|