Resolve "BCMR Adapter: Create BaseBCMR and HTTP implementation"

This commit is contained in:
devperate
2025-09-18 13:09:11 +00:00
committed by Emergent Reasons
parent 6d0a36248d
commit e4020a996c
11 changed files with 363 additions and 19 deletions
+72
View File
@@ -39,3 +39,75 @@ export function hasDuplicateParams(url: string | URL): boolean {
return false;
}
/**
* Check if the given object is a Record.
*
* @param object The variable to check.
* @returns True if the object is a record.
*/
export function isRecord(
value: unknown,
): value is Record<string | number | symbol, unknown> {
if (typeof value !== 'object' || value === null) return false;
// Check if its a plain object (not a class instance, array, etc.)
const prototype = Object.getPrototypeOf(value);
return prototype === null || prototype === Object.prototype;
}
/**
* Find all the ocurrences of a given key in a plain JS object.
* NOTE: This function is intended to search keys in JSON objects
* and it will not search the key walking through collection object structures(Set, Map, etc.)
* NOTE: This function is intended to be used to traverse not too nested JSON objects.
*
* @param object The plain JS Object to traverse.
* @param key The Key to search.
*
* @throws If object can't be serializated as JSON.
* @throws If object is more than 100 levels nested.
* @returns A list of values for the given key.
*/
export function findAllKeyOcurrences(
object: Record<string | number | symbol, unknown>,
key: string,
): Array<unknown> {
// Check object serialization as JSON to avoid circular reference, BigInt values or other object structures(Set, Map, Date, etc..)
JSON.stringify(object);
// Under 100 the resource allocation is excessively fine for any JS environment or hardware.
// NOTE: If for some reason this needs to be changed be sure to add proper test cases to measure performance.
// Currently(11/09/2025) the JS stack size can handle roughly 10000 recursive calls on browsers and NodeJS.
const allowedNestedLevels = 100;
const keyValues: Array<unknown> = [];
function traverse(currentObj: Record<string | number | symbol, unknown>, depth: number = 0) {
// Stop if depth exceeds the amount of 'allowedNestedLevels'.
if (depth > allowedNestedLevels)
throw new Error(`Maximum nesting level of ${allowedNestedLevels} reached.`);
// Stop when find a non object value.
if (typeof currentObj !== 'object' || currentObj === null) return;
if (Array.isArray(currentObj)) {
currentObj.forEach((item) => traverse(item, depth + 1));
return;
}
// Check if current object has the key property we are looking
if (key in currentObj) {
keyValues.push(currentObj[key]);
}
// Recursively traverse all properties
Object.values(currentObj).forEach((value) => {
if (isRecord(value)) traverse(value, depth + 1);
});
}
traverse(object);
return keyValues;
}