windmill-client 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/dist/client.d.ts +42 -6
- package/dist/client.mjs +66 -12
- package/dist/core/OpenAPI.mjs +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +208 -13
- package/dist/index.mjs +3 -2
- package/dist/services.gen.d.ts +74 -1
- package/dist/services.gen.mjs +140 -1
- package/dist/types.gen.d.ts +335 -0
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -448,7 +448,11 @@ export declare let _workflowCtx: WorkflowCtx | null;
|
|
|
448
448
|
export declare function setWorkflowCtx(ctx: WorkflowCtx | null): void;
|
|
449
449
|
export declare class WorkflowCtx {
|
|
450
450
|
private completed;
|
|
451
|
+
/** Null-prototype: step keys are caller-supplied, and a plain object would
|
|
452
|
+
* resolve `toString`/`constructor`/`__proto__` off `Object.prototype`. */
|
|
451
453
|
private counters;
|
|
454
|
+
/** Every key handed out by `_allocKey`, so distinct names can't alias one key. */
|
|
455
|
+
private _usedKeys;
|
|
452
456
|
private pending;
|
|
453
457
|
private _suspended;
|
|
454
458
|
/** When set, the task matching this key executes its inner function directly */
|
|
@@ -464,7 +468,10 @@ export declare class WorkflowCtx {
|
|
|
464
468
|
* `completed_steps[key]`. Initialized to a resolved promise. */
|
|
465
469
|
private _inlineChain;
|
|
466
470
|
constructor(checkpoint?: Record<string, any>);
|
|
467
|
-
/** Name-based key: `double` for first call, `double_2`, `double_3` for subsequent.
|
|
471
|
+
/** Name-based key: `double` for first call, `double_2`, `double_3` for subsequent.
|
|
472
|
+
* Suffixing alone can alias — a second `step("x")` and a first `step("x_2")` both
|
|
473
|
+
* want `x_2` — so keep bumping past keys already handed out. Allocation order is
|
|
474
|
+
* fixed by the workflow body, so replays reproduce the same keys. */
|
|
468
475
|
_allocKey(name: string): string;
|
|
469
476
|
_nextStep(name: string, script: string, args?: Record<string, any>, dispatch_type?: string, options?: TaskOptions): PromiseLike<any>;
|
|
470
477
|
/** Return and clear any pending (unawaited) steps. */
|
|
@@ -479,6 +486,7 @@ export declare class WorkflowCtx {
|
|
|
479
486
|
timeout?: number;
|
|
480
487
|
form?: object;
|
|
481
488
|
selfApproval?: boolean;
|
|
489
|
+
key?: string;
|
|
482
490
|
}): PromiseLike<{
|
|
483
491
|
value: any;
|
|
484
492
|
approver: string;
|
|
@@ -529,23 +537,51 @@ export declare function workflow<T>(fn: (...args: any[]) => Promise<T>): (...arg
|
|
|
529
537
|
/**
|
|
530
538
|
* Suspend the workflow and wait for an external approval.
|
|
531
539
|
*
|
|
532
|
-
*
|
|
533
|
-
*
|
|
540
|
+
* Pass `key` to name the step, then `getApprovalUrls(key)` yields the URLs that
|
|
541
|
+
* resume exactly this approval — route them through your own channel. Without a
|
|
542
|
+
* key the steps are named `approval`, `approval_2`, ...
|
|
534
543
|
*
|
|
535
544
|
* @example
|
|
536
|
-
* const urls = await step("urls", () =>
|
|
537
|
-
* await step("notify", () => sendEmail(urls.
|
|
538
|
-
* const { value, approver } = await waitForApproval({ timeout: 3600 });
|
|
545
|
+
* const urls = await step("urls", () => getApprovalUrls("manager"));
|
|
546
|
+
* await step("notify", () => sendEmail(urls.resume, urls.cancel));
|
|
547
|
+
* const { value, approver } = await waitForApproval({ key: "manager", timeout: 3600 });
|
|
539
548
|
*/
|
|
540
549
|
export declare function waitForApproval(options?: {
|
|
541
550
|
timeout?: number;
|
|
542
551
|
form?: object;
|
|
543
552
|
selfApproval?: boolean;
|
|
553
|
+
key?: string;
|
|
544
554
|
}): PromiseLike<{
|
|
545
555
|
value: any;
|
|
546
556
|
approver: string;
|
|
547
557
|
approved: boolean;
|
|
548
558
|
}>;
|
|
559
|
+
/**
|
|
560
|
+
* Resume/cancel/approval-page URLs bound to one `waitForApproval` step.
|
|
561
|
+
*
|
|
562
|
+
* Unlike `getResumeUrls()`, which signs a random nonce, these address the very
|
|
563
|
+
* `resume_job` record the step's built-in approval buttons use, so they are
|
|
564
|
+
* stable across replays and safe to embed in a custom notification.
|
|
565
|
+
*
|
|
566
|
+
* `stepKey` must match the `key` given to `waitForApproval`. Keys must be unique
|
|
567
|
+
* within a workflow; reusing one throws rather than silently renaming it. The URL
|
|
568
|
+
* only resumes while that step is awaiting approval; used at any other moment it is
|
|
569
|
+
* rejected rather than banking a row a different approval would consume. Send it
|
|
570
|
+
* ahead of time — approvers just cannot act before the workflow reaches the step.
|
|
571
|
+
*
|
|
572
|
+
* `resume` and `cancel` are step-bound; `approvalPage` is not — it opens the job's
|
|
573
|
+
* approval page, which acts on whichever approval is pending when it is used.
|
|
574
|
+
*
|
|
575
|
+
* @example
|
|
576
|
+
* const urls = await step("urls", () => getApprovalUrls("manager"));
|
|
577
|
+
* await step("notify", () => sendEmail(urls.resume, urls.cancel));
|
|
578
|
+
* await waitForApproval({ key: "manager" });
|
|
579
|
+
*/
|
|
580
|
+
export declare function getApprovalUrls(stepKey?: string, approver?: string): Promise<{
|
|
581
|
+
approvalPage: string;
|
|
582
|
+
resume: string;
|
|
583
|
+
cancel: string;
|
|
584
|
+
}>;
|
|
549
585
|
/**
|
|
550
586
|
* Process items in parallel with optional concurrency control.
|
|
551
587
|
*
|
package/dist/client.mjs
CHANGED
|
@@ -958,6 +958,13 @@ var StepSuspend = class extends Error {
|
|
|
958
958
|
this.name = "StepSuspend";
|
|
959
959
|
}
|
|
960
960
|
};
|
|
961
|
+
/** A step key travels as one path segment when its URLs are minted, so it must be
|
|
962
|
+
* non-empty and free of `/` and dot segments — otherwise `waitForApproval` would
|
|
963
|
+
* accept a key `getApprovalUrls` can never address. */
|
|
964
|
+
function assertUsableStepKey(key, what) {
|
|
965
|
+
const k = key.trim();
|
|
966
|
+
if (k === "" || k === "." || k === ".." || key.includes("/") || key.includes("\\")) throw new Error(`${what} must be a non-empty step name without \`/\` or dot segments`);
|
|
967
|
+
}
|
|
961
968
|
let _workflowCtx = null;
|
|
962
969
|
function setWorkflowCtx(ctx) {
|
|
963
970
|
_workflowCtx = ctx;
|
|
@@ -965,7 +972,11 @@ function setWorkflowCtx(ctx) {
|
|
|
965
972
|
}
|
|
966
973
|
var WorkflowCtx = class {
|
|
967
974
|
completed;
|
|
968
|
-
|
|
975
|
+
/** Null-prototype: step keys are caller-supplied, and a plain object would
|
|
976
|
+
* resolve `toString`/`constructor`/`__proto__` off `Object.prototype`. */
|
|
977
|
+
counters = Object.create(null);
|
|
978
|
+
/** Every key handed out by `_allocKey`, so distinct names can't alias one key. */
|
|
979
|
+
_usedKeys = new Set();
|
|
969
980
|
pending = [];
|
|
970
981
|
_suspended = false;
|
|
971
982
|
/** When set, the task matching this key executes its inner function directly */
|
|
@@ -981,14 +992,23 @@ var WorkflowCtx = class {
|
|
|
981
992
|
* `completed_steps[key]`. Initialized to a resolved promise. */
|
|
982
993
|
_inlineChain = Promise.resolve();
|
|
983
994
|
constructor(checkpoint = {}) {
|
|
984
|
-
this.completed = checkpoint?.completed_steps ?? {};
|
|
995
|
+
this.completed = Object.assign(Object.create(null), checkpoint?.completed_steps ?? {});
|
|
985
996
|
this._executingKey = checkpoint?._executing_key ?? null;
|
|
986
997
|
}
|
|
987
|
-
/** Name-based key: `double` for first call, `double_2`, `double_3` for subsequent.
|
|
998
|
+
/** Name-based key: `double` for first call, `double_2`, `double_3` for subsequent.
|
|
999
|
+
* Suffixing alone can alias — a second `step("x")` and a first `step("x_2")` both
|
|
1000
|
+
* want `x_2` — so keep bumping past keys already handed out. Allocation order is
|
|
1001
|
+
* fixed by the workflow body, so replays reproduce the same keys. */
|
|
988
1002
|
_allocKey(name) {
|
|
989
|
-
|
|
1003
|
+
let n = (this.counters[name] ?? 0) + 1;
|
|
1004
|
+
let key = n === 1 ? name : `${name}_${n}`;
|
|
1005
|
+
while (this._usedKeys.has(key)) {
|
|
1006
|
+
n++;
|
|
1007
|
+
key = `${name}_${n}`;
|
|
1008
|
+
}
|
|
990
1009
|
this.counters[name] = n;
|
|
991
|
-
|
|
1010
|
+
this._usedKeys.add(key);
|
|
1011
|
+
return key;
|
|
992
1012
|
}
|
|
993
1013
|
_nextStep(name, script, args = {}, dispatch_type = "inline", options) {
|
|
994
1014
|
const key = this._allocKey(name || script || "step");
|
|
@@ -1048,7 +1068,9 @@ var WorkflowCtx = class {
|
|
|
1048
1068
|
return steps;
|
|
1049
1069
|
}
|
|
1050
1070
|
_waitForApproval(options) {
|
|
1051
|
-
|
|
1071
|
+
if (options?.key !== void 0) assertUsableStepKey(options.key, "waitForApproval key");
|
|
1072
|
+
const key = this._allocKey(options?.key || "approval");
|
|
1073
|
+
if (options?.key && key !== options.key) throw new Error(`WAC step key "${options.key}" is already used in this workflow. Give each waitForApproval() its own key so getApprovalUrls() can address it.`);
|
|
1052
1074
|
if (key in this.completed) {
|
|
1053
1075
|
const value = this.completed[key];
|
|
1054
1076
|
return { then: (resolve) => resolve(value) };
|
|
@@ -1287,13 +1309,14 @@ function workflow(fn) {
|
|
|
1287
1309
|
/**
|
|
1288
1310
|
* Suspend the workflow and wait for an external approval.
|
|
1289
1311
|
*
|
|
1290
|
-
*
|
|
1291
|
-
*
|
|
1312
|
+
* Pass `key` to name the step, then `getApprovalUrls(key)` yields the URLs that
|
|
1313
|
+
* resume exactly this approval — route them through your own channel. Without a
|
|
1314
|
+
* key the steps are named `approval`, `approval_2`, ...
|
|
1292
1315
|
*
|
|
1293
1316
|
* @example
|
|
1294
|
-
* const urls = await step("urls", () =>
|
|
1295
|
-
* await step("notify", () => sendEmail(urls.
|
|
1296
|
-
* const { value, approver } = await waitForApproval({ timeout: 3600 });
|
|
1317
|
+
* const urls = await step("urls", () => getApprovalUrls("manager"));
|
|
1318
|
+
* await step("notify", () => sendEmail(urls.resume, urls.cancel));
|
|
1319
|
+
* const { value, approver } = await waitForApproval({ key: "manager", timeout: 3600 });
|
|
1297
1320
|
*/
|
|
1298
1321
|
function waitForApproval(options) {
|
|
1299
1322
|
const ctx = _workflowCtx ?? Reflect.get(globalThis, "__wmill_wf_ctx");
|
|
@@ -1301,6 +1324,37 @@ function waitForApproval(options) {
|
|
|
1301
1324
|
return ctx._waitForApproval(options);
|
|
1302
1325
|
}
|
|
1303
1326
|
/**
|
|
1327
|
+
* Resume/cancel/approval-page URLs bound to one `waitForApproval` step.
|
|
1328
|
+
*
|
|
1329
|
+
* Unlike `getResumeUrls()`, which signs a random nonce, these address the very
|
|
1330
|
+
* `resume_job` record the step's built-in approval buttons use, so they are
|
|
1331
|
+
* stable across replays and safe to embed in a custom notification.
|
|
1332
|
+
*
|
|
1333
|
+
* `stepKey` must match the `key` given to `waitForApproval`. Keys must be unique
|
|
1334
|
+
* within a workflow; reusing one throws rather than silently renaming it. The URL
|
|
1335
|
+
* only resumes while that step is awaiting approval; used at any other moment it is
|
|
1336
|
+
* rejected rather than banking a row a different approval would consume. Send it
|
|
1337
|
+
* ahead of time — approvers just cannot act before the workflow reaches the step.
|
|
1338
|
+
*
|
|
1339
|
+
* `resume` and `cancel` are step-bound; `approvalPage` is not — it opens the job's
|
|
1340
|
+
* approval page, which acts on whichever approval is pending when it is used.
|
|
1341
|
+
*
|
|
1342
|
+
* @example
|
|
1343
|
+
* const urls = await step("urls", () => getApprovalUrls("manager"));
|
|
1344
|
+
* await step("notify", () => sendEmail(urls.resume, urls.cancel));
|
|
1345
|
+
* await waitForApproval({ key: "manager" });
|
|
1346
|
+
*/
|
|
1347
|
+
async function getApprovalUrls(stepKey = "approval", approver) {
|
|
1348
|
+
assertUsableStepKey(stepKey, "getApprovalUrls stepKey");
|
|
1349
|
+
const workspace = getWorkspace();
|
|
1350
|
+
return await JobService.getWacApprovalUrls({
|
|
1351
|
+
workspace,
|
|
1352
|
+
stepKey,
|
|
1353
|
+
approver,
|
|
1354
|
+
id: getEnv("WM_JOB_ID") ?? "NO_JOB_ID"
|
|
1355
|
+
});
|
|
1356
|
+
}
|
|
1357
|
+
/**
|
|
1304
1358
|
* Process items in parallel with optional concurrency control.
|
|
1305
1359
|
*
|
|
1306
1360
|
* Each item is processed by calling `fn(item)`, which should be a task().
|
|
@@ -1342,4 +1396,4 @@ async function commitKafkaOffsets(triggerPath, topic, partition, offset) {
|
|
|
1342
1396
|
}
|
|
1343
1397
|
|
|
1344
1398
|
//#endregion
|
|
1345
|
-
export { SHARED_FOLDER, StepSuspend, WorkflowCtx, _workflowCtx, appendToResultStream, base64ToUint8Array, commitKafkaOffsets, databaseUrlFromResource, deleteS3File, denoS3LightClientSettings, getEnv, getFlowUserState, getIdToken, getInternalState, getPresignedS3PublicUrl, getPresignedS3PublicUrls, getProgress, getResource, getResult, getResultMaybe, getResumeEndpoints, getResumeUrls, getRootJobId, getState, getStatePath, getVariable, getWorkspace, loadS3File, loadS3FileStream, parallel, requestInteractiveSlackApproval, requestInteractiveTeamsApproval, resolveDefaultResource, runFlow, runFlowAsync, runScript, runScriptAsync, runScriptByHash, runScriptByHashAsync, runScriptByPath, runScriptByPathAsync, setClient, setFlowUserState, setInternalState, setProgress, setResource, setState, setVariable, setWorkflowCtx, signS3Object, signS3Objects, sleep, step, streamResult, task, taskFlow, taskScript, uint8ArrayToBase64, usernameToEmail, waitForApproval, waitJob, workerHasInternalServer, workflow, writeS3File };
|
|
1399
|
+
export { SHARED_FOLDER, StepSuspend, WorkflowCtx, _workflowCtx, appendToResultStream, base64ToUint8Array, commitKafkaOffsets, databaseUrlFromResource, deleteS3File, denoS3LightClientSettings, getApprovalUrls, getEnv, getFlowUserState, getIdToken, getInternalState, getPresignedS3PublicUrl, getPresignedS3PublicUrls, getProgress, getResource, getResult, getResultMaybe, getResumeEndpoints, getResumeUrls, getRootJobId, getState, getStatePath, getVariable, getWorkspace, loadS3File, loadS3FileStream, parallel, requestInteractiveSlackApproval, requestInteractiveTeamsApproval, resolveDefaultResource, runFlow, runFlowAsync, runScript, runScriptAsync, runScriptByHash, runScriptByHashAsync, runScriptByPath, runScriptByPathAsync, setClient, setFlowUserState, setInternalState, setProgress, setResource, setState, setVariable, setWorkflowCtx, signS3Object, signS3Objects, sleep, step, streamResult, task, taskFlow, taskScript, uint8ArrayToBase64, usernameToEmail, waitForApproval, waitJob, workerHasInternalServer, workflow, writeS3File };
|
package/dist/core/OpenAPI.mjs
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -4,8 +4,8 @@ export { OpenAPI, type OpenAPIConfig } from './core/OpenAPI';
|
|
|
4
4
|
export * from './services.gen';
|
|
5
5
|
export * from './types.gen';
|
|
6
6
|
export type { DenoS3LightClientSettings } from "./s3Types";
|
|
7
|
-
export { type Base64, setClient, getVariable, setVariable, getResource, setResource, getResumeUrls, setState, setProgress, getProgress, getState, getIdToken, denoS3LightClientSettings, loadS3FileStream, loadS3File, writeS3File, deleteS3File, signS3Objects, signS3Object, getPresignedS3PublicUrls, getPresignedS3PublicUrl, task, taskScript, taskFlow, workflow, step, sleep, parallel, waitForApproval, type TaskOptions, WorkflowCtx, _workflowCtx, setWorkflowCtx, StepSuspend, runScript, runScriptAsync, runScriptByPath, runScriptByHash, runScriptByPathAsync, runScriptByHashAsync, runFlow, runFlowAsync, waitJob, getRootJobId, setFlowUserState, getFlowUserState, usernameToEmail, requestInteractiveSlackApproval, type Sql, requestInteractiveTeamsApproval, appendToResultStream, streamResult, datatable, ducklake, upsertPartition, appendPartition, type DucklakeMaterializeOptions, type SqlStatement, type DatatableSqlTemplateFunction, type SqlTemplateFunction, type S3Object, type S3ObjectRecord, type S3ObjectURI, commitKafkaOffsets } from "./client";
|
|
8
|
-
import { setClient, getVariable, setVariable, getResource, setResource, getResumeUrls, setState, setProgress, getProgress, getState, getIdToken, denoS3LightClientSettings, loadS3FileStream, loadS3File, writeS3File, deleteS3File, signS3Objects, signS3Object, getPresignedS3PublicUrls, getPresignedS3PublicUrl, task, taskScript, taskFlow, workflow, step, sleep, parallel, waitForApproval, WorkflowCtx, setWorkflowCtx, StepSuspend, runScript, runScriptAsync, runScriptByPath, runScriptByHash, runScriptByPathAsync, runScriptByHashAsync, runFlow, runFlowAsync, waitJob, getRootJobId, setFlowUserState, getFlowUserState, usernameToEmail, requestInteractiveSlackApproval, requestInteractiveTeamsApproval, appendToResultStream, streamResult, datatable, ducklake, upsertPartition, appendPartition, getWorkspace, getStatePath, getInternalState, setInternalState, getResumeEndpoints, getResult, getResultMaybe, resolveDefaultResource, databaseUrlFromResource, base64ToUint8Array, uint8ArrayToBase64, parseS3Object, commitKafkaOffsets } from "./client";
|
|
7
|
+
export { type Base64, setClient, getVariable, setVariable, getResource, setResource, getResumeUrls, setState, setProgress, getProgress, getState, getIdToken, denoS3LightClientSettings, loadS3FileStream, loadS3File, writeS3File, deleteS3File, signS3Objects, signS3Object, getPresignedS3PublicUrls, getPresignedS3PublicUrl, task, taskScript, taskFlow, workflow, step, sleep, parallel, waitForApproval, getApprovalUrls, type TaskOptions, WorkflowCtx, _workflowCtx, setWorkflowCtx, StepSuspend, runScript, runScriptAsync, runScriptByPath, runScriptByHash, runScriptByPathAsync, runScriptByHashAsync, runFlow, runFlowAsync, waitJob, getRootJobId, setFlowUserState, getFlowUserState, usernameToEmail, requestInteractiveSlackApproval, type Sql, requestInteractiveTeamsApproval, appendToResultStream, streamResult, datatable, ducklake, upsertPartition, appendPartition, type DucklakeMaterializeOptions, type SqlStatement, type DatatableSqlTemplateFunction, type SqlTemplateFunction, type S3Object, type S3ObjectRecord, type S3ObjectURI, commitKafkaOffsets } from "./client";
|
|
8
|
+
import { setClient, getVariable, setVariable, getResource, setResource, getResumeUrls, setState, setProgress, getProgress, getState, getIdToken, denoS3LightClientSettings, loadS3FileStream, loadS3File, writeS3File, deleteS3File, signS3Objects, signS3Object, getPresignedS3PublicUrls, getPresignedS3PublicUrl, task, taskScript, taskFlow, workflow, step, sleep, parallel, waitForApproval, getApprovalUrls, WorkflowCtx, setWorkflowCtx, StepSuspend, runScript, runScriptAsync, runScriptByPath, runScriptByHash, runScriptByPathAsync, runScriptByHashAsync, runFlow, runFlowAsync, waitJob, getRootJobId, setFlowUserState, getFlowUserState, usernameToEmail, requestInteractiveSlackApproval, requestInteractiveTeamsApproval, appendToResultStream, streamResult, datatable, ducklake, upsertPartition, appendPartition, getWorkspace, getStatePath, getInternalState, setInternalState, getResumeEndpoints, getResult, getResultMaybe, resolveDefaultResource, databaseUrlFromResource, base64ToUint8Array, uint8ArrayToBase64, parseS3Object, commitKafkaOffsets } from "./client";
|
|
9
9
|
import { AdminService, AuditService, FlowService, GranularAclService, GroupService, JobService, ResourceService, VariableService, ScriptService, ScheduleService, SettingsService, UserService, WorkspaceService, TeamsService } from "./services.gen";
|
|
10
10
|
declare const wmill: {
|
|
11
11
|
setClient: typeof setClient;
|
|
@@ -36,6 +36,7 @@ declare const wmill: {
|
|
|
36
36
|
sleep: typeof sleep;
|
|
37
37
|
parallel: typeof parallel;
|
|
38
38
|
waitForApproval: typeof waitForApproval;
|
|
39
|
+
getApprovalUrls: typeof getApprovalUrls;
|
|
39
40
|
WorkflowCtx: typeof WorkflowCtx;
|
|
40
41
|
_workflowCtx: WorkflowCtx | null;
|
|
41
42
|
setWorkflowCtx: typeof setWorkflowCtx;
|
package/dist/index.js
CHANGED
|
@@ -126,7 +126,7 @@ const OpenAPI = {
|
|
|
126
126
|
PASSWORD: void 0,
|
|
127
127
|
TOKEN: getEnv$1("WM_TOKEN"),
|
|
128
128
|
USERNAME: void 0,
|
|
129
|
-
VERSION: "1.
|
|
129
|
+
VERSION: "1.771.0",
|
|
130
130
|
WITH_CREDENTIALS: true,
|
|
131
131
|
interceptors: {
|
|
132
132
|
request: new Interceptors(),
|
|
@@ -7445,6 +7445,42 @@ var ScriptService = class {
|
|
|
7445
7445
|
mediaType: "application/json"
|
|
7446
7446
|
});
|
|
7447
7447
|
}
|
|
7448
|
+
/**
|
|
7449
|
+
* list runnables (scripts, flows, apps) merged, ordered and keyset-paginated
|
|
7450
|
+
* @param data The data for the request.
|
|
7451
|
+
* @param data.workspace
|
|
7452
|
+
* @param data.orderBy sort key: 'updated' (default) or 'name'
|
|
7453
|
+
* @param data.orderDesc order by desc order (default true)
|
|
7454
|
+
* @param data.kinds comma-separated subset of script,flow,app (default all)
|
|
7455
|
+
* @param data.showArchived
|
|
7456
|
+
* @param data.includeWithoutMain include library scripts (no runnable main)
|
|
7457
|
+
* @param data.pathStart restrict to paths under this prefix
|
|
7458
|
+
* @param data.label
|
|
7459
|
+
* @param data.search case-insensitive substring match on summary or path
|
|
7460
|
+
* @param data.perPage number of items to return for a given page (default 30, max 100)
|
|
7461
|
+
* @param data.cursor opaque keyset cursor from a previous page's next_cursor
|
|
7462
|
+
* @returns unknown a page of merged, ordered runnables
|
|
7463
|
+
* @throws ApiError
|
|
7464
|
+
*/
|
|
7465
|
+
static listRunnables(data) {
|
|
7466
|
+
return request(OpenAPI, {
|
|
7467
|
+
method: "GET",
|
|
7468
|
+
url: "/w/{workspace}/runnables/list",
|
|
7469
|
+
path: { workspace: data.workspace },
|
|
7470
|
+
query: {
|
|
7471
|
+
order_by: data.orderBy,
|
|
7472
|
+
order_desc: data.orderDesc,
|
|
7473
|
+
kinds: data.kinds,
|
|
7474
|
+
show_archived: data.showArchived,
|
|
7475
|
+
include_without_main: data.includeWithoutMain,
|
|
7476
|
+
path_start: data.pathStart,
|
|
7477
|
+
label: data.label,
|
|
7478
|
+
search: data.search,
|
|
7479
|
+
per_page: data.perPage,
|
|
7480
|
+
cursor: data.cursor
|
|
7481
|
+
}
|
|
7482
|
+
});
|
|
7483
|
+
}
|
|
7448
7484
|
};
|
|
7449
7485
|
var DraftService = class {
|
|
7450
7486
|
/**
|
|
@@ -8975,6 +9011,7 @@ var JobService = class {
|
|
|
8975
9011
|
* @param data.page which page to return (start at 1, default 1)
|
|
8976
9012
|
* @param data.perPage number of items to return for a given page (default 30, max 100)
|
|
8977
9013
|
* @param data.isSkipped is the job skipped
|
|
9014
|
+
* @param data.resolved filter on whether a failure has been marked as handled. true keeps only resolved failures, false hides them
|
|
8978
9015
|
* @param data.isFlowStep is the job a flow step
|
|
8979
9016
|
* @param data.hasNullParent has null parent
|
|
8980
9017
|
* @param data.success filter on successful jobs
|
|
@@ -9016,6 +9053,7 @@ var JobService = class {
|
|
|
9016
9053
|
page: data.page,
|
|
9017
9054
|
per_page: data.perPage,
|
|
9018
9055
|
is_skipped: data.isSkipped,
|
|
9056
|
+
resolved: data.resolved,
|
|
9019
9057
|
is_flow_step: data.isFlowStep,
|
|
9020
9058
|
has_null_parent: data.hasNullParent,
|
|
9021
9059
|
success: data.success,
|
|
@@ -9153,6 +9191,7 @@ var JobService = class {
|
|
|
9153
9191
|
* @param data.page which page to return (start at 1, default 1)
|
|
9154
9192
|
* @param data.perPage number of items to return for a given page (default 30, max 100)
|
|
9155
9193
|
* @param data.isSkipped is the job skipped
|
|
9194
|
+
* @param data.resolved filter on whether a failure has been marked as handled. true keeps only resolved failures, false hides them
|
|
9156
9195
|
* @param data.isFlowStep is the job a flow step
|
|
9157
9196
|
* @param data.hasNullParent has null parent
|
|
9158
9197
|
* @param data.isNotSchedule is not a scheduled job
|
|
@@ -9186,6 +9225,7 @@ var JobService = class {
|
|
|
9186
9225
|
page: data.page,
|
|
9187
9226
|
per_page: data.perPage,
|
|
9188
9227
|
is_skipped: data.isSkipped,
|
|
9228
|
+
resolved: data.resolved,
|
|
9189
9229
|
is_flow_step: data.isFlowStep,
|
|
9190
9230
|
has_null_parent: data.hasNullParent,
|
|
9191
9231
|
is_not_schedule: data.isNotSchedule
|
|
@@ -9314,6 +9354,7 @@ var JobService = class {
|
|
|
9314
9354
|
* @param data.perPage number of items to return for a given page (default 30, max 100)
|
|
9315
9355
|
* @param data.triggerKind filter by trigger kind. Supports comma-separated list (e.g. 'schedule,webhook') and negation by prefixing all values with '!' (e.g. '!schedule,!webhook')
|
|
9316
9356
|
* @param data.isSkipped is the job skipped
|
|
9357
|
+
* @param data.resolved filter on whether a failure has been marked as handled. true keeps only resolved failures, false hides them
|
|
9317
9358
|
* @param data.isFlowStep is the job a flow step
|
|
9318
9359
|
* @param data.hasNullParent has null parent
|
|
9319
9360
|
* @param data.success filter on successful jobs
|
|
@@ -9358,6 +9399,7 @@ var JobService = class {
|
|
|
9358
9399
|
per_page: data.perPage,
|
|
9359
9400
|
trigger_kind: data.triggerKind,
|
|
9360
9401
|
is_skipped: data.isSkipped,
|
|
9402
|
+
resolved: data.resolved,
|
|
9361
9403
|
is_flow_step: data.isFlowStep,
|
|
9362
9404
|
has_null_parent: data.hasNullParent,
|
|
9363
9405
|
success: data.success,
|
|
@@ -9796,6 +9838,41 @@ var JobService = class {
|
|
|
9796
9838
|
});
|
|
9797
9839
|
}
|
|
9798
9840
|
/**
|
|
9841
|
+
* mark failed jobs as resolved
|
|
9842
|
+
* Marks failed jobs as handled so triage surfaces stop showing them as failures. The job status itself is unchanged. Returns the ids actually resolved: ids that are not visible to the caller or did not fail are silently skipped.
|
|
9843
|
+
* @param data The data for the request.
|
|
9844
|
+
* @param data.workspace
|
|
9845
|
+
* @param data.requestBody
|
|
9846
|
+
* @returns string ids of the jobs that were resolved
|
|
9847
|
+
* @throws ApiError
|
|
9848
|
+
*/
|
|
9849
|
+
static resolveCompletedJobs(data) {
|
|
9850
|
+
return request(OpenAPI, {
|
|
9851
|
+
method: "POST",
|
|
9852
|
+
url: "/w/{workspace}/jobs/completed/resolve",
|
|
9853
|
+
path: { workspace: data.workspace },
|
|
9854
|
+
body: data.requestBody,
|
|
9855
|
+
mediaType: "application/json"
|
|
9856
|
+
});
|
|
9857
|
+
}
|
|
9858
|
+
/**
|
|
9859
|
+
* remove the resolution of failed jobs
|
|
9860
|
+
* @param data The data for the request.
|
|
9861
|
+
* @param data.workspace
|
|
9862
|
+
* @param data.requestBody
|
|
9863
|
+
* @returns string ids of the jobs that were unresolved
|
|
9864
|
+
* @throws ApiError
|
|
9865
|
+
*/
|
|
9866
|
+
static unresolveCompletedJobs(data) {
|
|
9867
|
+
return request(OpenAPI, {
|
|
9868
|
+
method: "POST",
|
|
9869
|
+
url: "/w/{workspace}/jobs/completed/unresolve",
|
|
9870
|
+
path: { workspace: data.workspace },
|
|
9871
|
+
body: data.requestBody,
|
|
9872
|
+
mediaType: "application/json"
|
|
9873
|
+
});
|
|
9874
|
+
}
|
|
9875
|
+
/**
|
|
9799
9876
|
* cancel queued or running job
|
|
9800
9877
|
* @param data The data for the request.
|
|
9801
9878
|
* @param data.workspace
|
|
@@ -9943,6 +10020,28 @@ var JobService = class {
|
|
|
9943
10020
|
});
|
|
9944
10021
|
}
|
|
9945
10022
|
/**
|
|
10023
|
+
* get the resume urls bound to a specific wait_for_approval step of a workflow-as-code job
|
|
10024
|
+
* @param data The data for the request.
|
|
10025
|
+
* @param data.workspace
|
|
10026
|
+
* @param data.id
|
|
10027
|
+
* @param data.stepKey checkpoint key of the wait_for_approval step, as passed to `wait_for_approval(key=...)`
|
|
10028
|
+
* @param data.approver
|
|
10029
|
+
* @returns unknown url endpoints
|
|
10030
|
+
* @throws ApiError
|
|
10031
|
+
*/
|
|
10032
|
+
static getWacApprovalUrls(data) {
|
|
10033
|
+
return request(OpenAPI, {
|
|
10034
|
+
method: "GET",
|
|
10035
|
+
url: "/w/{workspace}/jobs/wac_approval_urls/{id}/{step_key}",
|
|
10036
|
+
path: {
|
|
10037
|
+
workspace: data.workspace,
|
|
10038
|
+
id: data.id,
|
|
10039
|
+
step_key: data.stepKey
|
|
10040
|
+
},
|
|
10041
|
+
query: { approver: data.approver }
|
|
10042
|
+
});
|
|
10043
|
+
}
|
|
10044
|
+
/**
|
|
9946
10045
|
* generate interactive slack approval for suspended job
|
|
9947
10046
|
* @param data The data for the request.
|
|
9948
10047
|
* @param data.workspace
|
|
@@ -10289,6 +10388,7 @@ var JobService = class {
|
|
|
10289
10388
|
* @param data.perPage number of items to return for a given page (default 30, max 100)
|
|
10290
10389
|
* @param data.triggerKind filter by trigger kind. Supports comma-separated list (e.g. 'schedule,webhook') and negation by prefixing all values with '!' (e.g. '!schedule,!webhook')
|
|
10291
10390
|
* @param data.isSkipped is the job skipped
|
|
10391
|
+
* @param data.resolved filter on whether a failure has been marked as handled. true keeps only resolved failures, false hides them
|
|
10292
10392
|
* @param data.isFlowStep is the job a flow step
|
|
10293
10393
|
* @param data.hasNullParent has null parent
|
|
10294
10394
|
* @param data.success filter on successful jobs
|
|
@@ -10330,6 +10430,7 @@ var JobService = class {
|
|
|
10330
10430
|
per_page: data.perPage,
|
|
10331
10431
|
trigger_kind: data.triggerKind,
|
|
10332
10432
|
is_skipped: data.isSkipped,
|
|
10433
|
+
resolved: data.resolved,
|
|
10333
10434
|
is_flow_step: data.isFlowStep,
|
|
10334
10435
|
has_null_parent: data.hasNullParent,
|
|
10335
10436
|
success: data.success,
|
|
@@ -13857,6 +13958,8 @@ var FolderService = class {
|
|
|
13857
13958
|
* list folder names
|
|
13858
13959
|
* @param data The data for the request.
|
|
13859
13960
|
* @param data.workspace
|
|
13961
|
+
* @param data.page which page to return (start at 1, default 1)
|
|
13962
|
+
* @param data.perPage number of items to return for a given page (default 30, max 100)
|
|
13860
13963
|
* @param data.onlyMemberOf only list the folders the user is member of (default false)
|
|
13861
13964
|
* @returns string folder list
|
|
13862
13965
|
* @throws ApiError
|
|
@@ -13866,7 +13969,11 @@ var FolderService = class {
|
|
|
13866
13969
|
method: "GET",
|
|
13867
13970
|
url: "/w/{workspace}/folders/listnames",
|
|
13868
13971
|
path: { workspace: data.workspace },
|
|
13869
|
-
query: {
|
|
13972
|
+
query: {
|
|
13973
|
+
page: data.page,
|
|
13974
|
+
per_page: data.perPage,
|
|
13975
|
+
only_member_of: data.onlyMemberOf
|
|
13976
|
+
}
|
|
13870
13977
|
});
|
|
13871
13978
|
}
|
|
13872
13979
|
/**
|
|
@@ -15366,6 +15473,7 @@ var ConcurrencyGroupsService = class {
|
|
|
15366
15473
|
* @param data.perPage number of items to return for a given page (default 30, max 100)
|
|
15367
15474
|
* @param data.triggerKind filter by trigger kind. Supports comma-separated list (e.g. 'schedule,webhook') and negation by prefixing all values with '!' (e.g. '!schedule,!webhook')
|
|
15368
15475
|
* @param data.isSkipped is the job skipped
|
|
15476
|
+
* @param data.resolved filter on whether a failure has been marked as handled. true keeps only resolved failures, false hides them
|
|
15369
15477
|
* @param data.isFlowStep is the job a flow step
|
|
15370
15478
|
* @param data.hasNullParent has null parent
|
|
15371
15479
|
* @param data.success filter on successful jobs
|
|
@@ -15407,6 +15515,7 @@ var ConcurrencyGroupsService = class {
|
|
|
15407
15515
|
per_page: data.perPage,
|
|
15408
15516
|
trigger_kind: data.triggerKind,
|
|
15409
15517
|
is_skipped: data.isSkipped,
|
|
15518
|
+
resolved: data.resolved,
|
|
15410
15519
|
is_flow_step: data.isFlowStep,
|
|
15411
15520
|
has_null_parent: data.hasNullParent,
|
|
15412
15521
|
success: data.success,
|
|
@@ -15999,6 +16108,36 @@ var HubPublishService = class {
|
|
|
15999
16108
|
});
|
|
16000
16109
|
}
|
|
16001
16110
|
/**
|
|
16111
|
+
* attach a recorded session to a hub raw app
|
|
16112
|
+
* Requires the caller to be a workspace admin. Forwards the request to the
|
|
16113
|
+
* configured Hub scoped to the `{workspace}:{folder}` source and returns
|
|
16114
|
+
* the Hub's status code and raw response body.
|
|
16115
|
+
*
|
|
16116
|
+
* @param data The data for the request.
|
|
16117
|
+
* @param data.workspace
|
|
16118
|
+
* @param data.id hub id of the raw app
|
|
16119
|
+
* @param data.folder workspace folder scoping the Hub publication: a workspace can publish
|
|
16120
|
+
* one Hub project per folder and the Hub-side source key is
|
|
16121
|
+
* `{workspace}:{folder}`
|
|
16122
|
+
*
|
|
16123
|
+
* @param data.requestBody
|
|
16124
|
+
* @returns string raw Hub response body (status code is passed through from the Hub)
|
|
16125
|
+
* @throws ApiError
|
|
16126
|
+
*/
|
|
16127
|
+
static publishHubRawAppRecording(data) {
|
|
16128
|
+
return request(OpenAPI, {
|
|
16129
|
+
method: "POST",
|
|
16130
|
+
url: "/w/{workspace}/hub/raw_apps/{id}/recording",
|
|
16131
|
+
path: {
|
|
16132
|
+
workspace: data.workspace,
|
|
16133
|
+
id: data.id
|
|
16134
|
+
},
|
|
16135
|
+
query: { folder: data.folder },
|
|
16136
|
+
body: data.requestBody,
|
|
16137
|
+
mediaType: "application/json"
|
|
16138
|
+
});
|
|
16139
|
+
}
|
|
16140
|
+
/**
|
|
16002
16141
|
* attach a recording to a hub script
|
|
16003
16142
|
* Requires the caller to be a workspace admin. Forwards the request to the
|
|
16004
16143
|
* configured Hub scoped to the `{workspace}:{folder}` source and returns
|
|
@@ -17636,6 +17775,13 @@ var StepSuspend = class extends Error {
|
|
|
17636
17775
|
this.name = "StepSuspend";
|
|
17637
17776
|
}
|
|
17638
17777
|
};
|
|
17778
|
+
/** A step key travels as one path segment when its URLs are minted, so it must be
|
|
17779
|
+
* non-empty and free of `/` and dot segments — otherwise `waitForApproval` would
|
|
17780
|
+
* accept a key `getApprovalUrls` can never address. */
|
|
17781
|
+
function assertUsableStepKey(key, what) {
|
|
17782
|
+
const k = key.trim();
|
|
17783
|
+
if (k === "" || k === "." || k === ".." || key.includes("/") || key.includes("\\")) throw new Error(`${what} must be a non-empty step name without \`/\` or dot segments`);
|
|
17784
|
+
}
|
|
17639
17785
|
let _workflowCtx = null;
|
|
17640
17786
|
function setWorkflowCtx(ctx) {
|
|
17641
17787
|
_workflowCtx = ctx;
|
|
@@ -17643,7 +17789,11 @@ function setWorkflowCtx(ctx) {
|
|
|
17643
17789
|
}
|
|
17644
17790
|
var WorkflowCtx = class {
|
|
17645
17791
|
completed;
|
|
17646
|
-
|
|
17792
|
+
/** Null-prototype: step keys are caller-supplied, and a plain object would
|
|
17793
|
+
* resolve `toString`/`constructor`/`__proto__` off `Object.prototype`. */
|
|
17794
|
+
counters = Object.create(null);
|
|
17795
|
+
/** Every key handed out by `_allocKey`, so distinct names can't alias one key. */
|
|
17796
|
+
_usedKeys = new Set();
|
|
17647
17797
|
pending = [];
|
|
17648
17798
|
_suspended = false;
|
|
17649
17799
|
/** When set, the task matching this key executes its inner function directly */
|
|
@@ -17659,14 +17809,23 @@ var WorkflowCtx = class {
|
|
|
17659
17809
|
* `completed_steps[key]`. Initialized to a resolved promise. */
|
|
17660
17810
|
_inlineChain = Promise.resolve();
|
|
17661
17811
|
constructor(checkpoint = {}) {
|
|
17662
|
-
this.completed = checkpoint?.completed_steps ?? {};
|
|
17812
|
+
this.completed = Object.assign(Object.create(null), checkpoint?.completed_steps ?? {});
|
|
17663
17813
|
this._executingKey = checkpoint?._executing_key ?? null;
|
|
17664
17814
|
}
|
|
17665
|
-
/** Name-based key: `double` for first call, `double_2`, `double_3` for subsequent.
|
|
17815
|
+
/** Name-based key: `double` for first call, `double_2`, `double_3` for subsequent.
|
|
17816
|
+
* Suffixing alone can alias — a second `step("x")` and a first `step("x_2")` both
|
|
17817
|
+
* want `x_2` — so keep bumping past keys already handed out. Allocation order is
|
|
17818
|
+
* fixed by the workflow body, so replays reproduce the same keys. */
|
|
17666
17819
|
_allocKey(name) {
|
|
17667
|
-
|
|
17820
|
+
let n = (this.counters[name] ?? 0) + 1;
|
|
17821
|
+
let key = n === 1 ? name : `${name}_${n}`;
|
|
17822
|
+
while (this._usedKeys.has(key)) {
|
|
17823
|
+
n++;
|
|
17824
|
+
key = `${name}_${n}`;
|
|
17825
|
+
}
|
|
17668
17826
|
this.counters[name] = n;
|
|
17669
|
-
|
|
17827
|
+
this._usedKeys.add(key);
|
|
17828
|
+
return key;
|
|
17670
17829
|
}
|
|
17671
17830
|
_nextStep(name, script, args = {}, dispatch_type = "inline", options) {
|
|
17672
17831
|
const key = this._allocKey(name || script || "step");
|
|
@@ -17726,7 +17885,9 @@ var WorkflowCtx = class {
|
|
|
17726
17885
|
return steps;
|
|
17727
17886
|
}
|
|
17728
17887
|
_waitForApproval(options) {
|
|
17729
|
-
|
|
17888
|
+
if (options?.key !== void 0) assertUsableStepKey(options.key, "waitForApproval key");
|
|
17889
|
+
const key = this._allocKey(options?.key || "approval");
|
|
17890
|
+
if (options?.key && key !== options.key) throw new Error(`WAC step key "${options.key}" is already used in this workflow. Give each waitForApproval() its own key so getApprovalUrls() can address it.`);
|
|
17730
17891
|
if (key in this.completed) {
|
|
17731
17892
|
const value = this.completed[key];
|
|
17732
17893
|
return { then: (resolve$1) => resolve$1(value) };
|
|
@@ -17965,13 +18126,14 @@ function workflow(fn) {
|
|
|
17965
18126
|
/**
|
|
17966
18127
|
* Suspend the workflow and wait for an external approval.
|
|
17967
18128
|
*
|
|
17968
|
-
*
|
|
17969
|
-
*
|
|
18129
|
+
* Pass `key` to name the step, then `getApprovalUrls(key)` yields the URLs that
|
|
18130
|
+
* resume exactly this approval — route them through your own channel. Without a
|
|
18131
|
+
* key the steps are named `approval`, `approval_2`, ...
|
|
17970
18132
|
*
|
|
17971
18133
|
* @example
|
|
17972
|
-
* const urls = await step("urls", () =>
|
|
17973
|
-
* await step("notify", () => sendEmail(urls.
|
|
17974
|
-
* const { value, approver } = await waitForApproval({ timeout: 3600 });
|
|
18134
|
+
* const urls = await step("urls", () => getApprovalUrls("manager"));
|
|
18135
|
+
* await step("notify", () => sendEmail(urls.resume, urls.cancel));
|
|
18136
|
+
* const { value, approver } = await waitForApproval({ key: "manager", timeout: 3600 });
|
|
17975
18137
|
*/
|
|
17976
18138
|
function waitForApproval(options) {
|
|
17977
18139
|
const ctx = _workflowCtx ?? Reflect.get(globalThis, "__wmill_wf_ctx");
|
|
@@ -17979,6 +18141,37 @@ function waitForApproval(options) {
|
|
|
17979
18141
|
return ctx._waitForApproval(options);
|
|
17980
18142
|
}
|
|
17981
18143
|
/**
|
|
18144
|
+
* Resume/cancel/approval-page URLs bound to one `waitForApproval` step.
|
|
18145
|
+
*
|
|
18146
|
+
* Unlike `getResumeUrls()`, which signs a random nonce, these address the very
|
|
18147
|
+
* `resume_job` record the step's built-in approval buttons use, so they are
|
|
18148
|
+
* stable across replays and safe to embed in a custom notification.
|
|
18149
|
+
*
|
|
18150
|
+
* `stepKey` must match the `key` given to `waitForApproval`. Keys must be unique
|
|
18151
|
+
* within a workflow; reusing one throws rather than silently renaming it. The URL
|
|
18152
|
+
* only resumes while that step is awaiting approval; used at any other moment it is
|
|
18153
|
+
* rejected rather than banking a row a different approval would consume. Send it
|
|
18154
|
+
* ahead of time — approvers just cannot act before the workflow reaches the step.
|
|
18155
|
+
*
|
|
18156
|
+
* `resume` and `cancel` are step-bound; `approvalPage` is not — it opens the job's
|
|
18157
|
+
* approval page, which acts on whichever approval is pending when it is used.
|
|
18158
|
+
*
|
|
18159
|
+
* @example
|
|
18160
|
+
* const urls = await step("urls", () => getApprovalUrls("manager"));
|
|
18161
|
+
* await step("notify", () => sendEmail(urls.resume, urls.cancel));
|
|
18162
|
+
* await waitForApproval({ key: "manager" });
|
|
18163
|
+
*/
|
|
18164
|
+
async function getApprovalUrls(stepKey = "approval", approver) {
|
|
18165
|
+
assertUsableStepKey(stepKey, "getApprovalUrls stepKey");
|
|
18166
|
+
const workspace = getWorkspace();
|
|
18167
|
+
return await JobService.getWacApprovalUrls({
|
|
18168
|
+
workspace,
|
|
18169
|
+
stepKey,
|
|
18170
|
+
approver,
|
|
18171
|
+
id: getEnv("WM_JOB_ID") ?? "NO_JOB_ID"
|
|
18172
|
+
});
|
|
18173
|
+
}
|
|
18174
|
+
/**
|
|
17982
18175
|
* Process items in parallel with optional concurrency control.
|
|
17983
18176
|
*
|
|
17984
18177
|
* Each item is processed by calling `fn(item)`, which should be a task().
|
|
@@ -18050,6 +18243,7 @@ const wmill = {
|
|
|
18050
18243
|
sleep,
|
|
18051
18244
|
parallel,
|
|
18052
18245
|
waitForApproval,
|
|
18246
|
+
getApprovalUrls,
|
|
18053
18247
|
WorkflowCtx,
|
|
18054
18248
|
_workflowCtx,
|
|
18055
18249
|
setWorkflowCtx,
|
|
@@ -18189,6 +18383,7 @@ exports.default = src_default;
|
|
|
18189
18383
|
exports.deleteS3File = deleteS3File;
|
|
18190
18384
|
exports.denoS3LightClientSettings = denoS3LightClientSettings;
|
|
18191
18385
|
exports.ducklake = ducklake;
|
|
18386
|
+
exports.getApprovalUrls = getApprovalUrls;
|
|
18192
18387
|
exports.getFlowUserState = getFlowUserState;
|
|
18193
18388
|
exports.getIdToken = getIdToken;
|
|
18194
18389
|
exports.getPresignedS3PublicUrl = getPresignedS3PublicUrl;
|