/** * Host-side credential store for dsh-connect channels. Adapts the DSH * `credentials` provider (`resolve/describe/set/unset`, env-style refs) into a * per-channel interface, so secrets live in the DSH credential store instead of * the plugin config (mirroring dsh-im's `credential-store.mjs`). The web * settings pane reports `configured` booleans and may echo store-backed secret * values (e.g. an appId) so an upgraded user can confirm them, but secrets * never persist to the settings state file — the credential store is the only * place secret values are held. * * @module dsh-connect/settings/credential-store */ import { type ChannelName } from "./channels.js"; /** * One resolved credential: the non-empty secret value plus the source layer * that supplied it (`env`, `file`, `project-env`, `user-env`). Mirrors the * host's `ResolvedCredential` from `@deepseek-ai/dsh-credentials`. * * `resolve` returns this *object*, not a bare string. Reading it as a string * silently yields nothing — see `resolveValue`. */ export interface ResolvedCredential { value: string; source: string; } /** The seam the DSH host provides; `describe` reports source metadata. */ export interface CredentialsProvider { /** * Resolve one ref to its value, or `undefined`/`null` while unconfigured. * The host returns a `{value, source}` record; a plain string is also * accepted so hand-written stubs stay valid. */ resolve(ref: string): Promise; describe(ref: string): Promise<{ configured: boolean; [k: string]: unknown; }>; set(ref: string, value: string): Promise; unset(ref: string): Promise; } /** Maps each channel's secret *config key* to its credential ref, so the * settings service and activation can enrich a channel config from the store. * * This is the **authoritative list of refs a channel owns**: every ref that * `save` can write appears here. A ref reachable only through * {@link CREDENTIAL_GROUPS} would be writable-but-unclearable — `save` and * `clear` both derive from this table for exactly that reason. */ export declare const CHANNEL_SECRET_KEYS: Record>; /** * Credential sets that satisfy a channel, as groups-of-refs. * * Within a group every ref must be configured; between groups any one group * being complete is enough. The grouping exists for DingTalk, which has two * mutually exclusive transports — webhook push (url + signing secret) and * stream mode (client id + secret). A flat all-of list would report a * webhook-only user as "未配置凭据" because their stream refs are empty. * * An empty group list means the channel needs no credentials at all, so it is * always satisfied — `web` mirrors the DSH Web UI in-process and holds no * secret. Reporting that as unconfigured was pure noise in the pane's badge. */ export declare const CREDENTIAL_GROUPS: Record; /** * Flat, de-duplicated view of every ref named by {@link CREDENTIAL_GROUPS}, * in declaration order. Kept because existing callers and tests import it; * new code should prefer `CHANNEL_SECRET_KEYS` for the refs a channel owns. */ export declare const CREDENTIAL_REFS: Record; /** A channel credential store bound to a DSH provider. */ export interface CredentialStore { /** * Whether the channel is usable, i.e. some group of {@link CREDENTIAL_GROUPS} * is fully configured. A channel with no groups is always usable. */ configured(channel: ChannelName): Promise; /** Persist a channel secret under its ref. */ save(channel: ChannelName, values: Record): Promise; /** Read the channel's stored secrets as { configKey: value }. */ get(channel: ChannelName): Promise>; /** Remove every ref for the channel. */ clear(channel: ChannelName): Promise; } /** Build a per-channel credential store over a DSH `credentials` provider. */ export declare function createCredentialStore(provider: CredentialsProvider): CredentialStore; //# sourceMappingURL=credential-store.d.ts.map