pkgs/types/src/lib/registry.ts (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
export class ComponentRegistry {
private components: Record<string, any> = {};
public loadComponents(rawComponents: Record<string, any>) {
this.components = rawComponents;
}
public resolveRef(ref: string): any {
if (!ref.startsWith("#/components/")) {
throw new Error(`component references only, rcvd: ${ref}`);
}
const pathParts = ref.replace("#/components/", "").split("/");
let currentData = this.components;
for (const part of pathParts) {
if (currentData === undefined || currentData === null) {
console.warn(`[w] failed to resolve reference: ${ref}`);
return null;
}
currentData = currentData[part];
}
return currentData;
}
public resolveDeep(obj: any, seen = new Set<any>()): any {
if (!obj || typeof obj !== "object") return obj;
// prevent infinite loops from circ. references
if (seen.has(obj)) return obj;
seen.add(obj);
if (obj.$ref) {
const resolved = this.resolveRef(obj.$ref);
return this.resolveDeep(resolved, seen);
}
if (Array.isArray(obj)) {
return obj.map((item) => this.resolveDeep(item, seen));
}
const result: Record<string, any> = {};
for (const [key, value] of Object.entries(obj)) {
result[key] = this.resolveDeep(value, seen);
}
return result;
}
}
|