all repos — kitten @ b219fb2f774165981101cc0bf3ba30e9fd84fa65

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;
	}
}