export type JsonValue = string | number | boolean | null | JsonValue[] | {
    [key: string]: JsonValue;
};
export interface FormSchema {
    /**
     * Field names whose values are secret and must never land on a Task node.
     * Declared at the form definition (e.g. `cloudflare-setup-form`'s schema in
     * `cloudflare-setup-types.ts`), not at the writer. Writers pass the form
     * schema through unmodified — the contract is "secrets are declared once
     * where the form is defined, redaction is enforced once at write time."
     */
    secretFields?: string[];
}
export interface RedactResult {
    /**
     * Payload with every `secretFields` entry removed. Non-secret keys keep
     * their values intact (including null, false, 0, empty string). Keys not
     * mentioned in `secretFields` always pass through — secrets are an
     * allow-list of names to drop, not the entire universe.
     */
    redacted: Record<string, JsonValue>;
    /** Number of fields that were stripped. Callers log this when > 0. */
    droppedFields: number;
    /** Names of fields that were stripped, sorted for stable log lines. */
    droppedFieldNames: string[];
}
/**
 * Strip every secret-tagged field from `payload` per `schema`. Pure: no IO,
 * no logging, no thrown errors. Caller is responsible for the
 * `[task] redacted ...` log line when `droppedFields > 0`.
 *
 * Edge-case behaviour:
 * - `payload` undefined / null → empty result, droppedFields=0.
 * - `schema` undefined / no `secretFields` → every key passes through.
 * - A secret field whose key is absent from `payload` → no-op (not counted).
 * - Non-string values on a secret field → key still dropped, value never
 *   inspected. Redaction is by KEY, not by value-shape heuristic.
 */
export declare function redactSecrets(payload: Record<string, JsonValue> | null | undefined, schema: FormSchema | null | undefined): RedactResult;
//# sourceMappingURL=index.d.ts.map