All files / blong-gogo/src RealmDiscovery.ts

0% Statements 0/58
0% Branches 0/1
0% Functions 0/1
0% Lines 0/58

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 51 52 53 54 55 56 57 58 59                                                                                                                     
import {access, readFile} from 'fs/promises';
import {dirname, join, parse} from 'path';

export interface IRealmInfo {
    realmPath: string;
    realmName: string;
    packageJson: {name: string; version: string; realm?: boolean; [key: string]: unknown};
}

const cache = new Map<string, IRealmInfo | null>();

/**
 * Traverse up from a layer file path to find the nearest package.json
 * that marks a realm boundary.
 *
 * A package.json is considered a realm boundary when it:
 * - Has a `"realm": true` marker, OR
 * - Is the first package.json found above the layer file
 *
 * @param layerPath - Absolute path to the layer file or directory
 */
export async function findRealm(layerPath: string): Promise<IRealmInfo | null> {
    const startDir = layerPath.endsWith('.ts') || layerPath.endsWith('.js')
        ? dirname(layerPath)
        : layerPath;

    if (cache.has(startDir)) return cache.get(startDir) ?? null;

    let current = startDir;
    while (true) {
        const parent = dirname(current);
        if (parent === current) break; // reached filesystem root

        const pkgPath = join(current, 'package.json');
        try {
            await access(pkgPath);
            const pkgJson = JSON.parse(await readFile(pkgPath, 'utf-8'));
            const result: IRealmInfo = {
                realmPath: current,
                realmName: pkgJson.name ?? parse(current).base,
                packageJson: pkgJson,
            };
            cache.set(startDir, result);
            return result;
        } catch {
            // No package.json here, continue up
        }
        current = parent;
    }

    cache.set(startDir, null);
    return null;
}

/** Clear the realm discovery cache (useful in watch mode). */
export function clearRealmCache(): void {
    cache.clear();
}