windmill-cli 1.770.0 → 1.771.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/main.js +302 -51
- package/package.json +1 -1
package/esm/main.js
CHANGED
|
@@ -16784,7 +16784,7 @@ var init_OpenAPI = __esm(() => {
|
|
|
16784
16784
|
PASSWORD: undefined,
|
|
16785
16785
|
TOKEN: getEnv3("WM_TOKEN"),
|
|
16786
16786
|
USERNAME: undefined,
|
|
16787
|
-
VERSION: "1.
|
|
16787
|
+
VERSION: "1.771.0",
|
|
16788
16788
|
WITH_CREDENTIALS: true,
|
|
16789
16789
|
interceptors: {
|
|
16790
16790
|
request: new Interceptors,
|
|
@@ -17103,6 +17103,7 @@ __export(exports_services_gen, {
|
|
|
17103
17103
|
updateApp: () => updateApp,
|
|
17104
17104
|
updateAmqpTrigger: () => updateAmqpTrigger,
|
|
17105
17105
|
unstar: () => unstar,
|
|
17106
|
+
unresolveCompletedJobs: () => unresolveCompletedJobs,
|
|
17106
17107
|
unassignGhesInstallation: () => unassignGhesInstallation,
|
|
17107
17108
|
unarchiveWorkspace: () => unarchiveWorkspace,
|
|
17108
17109
|
toggleWorkspaceErrorHandlerForScript: () => toggleWorkspaceErrorHandlerForScript,
|
|
@@ -17209,6 +17210,7 @@ __export(exports_services_gen, {
|
|
|
17209
17210
|
restartWorkerGroup: () => restartWorkerGroup,
|
|
17210
17211
|
restartFlowAtStep: () => restartFlowAtStep,
|
|
17211
17212
|
resolveNpmPackageVersion: () => resolveNpmPackageVersion,
|
|
17213
|
+
resolveCompletedJobs: () => resolveCompletedJobs,
|
|
17212
17214
|
resetPassword: () => resetPassword,
|
|
17213
17215
|
resetKafkaOffsets: () => resetKafkaOffsets,
|
|
17214
17216
|
resetDiffTally: () => resetDiffTally,
|
|
@@ -17234,6 +17236,7 @@ __export(exports_services_gen, {
|
|
|
17234
17236
|
publishHubScript: () => publishHubScript,
|
|
17235
17237
|
publishHubResources: () => publishHubResources,
|
|
17236
17238
|
publishHubResourceType: () => publishHubResourceType,
|
|
17239
|
+
publishHubRawAppRecording: () => publishHubRawAppRecording,
|
|
17237
17240
|
publishHubRawAppEmbed: () => publishHubRawAppEmbed,
|
|
17238
17241
|
publishHubRawApp: () => publishHubRawApp,
|
|
17239
17242
|
publishHubProjectLogo: () => publishHubProjectLogo,
|
|
@@ -17310,6 +17313,7 @@ __export(exports_services_gen, {
|
|
|
17310
17313
|
listScriptPaths: () => listScriptPaths,
|
|
17311
17314
|
listSchedulesWithJobs: () => listSchedulesWithJobs,
|
|
17312
17315
|
listSchedules: () => listSchedules,
|
|
17316
|
+
listRunnables: () => listRunnables,
|
|
17313
17317
|
listResourceTypeNames: () => listResourceTypeNames,
|
|
17314
17318
|
listResourceType: () => listResourceType,
|
|
17315
17319
|
listResourceNames: () => listResourceNames,
|
|
@@ -17438,6 +17442,7 @@ __export(exports_services_gen, {
|
|
|
17438
17442
|
getWorkspaceDefaultApp: () => getWorkspaceDefaultApp,
|
|
17439
17443
|
getWorkspaceAsSuperAdmin: () => getWorkspaceAsSuperAdmin,
|
|
17440
17444
|
getWebsocketTrigger: () => getWebsocketTrigger,
|
|
17445
|
+
getWacApprovalUrls: () => getWacApprovalUrls,
|
|
17441
17446
|
getVolumeStorage: () => getVolumeStorage,
|
|
17442
17447
|
getVariableValue: () => getVariableValue,
|
|
17443
17448
|
getVariable: () => getVariable,
|
|
@@ -21329,6 +21334,26 @@ var backendVersion = () => {
|
|
|
21329
21334
|
workspace: data3.workspace
|
|
21330
21335
|
}
|
|
21331
21336
|
});
|
|
21337
|
+
}, listRunnables = (data3) => {
|
|
21338
|
+
return request(OpenAPI, {
|
|
21339
|
+
method: "GET",
|
|
21340
|
+
url: "/w/{workspace}/runnables/list",
|
|
21341
|
+
path: {
|
|
21342
|
+
workspace: data3.workspace
|
|
21343
|
+
},
|
|
21344
|
+
query: {
|
|
21345
|
+
order_by: data3.orderBy,
|
|
21346
|
+
order_desc: data3.orderDesc,
|
|
21347
|
+
kinds: data3.kinds,
|
|
21348
|
+
show_archived: data3.showArchived,
|
|
21349
|
+
include_without_main: data3.includeWithoutMain,
|
|
21350
|
+
path_start: data3.pathStart,
|
|
21351
|
+
label: data3.label,
|
|
21352
|
+
search: data3.search,
|
|
21353
|
+
per_page: data3.perPage,
|
|
21354
|
+
cursor: data3.cursor
|
|
21355
|
+
}
|
|
21356
|
+
});
|
|
21332
21357
|
}, listFlows = (data3) => {
|
|
21333
21358
|
return request(OpenAPI, {
|
|
21334
21359
|
method: "GET",
|
|
@@ -22375,6 +22400,7 @@ var backendVersion = () => {
|
|
|
22375
22400
|
page: data3.page,
|
|
22376
22401
|
per_page: data3.perPage,
|
|
22377
22402
|
is_skipped: data3.isSkipped,
|
|
22403
|
+
resolved: data3.resolved,
|
|
22378
22404
|
is_flow_step: data3.isFlowStep,
|
|
22379
22405
|
has_null_parent: data3.hasNullParent,
|
|
22380
22406
|
success: data3.success,
|
|
@@ -22492,6 +22518,7 @@ var backendVersion = () => {
|
|
|
22492
22518
|
page: data3.page,
|
|
22493
22519
|
per_page: data3.perPage,
|
|
22494
22520
|
is_skipped: data3.isSkipped,
|
|
22521
|
+
resolved: data3.resolved,
|
|
22495
22522
|
is_flow_step: data3.isFlowStep,
|
|
22496
22523
|
has_null_parent: data3.hasNullParent,
|
|
22497
22524
|
is_not_schedule: data3.isNotSchedule
|
|
@@ -22586,6 +22613,7 @@ var backendVersion = () => {
|
|
|
22586
22613
|
per_page: data3.perPage,
|
|
22587
22614
|
trigger_kind: data3.triggerKind,
|
|
22588
22615
|
is_skipped: data3.isSkipped,
|
|
22616
|
+
resolved: data3.resolved,
|
|
22589
22617
|
is_flow_step: data3.isFlowStep,
|
|
22590
22618
|
has_null_parent: data3.hasNullParent,
|
|
22591
22619
|
success: data3.success,
|
|
@@ -22818,6 +22846,26 @@ var backendVersion = () => {
|
|
|
22818
22846
|
id: data3.id
|
|
22819
22847
|
}
|
|
22820
22848
|
});
|
|
22849
|
+
}, resolveCompletedJobs = (data3) => {
|
|
22850
|
+
return request(OpenAPI, {
|
|
22851
|
+
method: "POST",
|
|
22852
|
+
url: "/w/{workspace}/jobs/completed/resolve",
|
|
22853
|
+
path: {
|
|
22854
|
+
workspace: data3.workspace
|
|
22855
|
+
},
|
|
22856
|
+
body: data3.requestBody,
|
|
22857
|
+
mediaType: "application/json"
|
|
22858
|
+
});
|
|
22859
|
+
}, unresolveCompletedJobs = (data3) => {
|
|
22860
|
+
return request(OpenAPI, {
|
|
22861
|
+
method: "POST",
|
|
22862
|
+
url: "/w/{workspace}/jobs/completed/unresolve",
|
|
22863
|
+
path: {
|
|
22864
|
+
workspace: data3.workspace
|
|
22865
|
+
},
|
|
22866
|
+
body: data3.requestBody,
|
|
22867
|
+
mediaType: "application/json"
|
|
22868
|
+
});
|
|
22821
22869
|
}, cancelQueuedJob = (data3) => {
|
|
22822
22870
|
return request(OpenAPI, {
|
|
22823
22871
|
method: "POST",
|
|
@@ -22896,6 +22944,19 @@ var backendVersion = () => {
|
|
|
22896
22944
|
flow_level: data3.flowLevel
|
|
22897
22945
|
}
|
|
22898
22946
|
});
|
|
22947
|
+
}, getWacApprovalUrls = (data3) => {
|
|
22948
|
+
return request(OpenAPI, {
|
|
22949
|
+
method: "GET",
|
|
22950
|
+
url: "/w/{workspace}/jobs/wac_approval_urls/{id}/{step_key}",
|
|
22951
|
+
path: {
|
|
22952
|
+
workspace: data3.workspace,
|
|
22953
|
+
id: data3.id,
|
|
22954
|
+
step_key: data3.stepKey
|
|
22955
|
+
},
|
|
22956
|
+
query: {
|
|
22957
|
+
approver: data3.approver
|
|
22958
|
+
}
|
|
22959
|
+
});
|
|
22899
22960
|
}, getSlackApprovalPayload = (data3) => {
|
|
22900
22961
|
return request(OpenAPI, {
|
|
22901
22962
|
method: "GET",
|
|
@@ -24819,6 +24880,8 @@ var backendVersion = () => {
|
|
|
24819
24880
|
workspace: data3.workspace
|
|
24820
24881
|
},
|
|
24821
24882
|
query: {
|
|
24883
|
+
page: data3.page,
|
|
24884
|
+
per_page: data3.perPage,
|
|
24822
24885
|
only_member_of: data3.onlyMemberOf
|
|
24823
24886
|
}
|
|
24824
24887
|
});
|
|
@@ -25687,6 +25750,7 @@ var backendVersion = () => {
|
|
|
25687
25750
|
per_page: data3.perPage,
|
|
25688
25751
|
trigger_kind: data3.triggerKind,
|
|
25689
25752
|
is_skipped: data3.isSkipped,
|
|
25753
|
+
resolved: data3.resolved,
|
|
25690
25754
|
is_flow_step: data3.isFlowStep,
|
|
25691
25755
|
has_null_parent: data3.hasNullParent,
|
|
25692
25756
|
success: data3.success,
|
|
@@ -26003,6 +26067,20 @@ var backendVersion = () => {
|
|
|
26003
26067
|
body: data3.requestBody,
|
|
26004
26068
|
mediaType: "application/json"
|
|
26005
26069
|
});
|
|
26070
|
+
}, publishHubRawAppRecording = (data3) => {
|
|
26071
|
+
return request(OpenAPI, {
|
|
26072
|
+
method: "POST",
|
|
26073
|
+
url: "/w/{workspace}/hub/raw_apps/{id}/recording",
|
|
26074
|
+
path: {
|
|
26075
|
+
workspace: data3.workspace,
|
|
26076
|
+
id: data3.id
|
|
26077
|
+
},
|
|
26078
|
+
query: {
|
|
26079
|
+
folder: data3.folder
|
|
26080
|
+
},
|
|
26081
|
+
body: data3.requestBody,
|
|
26082
|
+
mediaType: "application/json"
|
|
26083
|
+
});
|
|
26006
26084
|
}, publishHubScriptRecording = (data3) => {
|
|
26007
26085
|
return request(OpenAPI, {
|
|
26008
26086
|
method: "POST",
|
|
@@ -26202,6 +26280,7 @@ __export(exports_gen, {
|
|
|
26202
26280
|
updateApp: () => updateApp,
|
|
26203
26281
|
updateAmqpTrigger: () => updateAmqpTrigger,
|
|
26204
26282
|
unstar: () => unstar,
|
|
26283
|
+
unresolveCompletedJobs: () => unresolveCompletedJobs,
|
|
26205
26284
|
unassignGhesInstallation: () => unassignGhesInstallation,
|
|
26206
26285
|
unarchiveWorkspace: () => unarchiveWorkspace,
|
|
26207
26286
|
toggleWorkspaceErrorHandlerForScript: () => toggleWorkspaceErrorHandlerForScript,
|
|
@@ -26308,6 +26387,7 @@ __export(exports_gen, {
|
|
|
26308
26387
|
restartWorkerGroup: () => restartWorkerGroup,
|
|
26309
26388
|
restartFlowAtStep: () => restartFlowAtStep,
|
|
26310
26389
|
resolveNpmPackageVersion: () => resolveNpmPackageVersion,
|
|
26390
|
+
resolveCompletedJobs: () => resolveCompletedJobs,
|
|
26311
26391
|
resetPassword: () => resetPassword,
|
|
26312
26392
|
resetKafkaOffsets: () => resetKafkaOffsets,
|
|
26313
26393
|
resetDiffTally: () => resetDiffTally,
|
|
@@ -26333,6 +26413,7 @@ __export(exports_gen, {
|
|
|
26333
26413
|
publishHubScript: () => publishHubScript,
|
|
26334
26414
|
publishHubResources: () => publishHubResources,
|
|
26335
26415
|
publishHubResourceType: () => publishHubResourceType,
|
|
26416
|
+
publishHubRawAppRecording: () => publishHubRawAppRecording,
|
|
26336
26417
|
publishHubRawAppEmbed: () => publishHubRawAppEmbed,
|
|
26337
26418
|
publishHubRawApp: () => publishHubRawApp,
|
|
26338
26419
|
publishHubProjectLogo: () => publishHubProjectLogo,
|
|
@@ -26409,6 +26490,7 @@ __export(exports_gen, {
|
|
|
26409
26490
|
listScriptPaths: () => listScriptPaths,
|
|
26410
26491
|
listSchedulesWithJobs: () => listSchedulesWithJobs,
|
|
26411
26492
|
listSchedules: () => listSchedules,
|
|
26493
|
+
listRunnables: () => listRunnables,
|
|
26412
26494
|
listResourceTypeNames: () => listResourceTypeNames,
|
|
26413
26495
|
listResourceType: () => listResourceType,
|
|
26414
26496
|
listResourceNames: () => listResourceNames,
|
|
@@ -26537,6 +26619,7 @@ __export(exports_gen, {
|
|
|
26537
26619
|
getWorkspaceDefaultApp: () => getWorkspaceDefaultApp,
|
|
26538
26620
|
getWorkspaceAsSuperAdmin: () => getWorkspaceAsSuperAdmin,
|
|
26539
26621
|
getWebsocketTrigger: () => getWebsocketTrigger,
|
|
26622
|
+
getWacApprovalUrls: () => getWacApprovalUrls,
|
|
26540
26623
|
getVolumeStorage: () => getVolumeStorage,
|
|
26541
26624
|
getVariableValue: () => getVariableValue,
|
|
26542
26625
|
getVariable: () => getVariable,
|
|
@@ -27066,7 +27149,7 @@ var init_auth = __esm(async () => {
|
|
|
27066
27149
|
});
|
|
27067
27150
|
|
|
27068
27151
|
// src/core/constants.ts
|
|
27069
|
-
var WM_FORK_PREFIX = "wm-fork", VERSION = "1.
|
|
27152
|
+
var WM_FORK_PREFIX = "wm-fork", VERSION = "1.771.0";
|
|
27070
27153
|
|
|
27071
27154
|
// src/utils/git.ts
|
|
27072
27155
|
var exports_git = {};
|
|
@@ -82088,15 +82171,43 @@ workflow<T>(fn: (...args: any[]) => Promise<T>): void
|
|
|
82088
82171
|
/**
|
|
82089
82172
|
* Suspend the workflow and wait for an external approval.
|
|
82090
82173
|
*
|
|
82091
|
-
*
|
|
82092
|
-
*
|
|
82174
|
+
* Pass \`key\` to name the step, then \`getApprovalUrls(key)\` yields the URLs that
|
|
82175
|
+
* resume exactly this approval — route them through your own channel. Without a
|
|
82176
|
+
* key the steps are named \`approval\`, \`approval_2\`, ...
|
|
82177
|
+
*
|
|
82178
|
+
* @example
|
|
82179
|
+
* const urls = await step("urls", () => getApprovalUrls("manager"));
|
|
82180
|
+
* await step("notify", () => sendEmail(urls.resume, urls.cancel));
|
|
82181
|
+
* const { value, approver } = await waitForApproval({ key: "manager", timeout: 3600 });
|
|
82182
|
+
*/
|
|
82183
|
+
waitForApproval(options?: { timeout?: number; form?: object; selfApproval?: boolean; key?: string; }): PromiseLike<{ value: any; approver: string; approved: boolean }>
|
|
82184
|
+
|
|
82185
|
+
/**
|
|
82186
|
+
* Resume/cancel/approval-page URLs bound to one \`waitForApproval\` step.
|
|
82187
|
+
*
|
|
82188
|
+
* Unlike \`getResumeUrls()\`, which signs a random nonce, these address the very
|
|
82189
|
+
* \`resume_job\` record the step's built-in approval buttons use, so they are
|
|
82190
|
+
* stable across replays and safe to embed in a custom notification.
|
|
82191
|
+
*
|
|
82192
|
+
* \`stepKey\` must match the \`key\` given to \`waitForApproval\`. Keys must be unique
|
|
82193
|
+
* within a workflow; reusing one throws rather than silently renaming it. The URL
|
|
82194
|
+
* only resumes while that step is awaiting approval; used at any other moment it is
|
|
82195
|
+
* rejected rather than banking a row a different approval would consume. Send it
|
|
82196
|
+
* ahead of time — approvers just cannot act before the workflow reaches the step.
|
|
82197
|
+
*
|
|
82198
|
+
* \`resume\` and \`cancel\` are step-bound; \`approvalPage\` is not — it opens the job's
|
|
82199
|
+
* approval page, which acts on whichever approval is pending when it is used.
|
|
82093
82200
|
*
|
|
82094
82201
|
* @example
|
|
82095
|
-
* const urls = await step("urls", () =>
|
|
82096
|
-
* await step("notify", () => sendEmail(urls.
|
|
82097
|
-
*
|
|
82202
|
+
* const urls = await step("urls", () => getApprovalUrls("manager"));
|
|
82203
|
+
* await step("notify", () => sendEmail(urls.resume, urls.cancel));
|
|
82204
|
+
* await waitForApproval({ key: "manager" });
|
|
82098
82205
|
*/
|
|
82099
|
-
|
|
82206
|
+
async getApprovalUrls(stepKey: string = "approval", approver?: string): Promise<{
|
|
82207
|
+
approvalPage: string;
|
|
82208
|
+
resume: string;
|
|
82209
|
+
cancel: string;
|
|
82210
|
+
}>
|
|
82100
82211
|
|
|
82101
82212
|
/**
|
|
82102
82213
|
* Process items in parallel with optional concurrency control.
|
|
@@ -82852,15 +82963,43 @@ workflow<T>(fn: (...args: any[]) => Promise<T>): void
|
|
|
82852
82963
|
/**
|
|
82853
82964
|
* Suspend the workflow and wait for an external approval.
|
|
82854
82965
|
*
|
|
82855
|
-
*
|
|
82856
|
-
*
|
|
82966
|
+
* Pass \`key\` to name the step, then \`getApprovalUrls(key)\` yields the URLs that
|
|
82967
|
+
* resume exactly this approval — route them through your own channel. Without a
|
|
82968
|
+
* key the steps are named \`approval\`, \`approval_2\`, ...
|
|
82857
82969
|
*
|
|
82858
82970
|
* @example
|
|
82859
|
-
* const urls = await step("urls", () =>
|
|
82860
|
-
* await step("notify", () => sendEmail(urls.
|
|
82861
|
-
* const { value, approver } = await waitForApproval({ timeout: 3600 });
|
|
82971
|
+
* const urls = await step("urls", () => getApprovalUrls("manager"));
|
|
82972
|
+
* await step("notify", () => sendEmail(urls.resume, urls.cancel));
|
|
82973
|
+
* const { value, approver } = await waitForApproval({ key: "manager", timeout: 3600 });
|
|
82862
82974
|
*/
|
|
82863
|
-
waitForApproval(options?: { timeout?: number; form?: object; selfApproval?: boolean; }): PromiseLike<{ value: any; approver: string; approved: boolean }>
|
|
82975
|
+
waitForApproval(options?: { timeout?: number; form?: object; selfApproval?: boolean; key?: string; }): PromiseLike<{ value: any; approver: string; approved: boolean }>
|
|
82976
|
+
|
|
82977
|
+
/**
|
|
82978
|
+
* Resume/cancel/approval-page URLs bound to one \`waitForApproval\` step.
|
|
82979
|
+
*
|
|
82980
|
+
* Unlike \`getResumeUrls()\`, which signs a random nonce, these address the very
|
|
82981
|
+
* \`resume_job\` record the step's built-in approval buttons use, so they are
|
|
82982
|
+
* stable across replays and safe to embed in a custom notification.
|
|
82983
|
+
*
|
|
82984
|
+
* \`stepKey\` must match the \`key\` given to \`waitForApproval\`. Keys must be unique
|
|
82985
|
+
* within a workflow; reusing one throws rather than silently renaming it. The URL
|
|
82986
|
+
* only resumes while that step is awaiting approval; used at any other moment it is
|
|
82987
|
+
* rejected rather than banking a row a different approval would consume. Send it
|
|
82988
|
+
* ahead of time — approvers just cannot act before the workflow reaches the step.
|
|
82989
|
+
*
|
|
82990
|
+
* \`resume\` and \`cancel\` are step-bound; \`approvalPage\` is not — it opens the job's
|
|
82991
|
+
* approval page, which acts on whichever approval is pending when it is used.
|
|
82992
|
+
*
|
|
82993
|
+
* @example
|
|
82994
|
+
* const urls = await step("urls", () => getApprovalUrls("manager"));
|
|
82995
|
+
* await step("notify", () => sendEmail(urls.resume, urls.cancel));
|
|
82996
|
+
* await waitForApproval({ key: "manager" });
|
|
82997
|
+
*/
|
|
82998
|
+
async getApprovalUrls(stepKey: string = "approval", approver?: string): Promise<{
|
|
82999
|
+
approvalPage: string;
|
|
83000
|
+
resume: string;
|
|
83001
|
+
cancel: string;
|
|
83002
|
+
}>
|
|
82864
83003
|
|
|
82865
83004
|
/**
|
|
82866
83005
|
* Process items in parallel with optional concurrency control.
|
|
@@ -83710,15 +83849,43 @@ workflow<T>(fn: (...args: any[]) => Promise<T>): void
|
|
|
83710
83849
|
/**
|
|
83711
83850
|
* Suspend the workflow and wait for an external approval.
|
|
83712
83851
|
*
|
|
83713
|
-
*
|
|
83714
|
-
*
|
|
83852
|
+
* Pass \`key\` to name the step, then \`getApprovalUrls(key)\` yields the URLs that
|
|
83853
|
+
* resume exactly this approval — route them through your own channel. Without a
|
|
83854
|
+
* key the steps are named \`approval\`, \`approval_2\`, ...
|
|
83715
83855
|
*
|
|
83716
83856
|
* @example
|
|
83717
|
-
* const urls = await step("urls", () =>
|
|
83718
|
-
* await step("notify", () => sendEmail(urls.
|
|
83719
|
-
* const { value, approver } = await waitForApproval({ timeout: 3600 });
|
|
83857
|
+
* const urls = await step("urls", () => getApprovalUrls("manager"));
|
|
83858
|
+
* await step("notify", () => sendEmail(urls.resume, urls.cancel));
|
|
83859
|
+
* const { value, approver } = await waitForApproval({ key: "manager", timeout: 3600 });
|
|
83720
83860
|
*/
|
|
83721
|
-
waitForApproval(options?: { timeout?: number; form?: object; selfApproval?: boolean; }): PromiseLike<{ value: any; approver: string; approved: boolean }>
|
|
83861
|
+
waitForApproval(options?: { timeout?: number; form?: object; selfApproval?: boolean; key?: string; }): PromiseLike<{ value: any; approver: string; approved: boolean }>
|
|
83862
|
+
|
|
83863
|
+
/**
|
|
83864
|
+
* Resume/cancel/approval-page URLs bound to one \`waitForApproval\` step.
|
|
83865
|
+
*
|
|
83866
|
+
* Unlike \`getResumeUrls()\`, which signs a random nonce, these address the very
|
|
83867
|
+
* \`resume_job\` record the step's built-in approval buttons use, so they are
|
|
83868
|
+
* stable across replays and safe to embed in a custom notification.
|
|
83869
|
+
*
|
|
83870
|
+
* \`stepKey\` must match the \`key\` given to \`waitForApproval\`. Keys must be unique
|
|
83871
|
+
* within a workflow; reusing one throws rather than silently renaming it. The URL
|
|
83872
|
+
* only resumes while that step is awaiting approval; used at any other moment it is
|
|
83873
|
+
* rejected rather than banking a row a different approval would consume. Send it
|
|
83874
|
+
* ahead of time — approvers just cannot act before the workflow reaches the step.
|
|
83875
|
+
*
|
|
83876
|
+
* \`resume\` and \`cancel\` are step-bound; \`approvalPage\` is not — it opens the job's
|
|
83877
|
+
* approval page, which acts on whichever approval is pending when it is used.
|
|
83878
|
+
*
|
|
83879
|
+
* @example
|
|
83880
|
+
* const urls = await step("urls", () => getApprovalUrls("manager"));
|
|
83881
|
+
* await step("notify", () => sendEmail(urls.resume, urls.cancel));
|
|
83882
|
+
* await waitForApproval({ key: "manager" });
|
|
83883
|
+
*/
|
|
83884
|
+
async getApprovalUrls(stepKey: string = "approval", approver?: string): Promise<{
|
|
83885
|
+
approvalPage: string;
|
|
83886
|
+
resume: string;
|
|
83887
|
+
cancel: string;
|
|
83888
|
+
}>
|
|
83722
83889
|
|
|
83723
83890
|
/**
|
|
83724
83891
|
* Process items in parallel with optional concurrency control.
|
|
@@ -85304,6 +85471,17 @@ def get_shared_state(path: str = 'state.json') -> None
|
|
|
85304
85471
|
# Dictionary with approvalPage, resume, and cancel URLs
|
|
85305
85472
|
def get_resume_urls(approver: str = None, flow_level: bool = None) -> dict
|
|
85306
85473
|
|
|
85474
|
+
# Get the resume URLs bound to one \`\`wait_for_approval\`\` step of this workflow.
|
|
85475
|
+
#
|
|
85476
|
+
# Args:
|
|
85477
|
+
# step_key: Checkpoint key of the approval step, as passed to
|
|
85478
|
+
# \`\`wait_for_approval(key=...)\`\`
|
|
85479
|
+
# approver: Optional approver name
|
|
85480
|
+
#
|
|
85481
|
+
# Returns:
|
|
85482
|
+
# Dictionary with approvalPage, resume, and cancel URLs
|
|
85483
|
+
def get_approval_urls(step_key: str = 'approval', approver: str = None) -> dict
|
|
85484
|
+
|
|
85307
85485
|
# Sends an interactive approval request via Slack, allowing optional customization of the message, approver, and form fields.
|
|
85308
85486
|
#
|
|
85309
85487
|
# **[Enterprise Edition Only]** To include form fields in the Slack approval request, use the "Advanced -> Suspend -> Form" functionality.
|
|
@@ -85580,8 +85758,9 @@ async def sleep(seconds: int)
|
|
|
85580
85758
|
|
|
85581
85759
|
# Suspend the workflow and wait for an external approval.
|
|
85582
85760
|
#
|
|
85583
|
-
#
|
|
85584
|
-
# resume
|
|
85761
|
+
# Pass \`\`key\`\` to name the step, then \`\`get_approval_urls(key)\`\` yields the URLs
|
|
85762
|
+
# that resume exactly this approval — route them through your own channel.
|
|
85763
|
+
# Without a key the steps are named \`\`approval\`\`, \`\`approval_2\`\`, ...
|
|
85585
85764
|
#
|
|
85586
85765
|
# Returns a dict with \`\`value\`\` (form data), \`\`approver\`\`, and \`\`approved\`\`.
|
|
85587
85766
|
#
|
|
@@ -85589,13 +85768,14 @@ async def sleep(seconds: int)
|
|
|
85589
85768
|
# timeout: Approval timeout in seconds (default 1800).
|
|
85590
85769
|
# form: Optional form schema for the approval page.
|
|
85591
85770
|
# self_approval: Whether the user who triggered the flow can approve it (default True).
|
|
85771
|
+
# key: Optional checkpoint key naming this approval step.
|
|
85592
85772
|
#
|
|
85593
85773
|
# Example::
|
|
85594
85774
|
#
|
|
85595
|
-
# urls = await step("urls", lambda:
|
|
85596
|
-
# await step("notify", lambda: send_email(urls["
|
|
85597
|
-
# result = await wait_for_approval(timeout=3600)
|
|
85598
|
-
async def wait_for_approval(timeout: int = 1800, form: dict | None = None, self_approval: bool = True) -> dict
|
|
85775
|
+
# urls = await step("urls", lambda: get_approval_urls("manager"))
|
|
85776
|
+
# await step("notify", lambda: send_email(urls["resume"], urls["cancel"]))
|
|
85777
|
+
# result = await wait_for_approval(key="manager", timeout=3600)
|
|
85778
|
+
async def wait_for_approval(timeout: int = 1800, form: dict | None = None, self_approval: bool = True, key: str | None = None) -> dict
|
|
85599
85779
|
|
|
85600
85780
|
# Process items in parallel with optional concurrency control.
|
|
85601
85781
|
#
|
|
@@ -86672,6 +86852,18 @@ const user = await backend.get_user({ user_id: '123' });
|
|
|
86672
86852
|
|
|
86673
86853
|
The frontend cannot reach datatables, workspace items, or external services on its own — it goes through \`backend.<key>(args)\` for everything server-side.
|
|
86674
86854
|
|
|
86855
|
+
### Keeping data out of recorded demos
|
|
86856
|
+
|
|
86857
|
+
An app can be demoed by recording a session: every interaction becomes a step carrying a snapshot of the page, replayed publicly or on the Hub. Password inputs are masked automatically. Mark anything else that must not appear with \`data-wm-no-record\` — the whole marked subtree is dropped from every snapshot, along with its values and the step's own metadata:
|
|
86858
|
+
|
|
86859
|
+
\`\`\`tsx
|
|
86860
|
+
<label data-wm-no-record>
|
|
86861
|
+
Customer SSN <input value={ssn} onChange={onSsn} />
|
|
86862
|
+
</label>
|
|
86863
|
+
\`\`\`
|
|
86864
|
+
|
|
86865
|
+
Apply it to customer data, internal notes and anything else a viewer of the demo should not see. It costs nothing when the app is never recorded.
|
|
86866
|
+
|
|
86675
86867
|
## Backend runnables
|
|
86676
86868
|
|
|
86677
86869
|
Each runnable has a unique key (used to call it from the frontend) and one of four types:
|
|
@@ -86774,6 +86966,7 @@ def main(user_id: str):
|
|
|
86774
86966
|
3. **Keep runnables focused** — one function per runnable; small surface area.
|
|
86775
86967
|
4. **Use descriptive keys** — \`get_user\`, not \`a\`.
|
|
86776
86968
|
5. **Always whitelist tables** — adding a runnable that queries a new table requires the table to be in \`data.tables\` first.
|
|
86969
|
+
6. **Mark sensitive UI with \`data-wm-no-record\`** — it is what keeps that data out of a recorded demo; passwords are handled for you.
|
|
86777
86970
|
`,
|
|
86778
86971
|
triggers: `---
|
|
86779
86972
|
name: triggers
|
|
@@ -87227,7 +87420,7 @@ import {
|
|
|
87227
87420
|
step,
|
|
87228
87421
|
sleep,
|
|
87229
87422
|
waitForApproval,
|
|
87230
|
-
|
|
87423
|
+
getApprovalUrls,
|
|
87231
87424
|
parallel,
|
|
87232
87425
|
workflow,
|
|
87233
87426
|
} from "windmill-client";
|
|
@@ -87245,7 +87438,7 @@ export const main = workflow(async (x: string) => {
|
|
|
87245
87438
|
Python:
|
|
87246
87439
|
|
|
87247
87440
|
\`\`\`python
|
|
87248
|
-
from wmill import task, task_script, task_flow, step, sleep, wait_for_approval,
|
|
87441
|
+
from wmill import task, task_script, task_flow, step, sleep, wait_for_approval, get_approval_urls, parallel, workflow
|
|
87249
87442
|
|
|
87250
87443
|
@task()
|
|
87251
87444
|
async def process(x: str) -> str:
|
|
@@ -87329,12 +87522,13 @@ output = await pipeline(input=data)
|
|
|
87329
87522
|
Use \`step()\` for lightweight inline values that must not change during replay:
|
|
87330
87523
|
|
|
87331
87524
|
\`\`\`typescript
|
|
87332
|
-
const urls = await step("get_urls", () => getResumeUrls());
|
|
87333
87525
|
const startedAt = await step("started_at", () => new Date().toISOString());
|
|
87334
87526
|
\`\`\`
|
|
87335
87527
|
|
|
87336
87528
|
\`\`\`python
|
|
87337
|
-
|
|
87529
|
+
from datetime import datetime
|
|
87530
|
+
|
|
87531
|
+
started_at = await step("started_at", lambda: datetime.now().isoformat())
|
|
87338
87532
|
\`\`\`
|
|
87339
87533
|
|
|
87340
87534
|
Use stable, descriptive step names. Do not generate step names dynamically.
|
|
@@ -87359,20 +87553,28 @@ Only parallelize independent steps. Do not read the result of a task before it i
|
|
|
87359
87553
|
|
|
87360
87554
|
## Approvals
|
|
87361
87555
|
|
|
87362
|
-
|
|
87556
|
+
Name the approval step and generate its URLs inside \`step()\` before sending them.
|
|
87557
|
+
\`getApprovalUrls\` / \`get_approval_urls\` returns the URLs bound to that step, the same
|
|
87558
|
+
ones its built-in approve/reject buttons use:
|
|
87363
87559
|
|
|
87364
87560
|
\`\`\`typescript
|
|
87365
|
-
const urls = await step("
|
|
87366
|
-
await step("notify", () => sendApprovalEmail(urls.
|
|
87367
|
-
const approval = await waitForApproval({ timeout: 3600 });
|
|
87561
|
+
const urls = await step("urls", () => getApprovalUrls("manager"));
|
|
87562
|
+
await step("notify", () => sendApprovalEmail(urls.resume, urls.cancel));
|
|
87563
|
+
const approval = await waitForApproval({ key: "manager", timeout: 3600 });
|
|
87368
87564
|
\`\`\`
|
|
87369
87565
|
|
|
87370
87566
|
\`\`\`python
|
|
87371
|
-
urls = await step("
|
|
87372
|
-
await step("notify", lambda: send_approval_email(urls["
|
|
87373
|
-
approval = await wait_for_approval(timeout=3600)
|
|
87567
|
+
urls = await step("urls", lambda: get_approval_urls("manager"))
|
|
87568
|
+
await step("notify", lambda: send_approval_email(urls["resume"], urls["cancel"]))
|
|
87569
|
+
approval = await wait_for_approval(key="manager", timeout=3600)
|
|
87374
87570
|
\`\`\`
|
|
87375
87571
|
|
|
87572
|
+
With several approvals in one workflow, give each its own key so each notification
|
|
87573
|
+
resumes its own step. Keys must be unique — reusing one raises an error rather than
|
|
87574
|
+
silently renaming the step. A minted URL only resumes while its own step is awaiting
|
|
87575
|
+
approval; used at any other moment it is rejected rather than resuming the wrong one. \`getResumeUrls()\` / \`get_resume_urls()\` still works but signs a
|
|
87576
|
+
random nonce, so its URLs are not tied to any particular approval step.
|
|
87577
|
+
|
|
87376
87578
|
\`selfApproval: false\` and \`self_approval=False\` are Enterprise-only approval behavior. Do not use them unless the user asks for that behavior.
|
|
87377
87579
|
|
|
87378
87580
|
## Error Handling
|
|
@@ -87386,7 +87588,7 @@ TypeScript: avoid broad \`try/catch\` around WAC SDK calls. The SDK uses an inte
|
|
|
87386
87588
|
|
|
87387
87589
|
## TypeScript Workflow-as-Code API (windmill-client)
|
|
87388
87590
|
|
|
87389
|
-
Import: \`import { workflow, task, taskScript, taskFlow, step, sleep, waitForApproval, getResumeUrls, parallel } from "windmill-client"\`
|
|
87591
|
+
Import: \`import { workflow, task, taskScript, taskFlow, step, sleep, waitForApproval, getApprovalUrls, getResumeUrls, parallel } from "windmill-client"\`
|
|
87390
87592
|
|
|
87391
87593
|
\`\`\`typescript
|
|
87392
87594
|
export interface TaskOptions {
|
|
@@ -87456,15 +87658,39 @@ export async function sleep(seconds: number): Promise<void>
|
|
|
87456
87658
|
/**
|
|
87457
87659
|
* Suspend the workflow and wait for an external approval.
|
|
87458
87660
|
*
|
|
87459
|
-
*
|
|
87460
|
-
*
|
|
87661
|
+
* Pass \`key\` to name the step, then \`getApprovalUrls(key)\` yields the URLs that
|
|
87662
|
+
* resume exactly this approval — route them through your own channel. Without a
|
|
87663
|
+
* key the steps are named \`approval\`, \`approval_2\`, ...
|
|
87461
87664
|
*
|
|
87462
87665
|
* @example
|
|
87463
|
-
* const urls = await step("urls", () =>
|
|
87464
|
-
* await step("notify", () => sendEmail(urls.
|
|
87465
|
-
* const { value, approver } = await waitForApproval({ timeout: 3600 });
|
|
87666
|
+
* const urls = await step("urls", () => getApprovalUrls("manager"));
|
|
87667
|
+
* await step("notify", () => sendEmail(urls.resume, urls.cancel));
|
|
87668
|
+
* const { value, approver } = await waitForApproval({ key: "manager", timeout: 3600 });
|
|
87466
87669
|
*/
|
|
87467
|
-
export function waitForApproval(options?: { timeout?: number; form?: object; selfApproval?: boolean; }): PromiseLike<{ value: any; approver: string; approved: boolean }>
|
|
87670
|
+
export function waitForApproval(options?: { timeout?: number; form?: object; selfApproval?: boolean; key?: string; }): PromiseLike<{ value: any; approver: string; approved: boolean }>
|
|
87671
|
+
|
|
87672
|
+
/**
|
|
87673
|
+
* Resume/cancel/approval-page URLs bound to one \`waitForApproval\` step.
|
|
87674
|
+
*
|
|
87675
|
+
* Unlike \`getResumeUrls()\`, which signs a random nonce, these address the very
|
|
87676
|
+
* \`resume_job\` record the step's built-in approval buttons use, so they are
|
|
87677
|
+
* stable across replays and safe to embed in a custom notification.
|
|
87678
|
+
*
|
|
87679
|
+
* \`stepKey\` must match the \`key\` given to \`waitForApproval\`. Keys must be unique
|
|
87680
|
+
* within a workflow; reusing one throws rather than silently renaming it. The URL
|
|
87681
|
+
* only resumes while that step is awaiting approval; used at any other moment it is
|
|
87682
|
+
* rejected rather than banking a row a different approval would consume. Send it
|
|
87683
|
+
* ahead of time — approvers just cannot act before the workflow reaches the step.
|
|
87684
|
+
*
|
|
87685
|
+
* \`resume\` and \`cancel\` are step-bound; \`approvalPage\` is not — it opens the job's
|
|
87686
|
+
* approval page, which acts on whichever approval is pending when it is used.
|
|
87687
|
+
*
|
|
87688
|
+
* @example
|
|
87689
|
+
* const urls = await step("urls", () => getApprovalUrls("manager"));
|
|
87690
|
+
* await step("notify", () => sendEmail(urls.resume, urls.cancel));
|
|
87691
|
+
* await waitForApproval({ key: "manager" });
|
|
87692
|
+
*/
|
|
87693
|
+
export async function getApprovalUrls(stepKey: string = "approval", approver?: string): Promise<{ approvalPage: string; resume: string; cancel: string; }>
|
|
87468
87694
|
|
|
87469
87695
|
/**
|
|
87470
87696
|
* Process items in parallel with optional concurrency control.
|
|
@@ -87482,7 +87708,7 @@ export async function parallel<T, R>(items: T[], fn: (item: T) => PromiseLike<R>
|
|
|
87482
87708
|
|
|
87483
87709
|
## Python Workflow-as-Code API (wmill)
|
|
87484
87710
|
|
|
87485
|
-
Import: \`from wmill import workflow, task, task_script, task_flow, step, sleep, wait_for_approval, get_resume_urls, parallel, TaskError\`
|
|
87711
|
+
Import: \`from wmill import workflow, task, task_script, task_flow, step, sleep, wait_for_approval, get_approval_urls, get_resume_urls, parallel, TaskError\`
|
|
87486
87712
|
|
|
87487
87713
|
\`\`\`python
|
|
87488
87714
|
# Raised when a WAC task step failed.
|
|
@@ -87570,8 +87796,9 @@ async def sleep(seconds: int)
|
|
|
87570
87796
|
|
|
87571
87797
|
# Suspend the workflow and wait for an external approval.
|
|
87572
87798
|
#
|
|
87573
|
-
#
|
|
87574
|
-
# resume
|
|
87799
|
+
# Pass \`\`key\`\` to name the step, then \`\`get_approval_urls(key)\`\` yields the URLs
|
|
87800
|
+
# that resume exactly this approval — route them through your own channel.
|
|
87801
|
+
# Without a key the steps are named \`\`approval\`\`, \`\`approval_2\`\`, ...
|
|
87575
87802
|
#
|
|
87576
87803
|
# Returns a dict with \`\`value\`\` (form data), \`\`approver\`\`, and \`\`approved\`\`.
|
|
87577
87804
|
#
|
|
@@ -87579,13 +87806,37 @@ async def sleep(seconds: int)
|
|
|
87579
87806
|
# timeout: Approval timeout in seconds (default 1800).
|
|
87580
87807
|
# form: Optional form schema for the approval page.
|
|
87581
87808
|
# self_approval: Whether the user who triggered the flow can approve it (default True).
|
|
87809
|
+
# key: Optional checkpoint key naming this approval step.
|
|
87582
87810
|
#
|
|
87583
87811
|
# Example::
|
|
87584
87812
|
#
|
|
87585
|
-
# urls = await step("urls", lambda:
|
|
87586
|
-
# await step("notify", lambda: send_email(urls["
|
|
87587
|
-
# result = await wait_for_approval(timeout=3600)
|
|
87588
|
-
async def wait_for_approval(timeout: int = 1800, form: dict | None = None, self_approval: bool = True) -> dict
|
|
87813
|
+
# urls = await step("urls", lambda: get_approval_urls("manager"))
|
|
87814
|
+
# await step("notify", lambda: send_email(urls["resume"], urls["cancel"]))
|
|
87815
|
+
# result = await wait_for_approval(key="manager", timeout=3600)
|
|
87816
|
+
async def wait_for_approval(timeout: int = 1800, form: dict | None = None, self_approval: bool = True, key: str | None = None) -> dict
|
|
87817
|
+
|
|
87818
|
+
# Get the resume/cancel/approval-page URLs bound to one \`\`wait_for_approval\`\` step.
|
|
87819
|
+
#
|
|
87820
|
+
# Unlike :func:\`get_resume_urls\`, which signs a random nonce, these address the
|
|
87821
|
+
# very \`\`resume_job\`\` record the step's built-in approval buttons use, so they
|
|
87822
|
+
# are stable across replays and safe to embed in a custom notification.
|
|
87823
|
+
#
|
|
87824
|
+
# Args:
|
|
87825
|
+
# step_key: Checkpoint key of the approval step, as passed to
|
|
87826
|
+
# \`\`wait_for_approval(key=...)\`\`. Keys must be unique within a workflow;
|
|
87827
|
+
# reusing one raises rather than silently renaming it. The URL only
|
|
87828
|
+
# resumes while that step is awaiting approval; used at any other moment
|
|
87829
|
+
# it is rejected rather than banking a row a different approval would
|
|
87830
|
+
# consume. Send it ahead of time — approvers just cannot act before the
|
|
87831
|
+
# workflow reaches the step.
|
|
87832
|
+
# \`\`resume\`\` and \`\`cancel\`\` are step-bound; \`\`approvalPage\`\` is not — it
|
|
87833
|
+
# opens the job's approval page, which acts on whichever approval is
|
|
87834
|
+
# pending when it is used.
|
|
87835
|
+
# approver: Optional approver name
|
|
87836
|
+
#
|
|
87837
|
+
# Returns:
|
|
87838
|
+
# Dictionary with approvalPage, resume, and cancel URLs
|
|
87839
|
+
def get_approval_urls(step_key: str = 'approval', approver: str = None) -> dict
|
|
87589
87840
|
|
|
87590
87841
|
# Process items in parallel with optional concurrency control.
|
|
87591
87842
|
#
|