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 kf { static context: Form static client: Client static formatter: Formatter static user: userObject static account: accountObject static eventParameters: any static api(url: string, args?: FetchOptions): Promise; } // ============================================ // Shared Base Types // ============================================ declare type QueryResponse = { items: any[]; total: number; page?: number; pageSize?: number; }; declare type BaseQueryOptions = { searchValue?: string; pageNumber?: number; pageSize?: number; }; declare type PayloadSortItem = { Id: string; SortType: "ASC" | "DESC"; }; declare type PayloadOptions = { Columns?: any[]; Filters?: any; Sort?: PayloadSortItem[]; FilterParam?: any; }; declare type ProcessPayloadOptions = { Columns?: any[]; Filters?: any; Sort?: PayloadSortItem[]; }; // ============================================ // Core Types // ============================================ declare type userObject = { _id: string; Name: string; Email: string; /** @deprecated Use AppRoles instead. */ Role: string; AppRoles: rolesObject[]; }; declare type rolesObject = { _id: string; Name: string; }; declare type accountObject = { _id: string; }; declare type environmentObject = { isMobile: boolean; }; declare type BoardItem = { _id: string; _view_id: string; }; declare type DataformItem = { _id: string; _view_id?: string; }; declare type ProcessItem = { _id: string; _activity_instance_id: string; }; // ============================================ // Form Field Value Types // ============================================ // The value shape a Geolocation field is stored/read as across the platform // (native forms and custom forms alike) — Latitude/Longitude are stringified // on save, matching the native Geolocation field's saved representation. declare type GeolocationValue = { Address?: string; Latitude: string; Longitude: string; City?: string; State?: string; Country?: string; ZipCode?: string; Area?: string; PlaceId?: string; }; // ============================================ // Process Types // ============================================ declare type ProcessMyItemsOptions = BaseQueryOptions & { status?: | "draft" | "inprogress" | "completed" | "withdrawn" | "rejected" | "all"; payload?: ProcessPayloadOptions; }; declare type ProcessMyTasksOptions = BaseQueryOptions & { activityId?: string; payload?: ProcessPayloadOptions; }; declare type ProcessParticipatedOptions = BaseQueryOptions & { activityId?: string; payload?: ProcessPayloadOptions; }; declare type ProcessAdminOptions = BaseQueryOptions & { payload?: ProcessPayloadOptions; }; declare type ProcessQueryResponse = QueryResponse; declare type ProcessGetItemOptions = { instanceId: string; activityInstanceId: string; }; declare type ProcessCreateItemOptions = { data?: object; }; declare type ProcessUpdateItemOptions = { instanceId: string; activityInstanceId: string; data: object; }; declare type ProcessDeleteItemOptions = { instanceId: string; }; declare type ProcessGetAdminItemOptions = { instanceId: string; }; declare type ProcessUpdateAdminItemOptions = { instanceId: string; data: object; }; declare type ProcessSubmitItemOptions = { instanceId: string; activityInstanceId: string; comment?: string; }; declare type ProcessRejectItemOptions = { instanceId: string; activityInstanceId: string; comment: string; }; declare type ProcessWithdrawItemOptions = { instanceId: string; comment?: string; }; declare type ProcessSendbackItemOptions = { instanceId: string; activityInstanceId: string; stepId: string; comment: string; }; declare type ProcessReassignItemOptions = { instanceId: string; activityInstanceId: string; reassignTo: object; comment: string; reassignType?: "initiator" | "approver" | "admin"; reassignedFrom?: object[]; }; declare type ProcessGetReassigneesOptions = { instanceId: string; activityInstanceId: string; pageNumber?: number; pageSize?: number; query?: string; }; declare type ProcessRestartItemOptions = { instanceId: string; activityInstanceId: string; }; declare type ProcessDiscardItemOptions = { instanceId: string; }; declare type ProcessFieldOptions = { instanceId: string; activityInstanceId: string; fieldId: string; /** Skip the server-side model lookup by supplying the field's type directly. */ fieldType?: string; tableId?: string; tableRowId?: string; }; declare type ProcessAttachmentFile = { id: string; name: string; key: string; size?: number; fileExtension?: string; }; declare type ProcessParseAttachmentOptions = { instanceId: string; // form.instanceId (process record id) activityInstanceId: string; fieldId: string; file: ProcessAttachmentFile; }; declare type ProcessAttachmentParseResult = { appliedFields: string[]; // field IDs auto-filled into the form store suggestedBy: string; // name of the parsed file }; declare type FetchOptions = { method?: string; body?: string | object; headers?: object; }; // ============================================ // Dataform Types // ============================================ declare type DataformQueryOptions = BaseQueryOptions & { viewId?: string; payload?: PayloadOptions; }; declare type DataformQueryResponse = QueryResponse; declare type DataformCreateItemOptions = { data?: object; viewId?: string; }; declare type DataformUpdateItemOptions = { itemId: string; // Required: the _id of the item to update data: object; // Required: the updated field values viewId?: string; // Optional: view ID for view-specific update }; declare type DataformGetItemOptions = { itemId: string; viewId?: string; }; declare type DataformDeleteItemOptions = { itemId: string; viewId?: string; }; declare type DataformDiscardItemOptions = { viewId?: string; }; declare type DataformSubmitItemOptions = { itemId: string; data?: object; viewId?: string; }; declare type DataformFieldOptions = { instanceId: string; fieldId: string; /** Skip the server-side model lookup by supplying the field's type directly. */ fieldType?: string; tableId?: string; tableRowId?: string; }; // ============================================ // Board Types // ============================================ declare type BoardGetItemsOptions = BaseQueryOptions & { viewId?: string; payload?: PayloadOptions; }; declare type BoardQueryResponse = QueryResponse; declare type BoardGetItemOptions = { instanceId: string; }; declare type BoardCreateItemOptions = { data?: object; }; declare type BoardUpdateItemOptions = { instanceId: string; // Required: the _id of the item to update data: object; // Required: the updated field values }; declare type BoardDeleteItemOptions = { instanceId: string; // Required: the _id of the item to delete }; declare type BoardSubmitItemOptions = { instanceId: string; comment?: string; }; declare type BoardDiscardItemOptions = { instanceId: string; }; declare type BoardFieldOptions = { instanceId: string; fieldId: string; /** Skip the server-side model lookup by supplying the field's type directly. */ fieldType?: string; tableId?: string; tableRowId?: string; };