declare class Form {
type: string
instanceId: string
activityInstanceId: string
toJSON(): any;
getField(fieldId: string): any;
updateField(args: object): any;
getValidationErrors(): any;
getFormConfiguration(): any;
getFieldState(): any;
getTable(tableId: string): Table;
}
declare class Table {
toJSON(): any;
getSelectedRows(): any;
getRows(): TableForm[];
getRow(rowId: string): TableForm;
addRow(rowObject: object): any;
addRows(rows: object[]): any;
deleteRow(rowId: string): any;
deleteRows(rows: string[]): any;
}
declare class TableForm {
type: string
getParent(): Form;
toJSON(): any;
getField(fieldId: string): any;
updateField(args: object): any;
}
declare class Client {
/**
* Display an info message toast in the platform.
*
* @param message - The message to display. Accepts a string or object (serialized to JSON).
* @returns A promise that resolves when the message is shown.
*
* @example
* await kf.client.showInfo("Record saved successfully");
*/
showInfo(message: string | object): any;
/**
* Display a confirmation dialog and wait for the user's response.
*
* @param args - Dialog configuration.
* @param args.title - Dialog title.
* @param args.content - Body text of the dialog.
* @param args.okText - Label for the confirm button (default: "Ok").
* @param args.cancelText - Label for the cancel button (default: "Cancel").
* @returns A promise that resolves with `{ action: "OK" }` or `{ action: "CANCEL" }`.
*
* @example
* const { action } = await kf.client.showConfirm({
* title: "Delete record?",
* content: "This cannot be undone.",
* okText: "Delete",
* cancelText: "Cancel",
* });
* if (action === "OK") { ... }
*/
showConfirm(args: {
title: string;
content: string;
okText: string;
cancelText: string;
}): any;
/**
* Navigate the platform to the given URL.
*
* @param url - The URL to navigate to.
*
* @example
* kf.client.redirect("https://example.com");
*/
redirect(url: string): any;
/**
* Resolve a Kissflow image field value to a base64 data URL.
*
* Custom components (iframes) cannot load Kissflow-hosted images directly due to
* CORS restrictions and 302 redirects to signed S3 URLs. This method fetches the
* image in the parent window (which has the required session cookies) and returns
* a self-contained `data:image/...;base64,...` URL that can be used as `
`
* without any CORS issues.
*
* @param imageValue - The image field value must contain a `key` property and
* optionally a `photos` array. Uses `photos[1]` (preview resolution) when available,
* falls back to `key`.
* @returns A promise that resolves with the base64 data URL string.
*
* @example
* const dataUrl = await kf.client.getImageUrl(imageFieldValue);
* document.querySelector("#avatar").src = dataUrl;
*/
getImageUrl(imageValue: Record): any;
/**
* Open the platform's file picker, upload the selected file(s), and resolve
* with their metadata.
*
* Custom components (iframes) cannot access the platform's authenticated upload
* endpoints directly. This method opens the file picker in the parent window
* (which has the required session), runs the full select → upload flow, and
* resolves once all uploads settle with an array of the uploaded files'
* metadata (each including `key`, `name`, `size`, `photos`, etc. — the same
* shape consumed by `getImageUrl`).
*
* Always resolves with an array — a single-element array for single-file
* pickers (e.g. `maxCount: 1` for `Image`), one entry per uploaded file for
* multi-file pickers (e.g. `Attachment`). Resolves with `[]` if the user closes
* the picker without completing any upload.
*
* @param options - File picker configuration (e.g. `fileExtensions`, `maxSize`,
* `maxCount`, `imageProps`).
* @returns A promise that resolves with an array of uploaded file metadata
* objects (empty if the picker was closed without uploading anything).
*
* @example
* const files = await kf.client.openFilePicker({ fileExtensions: ["JPG", "PNG"] });
* if (files.length) onChange(files[0]); // single-file consumer (Image)
*
* @example
* const files = await kf.client.openFilePicker({ maxCount: 10 });
* if (files.length) onChange([...existing, ...files]); // multi-file consumer (Attachment)
*/
openFilePicker(options: FilePickerOptions): any;
/**
* Open the platform's barcode/QR scanner and resolve with the decoded text.
*
* The scanner UI (camera stream + decoding) runs in the parent window, which
* owns the camera permission — the iframe itself never accesses the camera.
* Camera-permission prompts and denials are handled inside the scanner UI;
* they are not surfaced as errors here.
*
* Resolves with `null` if the user closes the scanner without a successful
* scan (including the scanner's own inactivity timeout).
*
* Note: currently supported in web custom app UIs; the mobile (PWA) custom
* UI does not host the scanner portal yet.
*
* @param options - Scanner configuration (e.g. `localFileScan` to allow
* decoding from an uploaded image instead of the camera).
* @returns A promise that resolves with the decoded string, or `null` if the
* scanner was closed without scanning.
*
* @example
* const code = await kf.client.openScanner({ localFileScan: true });
* if (code) onChange(code);
*/
openScanner(options?: ScannerOptions): any;
/**
* Open the platform's native Geolocation map picker (search, current-location
* detection, marker drag, reverse-geocoding) in a modal over the custom
* form/component. Runs in the parent window, which owns the Google Maps API
* key — the iframe itself never needs one.
*
* Resolves with `null` if the user closes the picker without selecting a
* location.
*
* @param value - Optional current geolocation value to pre-select on the map.
* @returns A promise that resolves with the picked location object, or
* `null` if the picker was closed without a selection.
*
* @example
* const location = await kf.client.pickLocation();
* if (location) onChange(location);
*/
pickLocation(value?: GeolocationValue): any;
/**
* Upload a File object to Kissflow's S3 storage and resolve with its metadata.
*
* Use this when you have a File/Blob already in memory (e.g. a canvas drawing
* converted to a PNG blob) and need to upload it without opening a file picker UI.
* The platform runs the upload in the parent window (which has the required session)
* and resolves with the uploaded file's `{ key, name, ... }` metadata — the same
* shape returned by `openFilePicker`.
*
* Resolves with `null` if the upload fails.
*
* @param file - The File or Blob to upload.
* @param fileName - Optional file name override (defaults to `file.name`).
* @returns A promise that resolves with the uploaded file metadata, or `null` on failure.
*
* @example
* const blob = await new Promise(res => canvas.toBlob(res, 'image/png'));
* const file = new File([blob], 'signature.png', { type: 'image/png' });
* const result = await kf.client.uploadFile(file);
* if (result) onChange(result);
*/
uploadFile(file: UploadableFile, fileName?: string): any;
/**
* Open the platform's file preview (lightbox) for one or more files.
*
* `files` always accepts an array — pass a single-element array for fields like
* `Image`, or the full list for multi-file fields like `Attachment`. The host's
* preview UI natively renders next/prev navigation across the array; the SDK
* just passes the file list through, no extra navigation surface is needed here.
*
* @param args - Preview configuration.
* @param args.files - Array of file metadata objects to preview.
* @param args.indexOfFile - Index of the file to open the preview on (default: 0).
* @returns A promise that resolves once the user closes the preview.
*
* @example
* await kf.client.openFilePreview({ files: [imageFieldValue] });
* await kf.client.openFilePreview({ files: attachmentFieldValue, indexOfFile: 2 });
*/
openFilePreview(args: {
files: Record[];
indexOfFile?: number;
}): any;
}
declare class Formatter {
toDate(date: string): any;
toDateTime(date: string): any;
toNumber(value: string): any;
toCurrency(value: string, currencyCode: string): any;
toBoolean(value: string): any;
}
declare class Component {
_id: string
type: string
onMount(callback: Function): void;
refresh(): any;
/** @deprecated Use condition visibility instead. */
show(): any;
/** @deprecated Use condition visibility instead. */
hide(): any;
}
declare class Popup {
_id: string
type: string
getParameter(key: string): any;
getAllParameters(): any;
close(): any;
getComponent(componentId: string): Component;
}
declare class Page {
_id: string
popup: Popup
type: string
_route: string
getParameter(key: string): any;
getAllParameters(): any;
getVariable(key: string): any;
setVariable(key: string | object, value?: any): any;
openPopup(popupId: string, popupParams?: object): any;
getComponent(componentId: string): Component;
/**
* Notify the Kissflow host that the custom UI navigated to `path`,
* so the parent browser URL mirrors the route. Used by the App UI framework.
*/
setRoute(path: string): void;
/** Returns the initial deep-link route the page was opened with. */
getRoute(): string;
}
declare class DecisionTable {
evaluate(payload?: object): any;
}
declare class Dataform {
/**
* Get all items from this dataform with optional filtering, sorting, and pagination
* @param options - Query options (searchValue, pageNumber, pageSize, payload)
* @returns Promise containing items and total count
*/
getItems(options?: DataformQueryOptions): Promise;
/**
* Get a single item by ID from this dataform
* @param options - itemId (required), optional viewId
* @returns Promise containing the item data
*/
getItem(options: DataformGetItemOptions): Promise;
/**
* Create a new item in this dataform
* @param options - Creation options (data: initial field values, viewId: optional view ID)
* @returns Promise containing the newly created item with _id
*/
createItem(options?: DataformCreateItemOptions): Promise;
/**
* Update an existing item in this dataform
* @param options - Update options (itemId: required, data: required updated values, viewId: optional view ID)
* @returns Promise containing the updated item
*/
updateItem(options: DataformUpdateItemOptions): Promise;
/**
* Import items from a CSV file into this dataform
* @param defaultValues - Optional default field values to apply to all imported items
*/
importCSV(defaultValues?: object): any;
/**
* Open the form UI for an existing dataform item
* @param item - Dataform item with _id and optional _view_id
*/
openForm(item: DataformItem): any;
/**
* Delete an item from this dataform
* @param options - itemId (required), optional viewId
*
* @example
* await dataform.deleteItem({ itemId: "item_123" });
*/
deleteItem(options: DataformDeleteItemOptions): Promise;
/**
* Discard the current draft for this dataform
* @param options - optional viewId
*
* @example
* await dataform.discardItem();
*/
discardItem(options?: DataformDiscardItemOptions): Promise;
/**
* Submit/finalize a dataform item
* @param options - itemId (required), optional data and viewId
*
* @example
* await dataform.submitItem({ itemId: "item_123" });
*/
submitItem(options: DataformSubmitItemOptions): Promise;
/**
* Get field definitions for this dataform
* @param options - Optional viewId to scope fields to a specific view
*/
getFields(options?: {
viewId?: string;
}): Promise;
/**
* Initialize a form with all necessary data (schema, item data, form store)
* This is the recommended way to create a custom form for dataform records
* It automatically handles fetching schema, item data, and initializing the form store
*
* @param instanceId - Optional instance ID of the dataform record. If omitted, creates a new record
* @param viewId - Optional view ID to scope the form's schema/permissions to a specific view
* @returns Promise with Form instance ready to use
*
* @example
* // Load existing record
* const dataform = kf.app.getDataform("EmpMaster");
* const form = await dataform.initForm("emp_123");
* const data = await form.toJSON();
*
* // Load existing record scoped to a view
* const form = await dataform.initForm("emp_123", "EmpMaster_View");
*
* // Create new record
* const form = await dataform.initForm();
* await form.updateField({ firstName: "John" });
*/
initForm(instanceId?: string, viewId?: string): Promise