Files
openclaw/src/agents/auth-profiles/upsert-with-lock.ts
2026-03-16 12:06:32 +00:00

57 lines
2.1 KiB
TypeScript

import { withFileLock } from "../../infra/file-lock.js";
import { loadJsonFile, saveJsonFile } from "../../infra/json-file.js";
import { AUTH_STORE_LOCK_OPTIONS, AUTH_STORE_VERSION } from "./constants.js";
import { ensureAuthStoreFile, resolveAuthStorePath } from "./paths.js";
import type { AuthProfileCredential, AuthProfileStore, ProfileUsageStats } from "./types.js";
function coerceAuthProfileStore(raw: unknown): AuthProfileStore {
const record = raw && typeof raw === "object" ? (raw as Record<string, unknown>) : {};
const profiles =
record.profiles && typeof record.profiles === "object" && !Array.isArray(record.profiles)
? { ...(record.profiles as Record<string, AuthProfileCredential>) }
: {};
const order =
record.order && typeof record.order === "object" && !Array.isArray(record.order)
? (record.order as Record<string, string[]>)
: undefined;
const lastGood =
record.lastGood && typeof record.lastGood === "object" && !Array.isArray(record.lastGood)
? (record.lastGood as Record<string, string>)
: undefined;
const usageStats =
record.usageStats && typeof record.usageStats === "object" && !Array.isArray(record.usageStats)
? (record.usageStats as Record<string, ProfileUsageStats>)
: undefined;
return {
version:
typeof record.version === "number" && Number.isFinite(record.version)
? record.version
: AUTH_STORE_VERSION,
profiles,
...(order ? { order } : {}),
...(lastGood ? { lastGood } : {}),
...(usageStats ? { usageStats } : {}),
};
}
export async function upsertAuthProfileWithLock(params: {
profileId: string;
credential: AuthProfileCredential;
agentDir?: string;
}): Promise<AuthProfileStore | null> {
const authPath = resolveAuthStorePath(params.agentDir);
ensureAuthStoreFile(authPath);
try {
return await withFileLock(authPath, AUTH_STORE_LOCK_OPTIONS, async () => {
const store = coerceAuthProfileStore(loadJsonFile(authPath));
store.profiles[params.profileId] = params.credential;
saveJsonFile(authPath, store);
return store;
});
} catch {
return null;
}
}