/**
* Credential form HTML renderer.
*
* Renders a dark-themed HTML form from a RelayConfigSchema.
* Used as the OAuth authorization page presented to the user during relay config.
*
* This is a TypeScript port of core-py's `credential_form.py`. CSS and embedded JS
* are kept verbatim so the rendered form has visual + behavioral parity between
* Python and TS servers.
*/
export interface ConfigField {
key: string;
label: string;
type: string;
placeholder?: string;
helpText?: string;
helpUrl?: string;
required?: boolean;
/** Regex string for client-side validation; rendered as the input's `pattern` attribute. */
validation?: string;
}
/**
* Return true iff every required field in `schema` has a non-empty value in
* `config`. For schemas whose fields are all optional, requires the explicit
* `_setup_complete: "true"` flag — see core-py `is_schema_complete` docstring.
*
* Strict equality on the flag: only the literal string `"true"` counts. This
* guards against legacy / partial bootstrap entries (e.g. peer-shared cloud
* keys) tricking the auto-open gate into thinking the user has configured.
*/
export declare function isSchemaComplete(config: Record | null | undefined, schema: RelayConfigSchema): boolean;
export interface CapabilityInfo {
label: string;
priority?: string;
description?: string;
}
/**
* A credential-form tab (schema-level `tabs` capability). Each tab is a
* mutually-exclusive credential mode; only the active tab's fields submit.
*/
export interface TabGroup {
id: string;
label: string;
fields: ConfigField[];
}
/**
* A repeatable field group (schema-level `cardGroup` capability). Renders
* Add/Remove cards, each cloning `fields`; submitted as a JSON array under
* `key` (e.g. `{ accounts: [{...}, {...}] }`).
*/
export interface CardGroup {
key: string;
fields: ConfigField[];
itemLabel?: string;
heading?: string;
addButtonLabel?: string;
minItems?: number;
titleField?: string;
}
export interface RelayConfigSchema {
server: string;
displayName?: string;
description?: string;
fields?: ConfigField[];
capabilityInfo?: CapabilityInfo[];
/** Mutually-exclusive credential modes; see the tabbed render path. */
tabs?: TabGroup[];
/** One repeatable field group; see the card-group render path. */
cardGroup?: CardGroup;
}
export interface RenderOptions {
submitUrl: string;
pageTitle?: string;
/**
* Optional ``{KEY: VALUE}`` map populated by the OAuth AS from
* ``?prefill_=`` query params on GET /authorize. Each matching
* field renders with an HTML-escaped ``value="..."`` attr so users only
* type what skret cannot supply (OTP / 2FA / one-time codes). Non-matching
* keys are ignored.
*/
prefill?: Record;
/**
* For a `tabs` schema, the id of the tab to render active on load (defaults
* to the first tab). Ignored for non-tabbed schemas.
*/
initialTab?: string;
/**
* Opt-in workspace-username field (multi-user stable-sub). Honoured by the
* flat, `tabs`, and `cardGroup` render paths.
*/
includeUsernameField?: boolean;
}
/**
* Wrap `bodyHtml` in the shared dark-theme HTML shell.
*
* The shell provides ``, `` (charset, viewport, a
* Content-Security-Policy meta, escaped ``, embedded `FORM_SHELL_CSS`)
* and a `` whose only child is `bodyHtml`. `bodyHtml` is inserted
* verbatim, so callers MUST pre-escape any untrusted values they interpolate.
*
* The CSP (`default-src 'none'; style-src 'unsafe-inline'; script-src
* 'unsafe-inline'; connect-src 'self'`) permits the page's own inline
* `