feat(FN-3766): add cli press sqlite store and credential helpers

Implements SQLite-based storage and credential management for the CLI printing press plugin, including type definitions, a persistent `cli-press-store`, and credential helpers, with updated routes, tests, and documentation.

Fusion-Task-Id: FN-3766
This commit is contained in:
Fusion
2026-05-10 18:11:03 -07:00
committed by gsxdsm
parent f7450ba3a2
commit 5a1518acd8
11 changed files with 1004 additions and 98 deletions

View File

@@ -0,0 +1,95 @@
import { Buffer } from "node:buffer";
import type { Credential, EncodedCredentialValue } from "./cli-press-types.js";
import { InvalidCredentialPlacementError, OAuthNotSupportedError } from "./cli-press-types.js";
export type RequestShape = {
headers: Record<string, string>;
query: Record<string, string>;
env: Record<string, string>;
};
export function encodeCredentialValue(raw: string): EncodedCredentialValue {
return {
encoding: "base64",
value: Buffer.from(raw, "utf8").toString("base64"),
};
}
export function decodeCredentialValue(encoded: EncodedCredentialValue): string {
if (encoded.encoding !== "base64") {
throw new Error(`Unsupported credential encoding: ${String((encoded as { encoding?: string }).encoding)}`);
}
return Buffer.from(encoded.value, "base64").toString("utf8");
}
function assertNoOAuth(kind: string): void {
if (kind === "oauth" || kind === "oauth2") {
throw new OAuthNotSupportedError(kind);
}
}
function assertPlacement(credential: Credential): void {
const credentialKind = credential.kind;
const placementKind = credential.placement.kind;
if (placementKind !== credentialKind) {
throw new InvalidCredentialPlacementError({ credentialKind, placementKind });
}
if (credential.kind === "api_key") {
const placement = credential.placement;
if (placement.kind !== "api_key") {
throw new InvalidCredentialPlacementError({ credentialKind, placementKind });
}
const hasHeader = typeof placement.header === "string" && placement.header.trim().length > 0;
const hasQuery = typeof placement.queryParam === "string" && placement.queryParam.trim().length > 0;
if ((hasHeader ? 1 : 0) + (hasQuery ? 1 : 0) !== 1) {
throw new InvalidCredentialPlacementError({ credentialKind, placementKind });
}
}
}
export function applyCredentialToRequest(credential: Credential, request: RequestShape): RequestShape {
assertNoOAuth((credential as { kind: string }).kind);
assertPlacement(credential);
const value = decodeCredentialValue(credential.value);
switch (credential.kind) {
case "header": {
const placement = credential.placement as { kind: "header"; header: string };
request.headers[placement.header] = value;
break;
}
case "query_param": {
const placement = credential.placement as { kind: "query_param"; queryParam: string };
request.query[placement.queryParam] = value;
break;
}
case "env_var": {
const placement = credential.placement as { kind: "env_var"; envVar: string };
request.env[placement.envVar] = value;
break;
}
case "bearer_token": {
const placement = credential.placement as { kind: "bearer_token"; header: string };
request.headers[placement.header] = `Bearer ${value}`;
break;
}
case "api_key": {
const placement = credential.placement as { kind: "api_key"; header?: string; queryParam?: string };
if (placement.header) {
request.headers[placement.header] = value;
} else if (placement.queryParam) {
request.query[placement.queryParam] = value;
}
break;
}
case "basic_auth": {
const placement = credential.placement as { kind: "basic_auth"; header: string };
const basicAuth = Buffer.from(value, "utf8").toString("base64");
request.headers[placement.header] = `Basic ${basicAuth}`;
break;
}
}
return request;
}