mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 08:00:42 +00:00
refactor: share browser path helpers
This commit is contained in:
@@ -30,6 +30,16 @@ function safeWriteJson(filePath: string, data: Record<string, unknown>) {
|
||||
fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
|
||||
}
|
||||
|
||||
function asRecord(value: unknown): Record<string, unknown> | null {
|
||||
return typeof value === "object" && value !== null && !Array.isArray(value)
|
||||
? (value as Record<string, unknown>)
|
||||
: null;
|
||||
}
|
||||
|
||||
function readNestedRecord(root: unknown, key: string): Record<string, unknown> | null {
|
||||
return asRecord(asRecord(root)?.[key]);
|
||||
}
|
||||
|
||||
function setDeep(obj: Record<string, unknown>, keys: string[], value: unknown) {
|
||||
let node: Record<string, unknown> = obj;
|
||||
for (const key of keys.slice(0, -1)) {
|
||||
@@ -65,42 +75,11 @@ export function isProfileDecorated(
|
||||
|
||||
const localState = safeReadJson(localStatePath);
|
||||
const profile = localState?.profile;
|
||||
const infoCache =
|
||||
typeof profile === "object" && profile !== null && !Array.isArray(profile)
|
||||
? (profile as Record<string, unknown>).info_cache
|
||||
: null;
|
||||
const info =
|
||||
typeof infoCache === "object" &&
|
||||
infoCache !== null &&
|
||||
!Array.isArray(infoCache) &&
|
||||
typeof (infoCache as Record<string, unknown>).Default === "object" &&
|
||||
(infoCache as Record<string, unknown>).Default !== null &&
|
||||
!Array.isArray((infoCache as Record<string, unknown>).Default)
|
||||
? ((infoCache as Record<string, unknown>).Default as Record<string, unknown>)
|
||||
: null;
|
||||
const info = readNestedRecord(readNestedRecord(profile, "info_cache"), "Default");
|
||||
|
||||
const prefs = safeReadJson(preferencesPath);
|
||||
const browserTheme = (() => {
|
||||
const browser = prefs?.browser;
|
||||
const theme =
|
||||
typeof browser === "object" && browser !== null && !Array.isArray(browser)
|
||||
? (browser as Record<string, unknown>).theme
|
||||
: null;
|
||||
return typeof theme === "object" && theme !== null && !Array.isArray(theme)
|
||||
? (theme as Record<string, unknown>)
|
||||
: null;
|
||||
})();
|
||||
|
||||
const autogeneratedTheme = (() => {
|
||||
const autogenerated = prefs?.autogenerated;
|
||||
const theme =
|
||||
typeof autogenerated === "object" && autogenerated !== null && !Array.isArray(autogenerated)
|
||||
? (autogenerated as Record<string, unknown>).theme
|
||||
: null;
|
||||
return typeof theme === "object" && theme !== null && !Array.isArray(theme)
|
||||
? (theme as Record<string, unknown>)
|
||||
: null;
|
||||
})();
|
||||
const browserTheme = readNestedRecord(prefs?.browser, "theme");
|
||||
const autogeneratedTheme = readNestedRecord(prefs?.autogenerated, "theme");
|
||||
|
||||
const nameOk = typeof info?.name === "string" ? info.name === desiredName : true;
|
||||
|
||||
|
||||
@@ -30,6 +30,12 @@ export const DEFAULT_DOWNLOAD_DIR = path.join(DEFAULT_BROWSER_TMP_DIR, "download
|
||||
export const DEFAULT_UPLOAD_DIR = path.join(DEFAULT_BROWSER_TMP_DIR, "uploads");
|
||||
|
||||
type InvalidPathResult = { ok: false; error: string };
|
||||
type ResolvePathsWithinRootParams = {
|
||||
rootDir: string;
|
||||
requestedPaths: string[];
|
||||
scopeLabel: string;
|
||||
};
|
||||
type ResolvePathsWithinRootResult = { ok: true; paths: string[] } | InvalidPathResult;
|
||||
|
||||
function invalidPath(scopeLabel: string): InvalidPathResult {
|
||||
return {
|
||||
@@ -146,11 +152,9 @@ export async function resolveWritablePathWithinRoot(params: {
|
||||
return lexical;
|
||||
}
|
||||
|
||||
export function resolvePathsWithinRoot(params: {
|
||||
rootDir: string;
|
||||
requestedPaths: string[];
|
||||
scopeLabel: string;
|
||||
}): { ok: true; paths: string[] } | { ok: false; error: string } {
|
||||
export function resolvePathsWithinRoot(
|
||||
params: ResolvePathsWithinRootParams,
|
||||
): ResolvePathsWithinRootResult {
|
||||
const resolvedPaths: string[] = [];
|
||||
for (const raw of params.requestedPaths) {
|
||||
const pathResult = resolvePathWithinRoot({
|
||||
@@ -166,34 +170,22 @@ export function resolvePathsWithinRoot(params: {
|
||||
return { ok: true, paths: resolvedPaths };
|
||||
}
|
||||
|
||||
export async function resolveExistingPathsWithinRoot(params: {
|
||||
rootDir: string;
|
||||
requestedPaths: string[];
|
||||
scopeLabel: string;
|
||||
}): Promise<{ ok: true; paths: string[] } | { ok: false; error: string }> {
|
||||
return await resolveCheckedPathsWithinRoot({
|
||||
...params,
|
||||
allowMissingFallback: true,
|
||||
});
|
||||
export async function resolveExistingPathsWithinRoot(
|
||||
params: ResolvePathsWithinRootParams,
|
||||
): Promise<ResolvePathsWithinRootResult> {
|
||||
return await resolveCheckedPathsWithinRoot(params, true);
|
||||
}
|
||||
|
||||
export async function resolveStrictExistingPathsWithinRoot(params: {
|
||||
rootDir: string;
|
||||
requestedPaths: string[];
|
||||
scopeLabel: string;
|
||||
}): Promise<{ ok: true; paths: string[] } | { ok: false; error: string }> {
|
||||
return await resolveCheckedPathsWithinRoot({
|
||||
...params,
|
||||
allowMissingFallback: false,
|
||||
});
|
||||
export async function resolveStrictExistingPathsWithinRoot(
|
||||
params: ResolvePathsWithinRootParams,
|
||||
): Promise<ResolvePathsWithinRootResult> {
|
||||
return await resolveCheckedPathsWithinRoot(params, false);
|
||||
}
|
||||
|
||||
async function resolveCheckedPathsWithinRoot(params: {
|
||||
rootDir: string;
|
||||
requestedPaths: string[];
|
||||
scopeLabel: string;
|
||||
allowMissingFallback: boolean;
|
||||
}): Promise<{ ok: true; paths: string[] } | { ok: false; error: string }> {
|
||||
async function resolveCheckedPathsWithinRoot(
|
||||
params: ResolvePathsWithinRootParams,
|
||||
allowMissingFallback: boolean,
|
||||
): Promise<ResolvePathsWithinRootResult> {
|
||||
const rootDir = path.resolve(params.rootDir);
|
||||
// Keep historical behavior for missing roots and rely on openFileWithinRoot for final checks.
|
||||
const rootRealPath = await resolveRealPathIfExists(rootDir);
|
||||
@@ -253,7 +245,7 @@ async function resolveCheckedPathsWithinRoot(params: {
|
||||
});
|
||||
resolvedPaths.push(opened.realPath);
|
||||
} catch (err) {
|
||||
if (params.allowMissingFallback && err instanceof SafeOpenError && err.code === "not-found") {
|
||||
if (allowMissingFallback && err instanceof SafeOpenError && err.code === "not-found") {
|
||||
// Preserve historical behavior for paths that do not exist yet.
|
||||
resolvedPaths.push(pathResult.fallbackPath);
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user