import { DenoS3LightClientSettings, type S3Object } from "./s3Types"; export { parseS3Object, type S3Object, type S3ObjectRecord, type S3ObjectURI, } from "./s3Types"; export { datatable, ducklake, upsertPartition, appendPartition, type SqlTemplateFunction, type DatatableSqlTemplateFunction, type DucklakeMaterializeOptions, type SqlStatement, } from "./sqlUtils"; export type Sql = string; export type Email = string; export type Base64 = string; export type Resource = any; export declare const SHARED_FOLDER = "/shared"; export declare function workerHasInternalServer(): boolean; /** * Initialize the Windmill client with authentication token and base URL * @param token - Authentication token (defaults to WM_TOKEN env variable) * @param baseUrl - API base URL (defaults to BASE_INTERNAL_URL or BASE_URL env variable) */ export declare function setClient(token?: string, baseUrl?: string): void; export declare const getEnv: (key: string) => string | undefined; /** * Create a client configuration from env variables * @returns client configuration */ export declare function getWorkspace(): string; /** * Get a resource value by path * @param path path of the resource, default to internal state path * @param undefinedIfEmpty if the resource does not exist, return undefined instead of throwing an error * @returns resource value */ export declare function getResource(path?: string, undefinedIfEmpty?: boolean): Promise; /** * Get the true root job id * @param jobId job id to get the root job id from (default to current job) * @returns root job id */ export declare function getRootJobId(jobId?: string): Promise; /** * @deprecated Use runScriptByPath or runScriptByHash instead */ export declare function runScript(path?: string | null, hash_?: string | null, args?: Record | null, verbose?: boolean, tag?: string | null): Promise; /** * Run a script synchronously by its path and wait for the result * @param path - Script path in Windmill * @param args - Arguments to pass to the script * @param verbose - Enable verbose logging * @param tag - Override the worker tag the job runs on * @returns Script execution result */ export declare function runScriptByPath(path: string, args?: Record | null, verbose?: boolean, tag?: string | null): Promise; /** * Run a script synchronously by its hash and wait for the result * @param hash_ - Script hash in Windmill * @param args - Arguments to pass to the script * @param verbose - Enable verbose logging * @param tag - Override the worker tag the job runs on * @returns Script execution result */ export declare function runScriptByHash(hash_: string, args?: Record | null, verbose?: boolean, tag?: string | null): Promise; /** * Append a text to the result stream * @param text text to append to the result stream */ export declare function appendToResultStream(text: string): void; /** * Stream to the result stream * @param stream stream to stream to the result stream */ export declare function streamResult(stream: AsyncIterable): Promise; /** * Run a flow synchronously by its path and wait for the result * @param path - Flow path in Windmill * @param args - Arguments to pass to the flow * @param verbose - Enable verbose logging * @param tag - Override the worker tag the job runs on * @returns Flow execution result */ export declare function runFlow(path?: string | null, args?: Record | null, verbose?: boolean, tag?: string | null): Promise; /** * Wait for a job to complete and return its result * @param jobId - ID of the job to wait for * @param verbose - Enable verbose logging * @returns Job result when completed */ export declare function waitJob(jobId: string, verbose?: boolean): Promise; /** * Get the result of a completed job * @param jobId - ID of the completed job * @returns Job result */ export declare function getResult(jobId: string): Promise; /** * Get the result of a job if completed, or its current status * @param jobId - ID of the job * @returns Object with started, completed, success, and result properties */ export declare function getResultMaybe(jobId: string): Promise; /** * Cancel a queued or running job by ID. * @param jobId - UUID of the job to cancel * @param reason - Optional reason for cancellation * @returns Response message from the cancel endpoint */ export declare function cancelJob(jobId: string, reason?: string | undefined): Promise; /** * @deprecated Use runScriptByPathAsync or runScriptByHashAsync instead */ export declare function runScriptAsync(path: string | null, hash_: string | null, args: Record | null, scheduledInSeconds?: number | null, tag?: string | null): Promise; /** * Run a script asynchronously by its path * @param path - Script path in Windmill * @param args - Arguments to pass to the script * @param scheduledInSeconds - Schedule execution for a future time (in seconds) * @param tag - Override the worker tag the job runs on * @returns Job ID of the created job */ export declare function runScriptByPathAsync(path: string, args?: Record | null, scheduledInSeconds?: number | null, tag?: string | null): Promise; /** * Run a script asynchronously by its hash * @param hash_ - Script hash in Windmill * @param args - Arguments to pass to the script * @param scheduledInSeconds - Schedule execution for a future time (in seconds) * @param tag - Override the worker tag the job runs on * @returns Job ID of the created job */ export declare function runScriptByHashAsync(hash_: string, args?: Record | null, scheduledInSeconds?: number | null, tag?: string | null): Promise; /** * Run a flow asynchronously by its path * @param path - Flow path in Windmill * @param args - Arguments to pass to the flow * @param scheduledInSeconds - Schedule execution for a future time (in seconds) * @param doNotTrackInParent - If false, tracks state in parent job (only use when fully awaiting the job) * @param tag - Override the worker tag the job runs on * @returns Job ID of the created job */ export declare function runFlowAsync(path: string | null, args: Record | null, scheduledInSeconds?: number | null, doNotTrackInParent?: boolean, tag?: string | null): Promise; /** * Resolve a resource value in case the default value was picked because the input payload was undefined * @param obj resource value or path of the resource under the format `$res:path` * @returns resource value */ export declare function resolveDefaultResource(obj: any): Promise; /** * Get the state file path from environment variables * @returns State path string */ export declare function getStatePath(): string; /** * Set a resource value by path * @param path path of the resource to set, default to state path * @param value new value of the resource to set * @param initializeToTypeIfNotExist if the resource does not exist, initialize it with this type */ export declare function setResource(value: any, path?: string, initializeToTypeIfNotExist?: string): Promise; /** * Set the state * @param state state to set * @deprecated use setState instead */ export declare function setInternalState(state: any): Promise; /** * Set the state * @param state state to set * @param path Optional state resource path override. Defaults to `getStatePath()`. */ export declare function setState(state: any, path?: string): Promise; /** * Set the progress * Progress cannot go back and limited to 0% to 99% range * @param percent Progress to set in % * @param jobId? Job to set progress for */ export declare function setProgress(percent: number, jobId?: any): Promise; /** * Get the progress * @param jobId? Job to get progress from * @returns Optional clamped between 0 and 100 progress value */ export declare function getProgress(jobId?: any): Promise; /** * Set a flow user state * @param key key of the state * @param value value of the state */ export declare function setFlowUserState(key: string, value: any, errorIfNotPossible?: boolean): Promise; /** * Get a flow user state * @param path path of the variable */ export declare function getFlowUserState(key: string, errorIfNotPossible?: boolean): Promise; /** * Get the internal state * @deprecated use getState instead */ export declare function getInternalState(): Promise; /** * Get the state shared across executions * @param path Optional state resource path override. Defaults to `getStatePath()`. */ export declare function getState(path?: string): Promise; /** * Get a variable by path * @param path path of the variable * @returns variable value */ export declare function getVariable(path: string): Promise; /** * Set a variable by path, create if not exist * @param path path of the variable * @param value value of the variable * @param isSecretIfNotExist if the variable does not exist, create it as secret or not (default: false) * @param descriptionIfNotExist if the variable does not exist, create it with this description (default: "") */ export declare function setVariable(path: string, value: string, isSecretIfNotExist?: boolean, descriptionIfNotExist?: string): Promise; /** * Build a PostgreSQL connection URL from a database resource * @param path - Path to the database resource * @returns PostgreSQL connection URL string */ export declare function databaseUrlFromResource(path: string): Promise; /** * Get S3 client settings from a resource or workspace default * @param s3_resource_path - Path to S3 resource (uses workspace default if undefined) * @param workspace - Workspace to read from (defaults to the `WM_WORKSPACE` env var) * @returns S3 client configuration settings */ export declare function denoS3LightClientSettings(s3_resource_path: string | undefined, workspace?: string | undefined): Promise; /** * Load the content of a file stored in S3. If the s3ResourcePath is undefined, it will default to the workspace S3 resource. * * ```typescript * let fileContent = await wmill.loadS3FileContent(inputFile) * // if the file is a raw text file, it can be decoded and printed directly: * const text = new TextDecoder().decode(fileContentStream) * console.log(text); * ``` * * @param workspace - Workspace to read from (defaults to the `WM_WORKSPACE` env var) */ export declare function loadS3File(s3object: S3Object, s3ResourcePath?: string | undefined, workspace?: string | undefined): Promise; /** * Load the content of a file stored in S3 as a stream. If the s3ResourcePath is undefined, it will default to the workspace S3 resource. * * ```typescript * let fileContentBlob = await wmill.loadS3FileStream(inputFile) * // if the content is plain text, the blob can be read directly: * console.log(await fileContentBlob.text()); * ``` * * @param workspace - Workspace to read from (defaults to the `WM_WORKSPACE` env var) */ export declare function loadS3FileStream(s3object: S3Object, s3ResourcePath?: string | undefined, workspace?: string | undefined): Promise; /** * Persist a file to the S3 bucket. If the s3ResourcePath is undefined, it will default to the workspace S3 resource. * * ```typescript * const s3object = await writeS3File(s3Object, "Hello Windmill!") * const fileContentAsUtf8Str = (await s3object.toArray()).toString('utf-8') * console.log(fileContentAsUtf8Str) * ``` * * @param workspace - Workspace to write to (defaults to the `WM_WORKSPACE` env var) */ export declare function writeS3File(s3object: S3Object | undefined, fileContent: string | Blob, s3ResourcePath?: string | undefined, contentType?: string | undefined, contentDisposition?: string | undefined, workspace?: string | undefined): Promise; /** * Permanently delete a file from S3 by key. * * ```typescript * await wmill.deleteS3File({ s3: "path/to/file.txt" }) * ``` * * @param s3object - S3 object identifying the file to delete (must have `s3` set) * @param workspace - Workspace to delete from (defaults to the `WM_WORKSPACE` env var) */ export declare function deleteS3File(s3object: S3Object, workspace?: string | undefined): Promise; /** * Sign S3 objects to be used by anonymous users in public apps * @param s3objects s3 objects to sign * @param expirySecs how long the signature stays valid, in seconds (default 43200 = 12h, clamped to [60, 604800]) * @returns signed s3 objects */ export declare function signS3Objects(s3objects: S3Object[], { expirySecs }?: { expirySecs?: number; }): Promise; /** * Sign S3 object to be used by anonymous users in public apps * @param s3object s3 object to sign * @param expirySecs how long the signature stays valid, in seconds (default 43200 = 12h, clamped to [60, 604800]) * @returns signed s3 object */ export declare function signS3Object(s3object: S3Object, { expirySecs }?: { expirySecs?: number; }): Promise; /** * Generate a presigned public URL for an array of S3 objects. * If an S3 object is not signed yet, it will be signed first. * @param s3Objects s3 objects to sign * @param expirySecs how long the signature stays valid, in seconds (default 43200 = 12h, clamped to [60, 604800]) * @returns list of signed public URLs */ export declare function getPresignedS3PublicUrls(s3Objects: S3Object[], { baseUrl, expirySecs }?: { baseUrl?: string; expirySecs?: number; }): Promise; /** * Generate a presigned public URL for an S3 object. If the S3 object is not signed yet, it will be signed first. * @param s3Object s3 object to sign * @param expirySecs how long the signature stays valid, in seconds (default 43200 = 12h, clamped to [60, 604800]) * @returns signed public URL */ export declare function getPresignedS3PublicUrl(s3Objects: S3Object, { baseUrl, expirySecs }?: { baseUrl?: string; expirySecs?: number; }): Promise; /** * Get URLs needed for resuming a flow after this step * @param approver approver name * @param flowLevel if true, generate resume URLs for the parent flow instead of the specific step. * This allows pre-approvals that can be consumed by any later suspend step in the same flow. * @returns approval page UI URL, resume and cancel API URLs for resuming the flow */ export declare function getResumeUrls(approver?: string, flowLevel?: boolean): Promise<{ approvalPage: string; resume: string; cancel: string; }>; /** * @deprecated use getResumeUrls instead */ export declare function getResumeEndpoints(approver?: string): Promise<{ approvalPage: string; resume: string; cancel: string; }>; /** * Get an OIDC jwt token for auth to external services (e.g: Vault, AWS) (ee only) * @param audience audience of the token * @param expiresIn Optional number of seconds until the token expires * @returns jwt token */ export declare function getIdToken(audience: string, expiresIn?: number): Promise; /** * Convert a base64-encoded string to Uint8Array * @param data - Base64-encoded string * @returns Decoded Uint8Array */ export declare function base64ToUint8Array(data: string): Uint8Array; /** * Convert a Uint8Array to base64-encoded string * @param arrayBuffer - Uint8Array to encode * @returns Base64-encoded string */ export declare function uint8ArrayToBase64(arrayBuffer: Uint8Array): string; /** * Get email from workspace username * @deprecated Read the contextual variables instead: `process.env.WM_END_USER_EMAIL || process.env.WM_EMAIL`. * WM_END_USER_EMAIL is the email of whoever triggered the run when it came from an app, so the fallback * yields the app viewer inside an app and the executing user everywhere else - without an extra API call, * and unlike this function it also resolves viewers who are not workspace members. An app viewed * anonymously has no identity to report: the variable is then empty and the fallback yields the publisher. * @param username * @returns email address */ export declare function usernameToEmail(username: string): Promise; interface SlackApprovalOptions { slackResourcePath: string; channelId: string; message?: string; approver?: string; defaultArgsJson?: Record; dynamicEnumsJson?: Record; resumeButtonText?: string; cancelButtonText?: string; } interface TeamsApprovalOptions { teamName: string; channelName: string; message?: string; approver?: string; defaultArgsJson?: Record; dynamicEnumsJson?: Record; } /** * Sends an interactive approval request via Slack, allowing optional customization of the message, approver, and form fields. * * **[Enterprise Edition Only]** To include form fields in the Slack approval request, go to **Advanced -> Suspend -> Form** * and define a form. Learn more at [Windmill Documentation](https://www.windmill.dev/docs/flows/flow_approval#form). * * @param {Object} options - The configuration options for the Slack approval request. * @param {string} options.slackResourcePath - The path to the Slack resource in Windmill. * @param {string} options.channelId - The Slack channel ID where the approval request will be sent. * @param {string} [options.message] - Optional custom message to include in the Slack approval request. * @param {string} [options.approver] - Optional user ID or name of the approver for the request. * @param {DefaultArgs} [options.defaultArgsJson] - Optional object defining or overriding the default arguments to a form field. * @param {Enums} [options.dynamicEnumsJson] - Optional object overriding the enum default values of an enum form field. * @param {string} [options.resumeButtonText] - Optional text for the resume button. * @param {string} [options.cancelButtonText] - Optional text for the cancel button. * * @returns {Promise} Resolves when the Slack approval request is successfully sent. * * @throws {Error} If the function is not called within a flow or flow preview. * @throws {Error} If the `JobService.getSlackApprovalPayload` call fails. * * **Usage Example:** * ```typescript * await requestInteractiveSlackApproval({ * slackResourcePath: "/u/alex/my_slack_resource", * channelId: "admins-slack-channel", * message: "Please approve this request", * approver: "approver123", * defaultArgsJson: { key1: "value1", key2: 42 }, * dynamicEnumsJson: { foo: ["choice1", "choice2"], bar: ["optionA", "optionB"] }, * resumeButtonText: "Resume", * cancelButtonText: "Cancel", * }); * ``` * * **Note:** This function requires execution within a Windmill flow or flow preview. */ export declare function requestInteractiveSlackApproval({ slackResourcePath, channelId, message, approver, defaultArgsJson, dynamicEnumsJson, resumeButtonText, cancelButtonText, }: SlackApprovalOptions): Promise; /** * Sends an interactive approval request via Teams, allowing optional customization of the message, approver, and form fields. * * **[Enterprise Edition Only]** To include form fields in the Teams approval request, go to **Advanced -> Suspend -> Form** * and define a form. Learn more at [Windmill Documentation](https://www.windmill.dev/docs/flows/flow_approval#form). * * @param {Object} options - The configuration options for the Teams approval request. * @param {string} options.teamName - The Teams team name where the approval request will be sent. * @param {string} options.channelName - The Teams channel name where the approval request will be sent. * @param {string} [options.message] - Optional custom message to include in the Teams approval request. * @param {string} [options.approver] - Optional user ID or name of the approver for the request. * @param {DefaultArgs} [options.defaultArgsJson] - Optional object defining or overriding the default arguments to a form field. * @param {Enums} [options.dynamicEnumsJson] - Optional object overriding the enum default values of an enum form field. * * @returns {Promise} Resolves when the Teams approval request is successfully sent. * * @throws {Error} If the function is not called within a flow or flow preview. * @throws {Error} If the `JobService.getTeamsApprovalPayload` call fails. * * **Usage Example:** * ```typescript * await requestInteractiveTeamsApproval({ * teamName: "admins-teams", * channelName: "admins-teams-channel", * message: "Please approve this request", * approver: "approver123", * defaultArgsJson: { key1: "value1", key2: 42 }, * dynamicEnumsJson: { foo: ["choice1", "choice2"], bar: ["optionA", "optionB"] }, * }); * ``` * * **Note:** This function requires execution within a Windmill flow or flow preview. */ export declare function requestInteractiveTeamsApproval({ teamName, channelName, message, approver, defaultArgsJson, dynamicEnumsJson, }: TeamsApprovalOptions): Promise; export declare class StepSuspend extends Error { dispatchInfo: Record; constructor(dispatchInfo: Record); } /** Values `JSON.stringify` cannot represent: it omits the property holding one. * The type-level half of `checkpointableResult`, which nulls them at the top * level, where there is no key to omit. */ type JsonDropped = ((...args: any[]) => any) | (abstract new (...args: any[]) => any) | symbol; /** * What a value looks like after the JSON round trip a checkpoint performs: * `Date` → string, `Map`/`Set` → `{}`, `undefined` → null, methods gone. * `NaN` and the infinities decode as null too, deliberately still typed * `number`: `number | null` everywhere costs more than that case is worth. * * Mirrors `encodeCheckpointPayload` below — keep the two in step, or `step()` * starts describing a value it does not return. */ export type Jsonified = 0 extends 1 & T ? any : unknown extends T ? unknown : T extends string | number | boolean | null ? T : T extends undefined | void | symbol | ((...args: any[]) => any) ? null : T extends bigint ? string : T extends { toJSON(): infer R; } ? Jsonified : T extends ReadonlyMap | ReadonlySet ? Record : T extends readonly any[] ? { [K in keyof T]: Jsonified; } : T extends object ? JsonifiedObject : never; /** * `JSON.stringify` keeps own enumerable string keys whose value it can * represent. A key that can only hold an unrepresentable value is gone; one * that merely might becomes optional, because it can come back missing — * `| undefined` alone would still demand the key be there. */ type JsonifiedObject = Flatten<{ [K in keyof T as K extends symbol ? never : [Exclude] extends [never] ? never : [T[K]] extends [Exclude] ? K : never]: Jsonified; } & { [K in keyof T as K extends symbol ? never : [Exclude] extends [never] ? never : [T[K]] extends [Exclude] ? never : K]?: Jsonified>; }>; /** Collapse the two halves above into one object, so hovering `Jsonified` shows * a shape rather than an intersection. */ type Flatten = { [K in keyof T]: T[K]; }; /** * A task function as its callers see it. A task's result always crosses a JSON * boundary — the child job's result is read back from the checkpoint, and the * v1 path reads it back from the API — so only {@link Jsonified} of it survives. * * Rebuilding the signature costs some precision TypeScript cannot preserve: a * generic task's type parameters instantiate at their constraints, and an * overloaded one keeps only its last signature. Neither survives JSON anyway. */ export type JsonifiedFn Promise> = (...args: Parameters) => Promise>>>; /** Re-dispatch policy for a failed task. * * Every attempt is a step of its own (`fetch`, `fetch#2`, `fetch#3`), and the * wait between two of them is a durable sleep, so a retrying task holds no * worker while it backs off. * * A workflow sleeps once per round, so tasks backing off in the same fan-out * wait one after another rather than together: the delay before a fan-out * retries is the sum of every backoff pending in it, not the longest one, and * it grows with both the width of the fan-out and `attempts`. Retries with no * `delay` all go out in a single round. */ export interface TaskRetry { /** Attempts after the first failure: `2` runs the task at most 3 times. * A whole number from 0 to 100; anything else is rejected where the policy * is written. */ attempts: number; /** Seconds to wait before the first retry. Default 0, retry immediately. * Sub-second delays are dropped — a durable sleep resolves to the second. */ delay?: number; /** Applied to the delay after each attempt: 1 (the default) keeps it * constant, 2 doubles it. */ multiplier?: number; /** Ceiling for the delay in seconds, for a `multiplier` above 1. */ max_delay?: number; } export interface TaskOptions { timeout?: number; tag?: string; /** Seconds during which a previous result of this task is served instead of * running it again. A task written inline in the workflow is keyed on its * step key (its name and call order) and the workflow's input, not on the * arguments it is called with, so cache one only when whether it runs, and * what it receives, follow from the workflow's input alone. A `taskScript` * target is keyed on the arguments it is called with. It has no effect on a * `taskFlow` target, which keeps its flow's own cache policy. */ cache_ttl?: number; priority?: number; concurrency_limit?: number; concurrency_key?: string; concurrency_time_window_s?: number; retry?: TaskRetry; } export declare let _workflowCtx: WorkflowCtx | null; export declare function setWorkflowCtx(ctx: WorkflowCtx | null): void; export declare class WorkflowCtx { private completed; /** Null-prototype: step keys are caller-supplied, and a plain object would * resolve `toString`/`constructor`/`__proto__` off `Object.prototype`. */ private counters; /** Every key handed out by `_allocKey`, so distinct names can't alias one key. */ private _usedKeys; private pending; private _suspended; /** The last suspend this ctx raised. `StepSuspend` is an `Error`, so any * `catch` in the workflow body swallows it and the run would report a * `complete` whose step never reached `completed_steps`. Python is immune: * `_StepSuspend` derives from `BaseException`. */ private _pendingSuspend; /** The failure raised by the step this child round is executing. That exception * *is* the round's result, so a `catch` in the body must not be able to turn it * into a `complete` — the parent would then record the caught branch's value as * a successful step. Boxed: the thrown value may be any falsy value. */ private _pendingStepFailure; /** Failed tasks whose rejection nothing has consumed, by step key. An unawaited * task is still dispatched and still fails, but nothing drives the rejecting * thenable it returned. The first `.then()` on that thenable drops the entry, * so what remains is only what the body never looked at. */ private _unobservedTaskFailures; /** When set, the task matching this key executes its inner function directly */ _executingKey: string | null; /** Serializes fast-path POSTs across concurrent step() calls within one * workflow invocation. Wraps only the HTTP call, not fn() — so * `Promise.all([step("a", fn_a), step("b", fn_b)])` still runs the two * fn() bodies in parallel, only the API requests are ordered. This * closes the first-write race window against `SELECT FOR UPDATE` on a * not-yet-created `v2_job_status` row: two concurrent POSTs would both * see None and overwrite each other's checkpoint because the helper * writes the whole serialized `_checkpoint` object, not a single * `completed_steps[key]`. Initialized to a resolved promise. */ private _inlineChain; constructor(checkpoint?: Record); /** Name-based key: `double` for first call, `double_2`, `double_3` for subsequent. * Suffixing alone can alias — a second `step("x")` and a first `step("x_2")` both * want `x_2` — so keep bumping past keys already handed out. Allocation order is * fixed by the workflow body, so replays reproduce the same keys. */ _allocKey(name: string): string; _nextStep(name: string, script: string, args?: Record, dispatch_type?: string, options?: TaskOptions): PromiseLike; /** Wait out the backoff between two attempts of a retried task, as a durable * sleep, and return once there is nothing to wait for — no delay configured, * or the sleep already in the checkpoint. * * Raises where it stands, the way `_sleep` does, rather than handing back a * thenable: a task call the body never awaits is still dispatched (the runner * flushes `pending`), so a backoff that only fired when awaited would drop * the retry and let the round report the workflow complete. */ private _retryBackoff; /** Return and clear any pending (unawaited) steps. */ _flushPending(): Array<{ name: string; script: string; args: Record; key: string; dispatch_type: string; }>; _waitForApproval(options?: { timeout?: number; form?: object; selfApproval?: boolean; key?: string; skin?: "detailed" | "minimal"; description?: string | object; }): PromiseLike<{ value: any; approver: string; approved: boolean; }>; _sleep(seconds: number): PromiseLike; _runInlineStep(name: string, fn: () => T | Promise): Promise; /** Raise a suspend, parking it so a body that catches it cannot make it * vanish. Every suspend raised for this ctx must go through here. */ _raiseSuspend(dispatchInfo: Record): never; /** Park then raise the executing step's failure. Child mode only — in a parent * round a task failure is an ordinary `TaskError` the body may handle. */ _raiseStepFailure(error: unknown): never; /** Re-throw a swallowed suspend or step failure at the next SDK call. It * happened before whatever the body is doing now, so it wins: the run is * unwinding either way and everything after it re-runs on the replay. Left * set, so a body that catches in a loop can't swallow it a second time. */ private _rethrowSwallowed; /** Hand the runner a suspend the workflow body caught and swallowed, so it is * honoured instead of silently turning into a `complete`. Returns null when * the suspend propagated normally. */ _takePendingSuspend(): StepSuspend | null; /** Same for the executing step's failure, so the runner can fail the child job. */ _takePendingStepFailure(): { error: unknown; } | null; /** Report the task failures the body never looked at, and forget them. Which * rounds may call this is the runner's constraint, stated where it is enforced. */ _warnUnobservedTaskFailures(): void; } export declare function sleep(seconds: number): Promise; /** * Execute `fn` inline and checkpoint the result. On replay the cached value is * returned without re-executing `fn`. * * `fn`'s result is encoded as JSON and decoded back before it is returned, so * the round that runs the body sees the same types every replay sees: a `Date` * comes back as a string, a `Map` as `{}`. {@link Jsonified} is that shape. */ export declare function step(name: string, fn: () => T | Promise): Promise>>; /** * Wrap an async function as a workflow task. * * @example * const extract_data = task(async (url: string) => { ... }); * const run_external = task("f/external_script", async (x: number) => { ... }); * const call_api = task(fetchOrders, { retry: { attempts: 3, delay: 30, multiplier: 2 } }); * * Inside a `workflow()`, calling a task dispatches it as a step. * Outside a workflow, the function body executes directly and * {@link TaskOptions} — retry included — does not apply. * * A task runs as its own job, so its result is always encoded as JSON and * decoded back before the caller sees it: a `Date` comes back as a string, a * `Map` as `{}`. {@link JsonifiedFn} is that shape. */ export declare function task Promise>(fnOrPath: T | string, maybeFnOrOptions?: T | TaskOptions, maybeOptions?: TaskOptions): JsonifiedFn; /** * Create a task that dispatches to a separate Windmill script. * * @example * const extract = taskScript("f/data/extract"); * // inside workflow: await extract({ url: "https://..." }) */ export declare function taskScript(path: string, options?: TaskOptions): (...args: any[]) => PromiseLike; /** * Create a task that dispatches to a separate Windmill flow. * * @example * const pipeline = taskFlow("f/etl/pipeline"); * // inside workflow: await pipeline({ input: data }) */ export declare function taskFlow(path: string, options?: TaskOptions): (...args: any[]) => PromiseLike; /** * Mark an async function as a workflow-as-code entry point. * * The function must be **deterministic**: given the same inputs it must call * tasks in the same order on every replay. Branching on task results is fine * (results are replayed from checkpoint), but branching on external state * (current time, random values, external API calls) must use `step()` to * checkpoint the value so replays see the same result. */ export declare function workflow(fn: (...args: any[]) => Promise): (...args: any[]) => Promise; /** * Suspend the workflow and wait for an external approval. * * Pass `key` to name the step, then `getApprovalUrls(key)` yields the URLs that * resume exactly this approval — route them through your own channel. Without a * key the steps are named `approval`, `approval_2`, ... * * `skin: "minimal"` shows approvers only the request (form and approve/reject) * instead of the detailed page with the workflow's details. `description` is * shown above the form: a string, or a rich value such as `{ markdown: "..." }`. * * @example * const urls = await step("urls", () => getApprovalUrls("manager")); * await step("notify", () => sendEmail(urls.resume, urls.cancel)); * const { value, approver } = await waitForApproval({ key: "manager", timeout: 3600 }); */ export declare function waitForApproval(options?: { timeout?: number; form?: object; selfApproval?: boolean; key?: string; skin?: "detailed" | "minimal"; description?: string | object; }): PromiseLike<{ value: any; approver: string; approved: boolean; }>; /** * Resume/cancel/approval-page URLs bound to one `waitForApproval` step. * * Unlike `getResumeUrls()`, which signs a random nonce, these address the very * `resume_job` record the step's built-in approval buttons use, so they are * stable across replays and safe to embed in a custom notification. * * `stepKey` must match the `key` given to `waitForApproval`. Keys must be unique * within a workflow; reusing one throws rather than silently renaming it. The URL * only resumes while that step is awaiting approval; used at any other moment it is * rejected rather than banking a row a different approval would consume. Send it * ahead of time — approvers just cannot act before the workflow reaches the step. * * `resume` and `cancel` are step-bound; `approvalPage` is not — it opens the job's * approval page, which acts on whichever approval is pending when it is used. * * @example * const urls = await step("urls", () => getApprovalUrls("manager")); * await step("notify", () => sendEmail(urls.resume, urls.cancel)); * await waitForApproval({ key: "manager" }); */ export declare function getApprovalUrls(stepKey?: string, approver?: string): Promise<{ approvalPage: string; resume: string; cancel: string; }>; /** * Process items in parallel with optional concurrency control. * * Each item is processed by calling `fn(item)`, which should be a task(). * Items are dispatched in batches of `concurrency` (default: all at once). * * @example * const process = task(async (item: string) => { ... }); * const results = await parallel(items, process, { concurrency: 5 }); */ export declare function parallel(items: T[], fn: (item: T) => PromiseLike | R, options?: { concurrency?: number; }): Promise; /** * Commit Kafka offsets for a trigger with auto_commit disabled. * @param triggerPath - Path to the Kafka trigger (from event.wm_trigger.trigger_path) * @param topic - Kafka topic name (from event.topic) * @param partition - Partition number (from event.partition) * @param offset - Message offset to commit (from event.offset) */ export declare function commitKafkaOffsets(triggerPath: string, topic: string, partition: number, offset: number): Promise;