Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline (Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/* packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
47 lines
1.7 KiB
TypeScript
47 lines
1.7 KiB
TypeScript
import type { OAuthCredential } from "@earendil-works/pi-ai";
|
|
import { builtinModels } from "@earendil-works/pi-ai/providers/all";
|
|
import { describe, expect, it } from "vitest";
|
|
import { PiRuntimeCredentialStore } from "./pi-credentials.js";
|
|
|
|
function credential(overrides: Partial<OAuthCredential> = {}): OAuthCredential {
|
|
return {
|
|
type: "oauth",
|
|
access: "access-token",
|
|
refresh: "refresh-token",
|
|
expires: Date.now() + 60 * 60_000,
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
describe("PiRuntimeCredentialStore", () => {
|
|
it("does not configure openai-codex without a stored OAuth credential", async () => {
|
|
expect(await builtinModels().getAuth("openai-codex")).toBeUndefined();
|
|
});
|
|
|
|
it("bridges an encrypted OAuth credential into the OAuth-only Codex provider", async () => {
|
|
const store = new PiRuntimeCredentialStore("openai-codex", credential());
|
|
const models = builtinModels({ credentials: store });
|
|
|
|
const auth = await models.getAuth("openai-codex");
|
|
|
|
expect(auth?.auth.apiKey).toBe("access-token");
|
|
expect(await store.list()).toEqual([{ providerId: "openai-codex", type: "oauth" }]);
|
|
});
|
|
|
|
it("serializes refresh publication without exposing credential values in metadata", async () => {
|
|
let persisted: OAuthCredential | undefined;
|
|
const store = new PiRuntimeCredentialStore(
|
|
"openai-codex",
|
|
credential({ access: "old-access" }),
|
|
async (next) => {
|
|
persisted = next;
|
|
},
|
|
);
|
|
|
|
await store.modify("openai-codex", async () => credential({ access: "new-access" }));
|
|
|
|
expect(persisted?.access).toBe("new-access");
|
|
expect(await store.list()).toEqual([{ providerId: "openai-codex", type: "oauth" }]);
|
|
});
|
|
});
|