windmill-client 1.450.0-beta.0 → 1.450.0-beta.2

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 CHANGED
@@ -19,17 +19,19 @@ export declare function getWorkspace(): string;
19
19
  */
20
20
  export declare function getResource(path?: string, undefinedIfEmpty?: boolean): Promise<any>;
21
21
  /**
22
- * Get a resource value by path
22
+ * Get the true root job id
23
23
  * @param jobId job id to get the root job id from (default to current job)
24
24
  * @returns root job id
25
25
  */
26
26
  export declare function getRootJobId(jobId?: string): Promise<string>;
27
27
  export declare function runScript(path?: string | null, hash_?: string | null, args?: Record<string, any> | null, verbose?: boolean): Promise<any>;
28
+ export declare function runFlow(path?: string | null, args?: Record<string, any> | null, verbose?: boolean): Promise<any>;
28
29
  export declare function waitJob(jobId: string, verbose?: boolean): Promise<any>;
29
30
  export declare function getResult(jobId: string): Promise<any>;
30
31
  export declare function getResultMaybe(jobId: string): Promise<any>;
31
32
  export declare function task<P, T>(f: (_: P) => T): (_: P) => Promise<T>;
32
33
  export declare function runScriptAsync(path: string | null, hash_: string | null, args: Record<string, any> | null, scheduledInSeconds?: number | null): Promise<string>;
34
+ export declare function runFlowAsync(path: string | null, args: Record<string, any> | null, scheduledInSeconds?: number | null, doNotTrackInParent?: boolean): Promise<string>;
33
35
  /**
34
36
  * Resolve a resource value in case the default value was picked because the input payload was undefined
35
37
  * @param obj resource value or path of the resource under the format `$res:path`
@@ -55,6 +57,19 @@ export declare function setInternalState(state: any): Promise<void>;
55
57
  * @param state state to set
56
58
  */
57
59
  export declare function setState(state: any): Promise<void>;
60
+ /**
61
+ * Set the progress
62
+ * Progress cannot go back and limited to 0% to 99% range
63
+ * @param percent Progress to set in %
64
+ * @param jobId? Job to set progress for
65
+ */
66
+ export declare function setProgress(percent: number, jobId?: any): Promise<void>;
67
+ /**
68
+ * Get the progress
69
+ * @param jobId? Job to get progress from
70
+ * @returns Optional clamped between 0 and 100 progress value
71
+ */
72
+ export declare function getProgress(jobId?: any): Promise<number | null>;
58
73
  /**
59
74
  * Set a flow user state
60
75
  * @param key key of the state
@@ -123,7 +138,7 @@ export declare function loadS3FileStream(s3object: S3Object, s3ResourcePath?: st
123
138
  * console.log(fileContentAsUtf8Str)
124
139
  * ```
125
140
  */
126
- export declare function writeS3File(s3object: S3Object | undefined, fileContent: string | Blob, s3ResourcePath?: string | undefined): Promise<S3Object>;
141
+ export declare function writeS3File(s3object: S3Object | undefined, fileContent: string | Blob, s3ResourcePath?: string | undefined, contentType?: string | undefined, contentDisposition?: string | undefined): Promise<S3Object>;
127
142
  /**
128
143
  * Get URLs needed for resuming a flow after this step
129
144
  * @param approver approver name
@@ -158,3 +173,45 @@ export declare function uint8ArrayToBase64(arrayBuffer: Uint8Array): string;
158
173
  * @returns email address
159
174
  */
160
175
  export declare function usernameToEmail(username: string): Promise<string>;
176
+ interface SlackApprovalOptions {
177
+ slackResourcePath: string;
178
+ channelId: string;
179
+ message?: string;
180
+ approver?: string;
181
+ defaultArgsJson?: Record<string, any>;
182
+ dynamicEnumsJson?: Record<string, any>;
183
+ }
184
+ /**
185
+ * Sends an interactive approval request via Slack, allowing optional customization of the message, approver, and form fields.
186
+ *
187
+ * **[Enterprise Edition Only]** To include form fields in the Slack approval request, go to **Advanced -> Suspend -> Form**
188
+ * and define a form. Learn more at [Windmill Documentation](https://www.windmill.dev/docs/flows/flow_approval#form).
189
+ *
190
+ * @param {Object} options - The configuration options for the Slack approval request.
191
+ * @param {string} options.slackResourcePath - The path to the Slack resource in Windmill.
192
+ * @param {string} options.channelId - The Slack channel ID where the approval request will be sent.
193
+ * @param {string} [options.message] - Optional custom message to include in the Slack approval request.
194
+ * @param {string} [options.approver] - Optional user ID or name of the approver for the request.
195
+ * @param {DefaultArgs} [options.defaultArgsJson] - Optional object defining or overriding the default arguments to a form field.
196
+ * @param {Enums} [options.dynamicEnumsJson] - Optional object overriding the enum default values of an enum form field.
197
+ *
198
+ * @returns {Promise<void>} Resolves when the Slack approval request is successfully sent.
199
+ *
200
+ * @throws {Error} If the function is not called within a flow or flow preview.
201
+ * @throws {Error} If the `JobService.getSlackApprovalPayload` call fails.
202
+ *
203
+ * **Usage Example:**
204
+ * ```typescript
205
+ * await requestInteractiveSlackApproval({
206
+ * slackResourcePath: "/u/alex/my_slack_resource",
207
+ * channelId: "admins-slack-channel",
208
+ * message: "Please approve this request",
209
+ * approver: "approver123",
210
+ * defaultArgsJson: { key1: "value1", key2: 42 },
211
+ * dynamicEnumsJson: { foo: ["choice1", "choice2"], bar: ["optionA", "optionB"] },
212
+ * });
213
+ * ```
214
+ *
215
+ * **Note:** This function requires execution within a Windmill flow or flow preview.
216
+ */
217
+ export declare function requestInteractiveSlackApproval({ slackResourcePath, channelId, message, approver, defaultArgsJson, dynamicEnumsJson, }: SlackApprovalOptions): Promise<void>;
package/dist/client.js CHANGED
@@ -9,7 +9,44 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.usernameToEmail = exports.uint8ArrayToBase64 = exports.base64ToUint8Array = exports.getIdToken = exports.getResumeEndpoints = exports.getResumeUrls = exports.writeS3File = exports.loadS3FileStream = exports.loadS3File = exports.denoS3LightClientSettings = exports.databaseUrlFromResource = exports.setVariable = exports.getVariable = exports.getState = exports.getInternalState = exports.getFlowUserState = exports.setFlowUserState = exports.setState = exports.setInternalState = exports.setResource = exports.getStatePath = exports.resolveDefaultResource = exports.runScriptAsync = exports.task = exports.getResultMaybe = exports.getResult = exports.waitJob = exports.runScript = exports.getRootJobId = exports.getResource = exports.getWorkspace = exports.setClient = exports.SHARED_FOLDER = exports.WorkspaceService = exports.UserService = exports.SettingsService = exports.ScheduleService = exports.ScriptService = exports.VariableService = exports.ResourceService = exports.JobService = exports.GroupService = exports.GranularAclService = exports.FlowService = exports.AuditService = exports.AdminService = void 0;
12
+ exports.SHARED_FOLDER = exports.WorkspaceService = exports.UserService = exports.SettingsService = exports.ScheduleService = exports.ScriptService = exports.VariableService = exports.ResourceService = exports.JobService = exports.GroupService = exports.GranularAclService = exports.FlowService = exports.AuditService = exports.AdminService = void 0;
13
+ exports.setClient = setClient;
14
+ exports.getWorkspace = getWorkspace;
15
+ exports.getResource = getResource;
16
+ exports.getRootJobId = getRootJobId;
17
+ exports.runScript = runScript;
18
+ exports.runFlow = runFlow;
19
+ exports.waitJob = waitJob;
20
+ exports.getResult = getResult;
21
+ exports.getResultMaybe = getResultMaybe;
22
+ exports.task = task;
23
+ exports.runScriptAsync = runScriptAsync;
24
+ exports.runFlowAsync = runFlowAsync;
25
+ exports.resolveDefaultResource = resolveDefaultResource;
26
+ exports.getStatePath = getStatePath;
27
+ exports.setResource = setResource;
28
+ exports.setInternalState = setInternalState;
29
+ exports.setState = setState;
30
+ exports.setProgress = setProgress;
31
+ exports.getProgress = getProgress;
32
+ exports.setFlowUserState = setFlowUserState;
33
+ exports.getFlowUserState = getFlowUserState;
34
+ exports.getInternalState = getInternalState;
35
+ exports.getState = getState;
36
+ exports.getVariable = getVariable;
37
+ exports.setVariable = setVariable;
38
+ exports.databaseUrlFromResource = databaseUrlFromResource;
39
+ exports.denoS3LightClientSettings = denoS3LightClientSettings;
40
+ exports.loadS3File = loadS3File;
41
+ exports.loadS3FileStream = loadS3FileStream;
42
+ exports.writeS3File = writeS3File;
43
+ exports.getResumeUrls = getResumeUrls;
44
+ exports.getResumeEndpoints = getResumeEndpoints;
45
+ exports.getIdToken = getIdToken;
46
+ exports.base64ToUint8Array = base64ToUint8Array;
47
+ exports.uint8ArrayToBase64 = uint8ArrayToBase64;
48
+ exports.usernameToEmail = usernameToEmail;
49
+ exports.requestInteractiveSlackApproval = requestInteractiveSlackApproval;
13
50
  const index_1 = require("./index");
14
51
  const index_2 = require("./index");
15
52
  var index_3 = require("./index");
@@ -27,6 +64,7 @@ Object.defineProperty(exports, "SettingsService", { enumerable: true, get: funct
27
64
  Object.defineProperty(exports, "UserService", { enumerable: true, get: function () { return index_3.UserService; } });
28
65
  Object.defineProperty(exports, "WorkspaceService", { enumerable: true, get: function () { return index_3.WorkspaceService; } });
29
66
  exports.SHARED_FOLDER = "/shared";
67
+ let mockedApi = undefined;
30
68
  function setClient(token, baseUrl) {
31
69
  var _a, _b, _c;
32
70
  if (baseUrl === undefined) {
@@ -40,7 +78,6 @@ function setClient(token, baseUrl) {
40
78
  index_2.OpenAPI.TOKEN = token;
41
79
  index_2.OpenAPI.BASE = baseUrl + "/api";
42
80
  }
43
- exports.setClient = setClient;
44
81
  const getEnv = (key) => {
45
82
  var _a, _b, _c;
46
83
  if (typeof window === "undefined") {
@@ -58,7 +95,6 @@ function getWorkspace() {
58
95
  var _a;
59
96
  return (_a = getEnv("WM_WORKSPACE")) !== null && _a !== void 0 ? _a : "no_workspace";
60
97
  }
61
- exports.getWorkspace = getWorkspace;
62
98
  /**
63
99
  * Get a resource value by path
64
100
  * @param path path of the resource, default to internal state path
@@ -67,8 +103,17 @@ exports.getWorkspace = getWorkspace;
67
103
  */
68
104
  function getResource(path, undefinedIfEmpty) {
69
105
  return __awaiter(this, void 0, void 0, function* () {
70
- const workspace = getWorkspace();
71
106
  path = path !== null && path !== void 0 ? path : getStatePath();
107
+ const mockedApi = yield getMockedApi();
108
+ if (mockedApi) {
109
+ if (mockedApi.resources[path]) {
110
+ return mockedApi.resources[path];
111
+ }
112
+ else {
113
+ console.log(`MockedAPI present, but resource not found at ${path}, falling back to real API`);
114
+ }
115
+ }
116
+ const workspace = getWorkspace();
72
117
  try {
73
118
  return yield index_1.ResourceService.getResourceValueInterpolated({
74
119
  workspace,
@@ -85,9 +130,8 @@ function getResource(path, undefinedIfEmpty) {
85
130
  }
86
131
  });
87
132
  }
88
- exports.getResource = getResource;
89
133
  /**
90
- * Get a resource value by path
134
+ * Get the true root job id
91
135
  * @param jobId job id to get the root job id from (default to current job)
92
136
  * @returns root job id
93
137
  */
@@ -101,7 +145,6 @@ function getRootJobId(jobId) {
101
145
  return yield index_1.JobService.getRootJobId({ workspace, id: jobId });
102
146
  });
103
147
  }
104
- exports.getRootJobId = getRootJobId;
105
148
  function runScript() {
106
149
  return __awaiter(this, arguments, void 0, function* (path = null, hash_ = null, args = null, verbose = false) {
107
150
  args = args || {};
@@ -112,7 +155,16 @@ function runScript() {
112
155
  return yield waitJob(jobId, verbose);
113
156
  });
114
157
  }
115
- exports.runScript = runScript;
158
+ function runFlow() {
159
+ return __awaiter(this, arguments, void 0, function* (path = null, args = null, verbose = false) {
160
+ args = args || {};
161
+ if (verbose) {
162
+ console.info(`running \`${path}\` synchronously with args:`, args);
163
+ }
164
+ const jobId = yield runFlowAsync(path, args, null, false);
165
+ return yield waitJob(jobId, verbose);
166
+ });
167
+ }
116
168
  function waitJob(jobId_1) {
117
169
  return __awaiter(this, arguments, void 0, function* (jobId, verbose = false) {
118
170
  while (true) {
@@ -141,21 +193,18 @@ function waitJob(jobId_1) {
141
193
  }
142
194
  });
143
195
  }
144
- exports.waitJob = waitJob;
145
196
  function getResult(jobId) {
146
197
  return __awaiter(this, void 0, void 0, function* () {
147
198
  const workspace = getWorkspace();
148
199
  return yield index_1.JobService.getCompletedJobResult({ workspace, id: jobId });
149
200
  });
150
201
  }
151
- exports.getResult = getResult;
152
202
  function getResultMaybe(jobId) {
153
203
  return __awaiter(this, void 0, void 0, function* () {
154
204
  const workspace = getWorkspace();
155
205
  return yield index_1.JobService.getCompletedJobResultMaybe({ workspace, id: jobId });
156
206
  });
157
207
  }
158
- exports.getResultMaybe = getResultMaybe;
159
208
  const STRIP_COMMENTS = /(\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s*=[^,\)]*(('(?:\\'|[^'\r\n])*')|("(?:\\"|[^"\r\n])*"))|(\s*=[^,\)]*))/gm;
160
209
  const ARGUMENT_NAMES = /([^\s,]+)/g;
161
210
  function getParamNames(func) {
@@ -187,7 +236,6 @@ function task(f) {
187
236
  return r;
188
237
  });
189
238
  }
190
- exports.task = task;
191
239
  function runScriptAsync(path_1, hash_1, args_1) {
192
240
  return __awaiter(this, arguments, void 0, function* (path, hash_, args, scheduledInSeconds = null) {
193
241
  // Create a script job and return its job id.
@@ -229,7 +277,47 @@ function runScriptAsync(path_1, hash_1, args_1) {
229
277
  }).then((res) => res.text());
230
278
  });
231
279
  }
232
- exports.runScriptAsync = runScriptAsync;
280
+ function runFlowAsync(path_1, args_1) {
281
+ return __awaiter(this, arguments, void 0, function* (path, args, scheduledInSeconds = null,
282
+ // can only be set to false if this the job will be fully await and not concurrent with any other job
283
+ // as otherwise the child flow and its own child will store their state in the parent job which will
284
+ // lead to incorrectness and failures
285
+ doNotTrackInParent = true) {
286
+ // Create a script job and return its job id.
287
+ args = args || {};
288
+ const params = {};
289
+ if (scheduledInSeconds) {
290
+ params["scheduled_in_secs"] = scheduledInSeconds;
291
+ }
292
+ if (!doNotTrackInParent) {
293
+ let parentJobId = getEnv("WM_JOB_ID");
294
+ if (parentJobId !== undefined) {
295
+ params["parent_job"] = parentJobId;
296
+ }
297
+ let rootJobId = getEnv("WM_ROOT_FLOW_JOB_ID");
298
+ if (rootJobId != undefined && rootJobId != "") {
299
+ params["root_job"] = rootJobId;
300
+ }
301
+ }
302
+ let endpoint;
303
+ if (path) {
304
+ endpoint = `/w/${getWorkspace()}/jobs/run/f/${path}`;
305
+ }
306
+ else {
307
+ throw new Error("path must be provided");
308
+ }
309
+ let url = new URL(index_2.OpenAPI.BASE + endpoint);
310
+ url.search = new URLSearchParams(params).toString();
311
+ return fetch(url, {
312
+ method: "POST",
313
+ headers: {
314
+ "Content-Type": "application/json",
315
+ Authorization: `Bearer ${index_2.OpenAPI.TOKEN}`,
316
+ },
317
+ body: JSON.stringify(args),
318
+ }).then((res) => res.text());
319
+ });
320
+ }
233
321
  /**
234
322
  * Resolve a resource value in case the default value was picked because the input payload was undefined
235
323
  * @param obj resource value or path of the resource under the format `$res:path`
@@ -245,7 +333,6 @@ function resolveDefaultResource(obj) {
245
333
  }
246
334
  });
247
335
  }
248
- exports.resolveDefaultResource = resolveDefaultResource;
249
336
  function getStatePath() {
250
337
  var _a;
251
338
  const state_path = (_a = getEnv("WM_STATE_PATH_NEW")) !== null && _a !== void 0 ? _a : getEnv("WM_STATE_PATH");
@@ -254,7 +341,6 @@ function getStatePath() {
254
341
  }
255
342
  return state_path;
256
343
  }
257
- exports.getStatePath = getStatePath;
258
344
  /**
259
345
  * Set a resource value by path
260
346
  * @param path path of the resource to set, default to state path
@@ -264,6 +350,11 @@ exports.getStatePath = getStatePath;
264
350
  function setResource(value, path, initializeToTypeIfNotExist) {
265
351
  return __awaiter(this, void 0, void 0, function* () {
266
352
  path = path !== null && path !== void 0 ? path : getStatePath();
353
+ const mockedApi = yield getMockedApi();
354
+ if (mockedApi) {
355
+ mockedApi.resources[path] = value;
356
+ return;
357
+ }
267
358
  const workspace = getWorkspace();
268
359
  if (yield index_1.ResourceService.existsResource({ workspace, path })) {
269
360
  yield index_1.ResourceService.updateResourceValue({
@@ -283,7 +374,6 @@ function setResource(value, path, initializeToTypeIfNotExist) {
283
374
  }
284
375
  });
285
376
  }
286
- exports.setResource = setResource;
287
377
  /**
288
378
  * Set the state
289
379
  * @param state state to set
@@ -294,7 +384,6 @@ function setInternalState(state) {
294
384
  yield setResource(state, undefined, "state");
295
385
  });
296
386
  }
297
- exports.setInternalState = setInternalState;
298
387
  /**
299
388
  * Set the state
300
389
  * @param state state to set
@@ -304,7 +393,53 @@ function setState(state) {
304
393
  yield setResource(state, undefined, "state");
305
394
  });
306
395
  }
307
- exports.setState = setState;
396
+ /**
397
+ * Set the progress
398
+ * Progress cannot go back and limited to 0% to 99% range
399
+ * @param percent Progress to set in %
400
+ * @param jobId? Job to set progress for
401
+ */
402
+ function setProgress(percent, jobId) {
403
+ return __awaiter(this, void 0, void 0, function* () {
404
+ var _a;
405
+ const workspace = getWorkspace();
406
+ let flowId = getEnv("WM_FLOW_JOB_ID");
407
+ // If jobId specified we need to find if there is a parent/flow
408
+ if (jobId) {
409
+ const job = yield index_1.JobService.getJob({
410
+ id: jobId !== null && jobId !== void 0 ? jobId : "NO_JOB_ID",
411
+ workspace,
412
+ noLogs: true,
413
+ });
414
+ // Could be actual flowId or undefined
415
+ flowId = job.parent_job;
416
+ }
417
+ yield index_1.MetricsService.setJobProgress({
418
+ id: (_a = jobId !== null && jobId !== void 0 ? jobId : getEnv("WM_JOB_ID")) !== null && _a !== void 0 ? _a : "NO_JOB_ID",
419
+ workspace,
420
+ requestBody: {
421
+ // In case user inputs float, it should be converted to int
422
+ percent: Math.floor(percent),
423
+ flow_job_id: flowId == "" ? undefined : flowId,
424
+ },
425
+ });
426
+ });
427
+ }
428
+ /**
429
+ * Get the progress
430
+ * @param jobId? Job to get progress from
431
+ * @returns Optional clamped between 0 and 100 progress value
432
+ */
433
+ function getProgress(jobId) {
434
+ return __awaiter(this, void 0, void 0, function* () {
435
+ var _a;
436
+ // TODO: Delete or set to 100 completed job metrics
437
+ return yield index_1.MetricsService.getJobProgress({
438
+ id: (_a = jobId !== null && jobId !== void 0 ? jobId : getEnv("WM_JOB_ID")) !== null && _a !== void 0 ? _a : "NO_JOB_ID",
439
+ workspace: getWorkspace(),
440
+ });
441
+ });
442
+ }
308
443
  /**
309
444
  * Set a flow user state
310
445
  * @param key key of the state
@@ -335,7 +470,6 @@ function setFlowUserState(key, value, errorIfNotPossible) {
335
470
  }
336
471
  });
337
472
  }
338
- exports.setFlowUserState = setFlowUserState;
339
473
  /**
340
474
  * Get a flow user state
341
475
  * @param path path of the variable
@@ -361,7 +495,6 @@ function getFlowUserState(key, errorIfNotPossible) {
361
495
  }
362
496
  });
363
497
  }
364
- exports.getFlowUserState = getFlowUserState;
365
498
  // /**
366
499
  // * Set the shared state
367
500
  // * @param state state to set
@@ -388,7 +521,6 @@ function getInternalState() {
388
521
  return yield getResource(getStatePath(), true);
389
522
  });
390
523
  }
391
- exports.getInternalState = getInternalState;
392
524
  /**
393
525
  * Get the state shared across executions
394
526
  */
@@ -397,7 +529,6 @@ function getState() {
397
529
  return yield getResource(getStatePath(), true);
398
530
  });
399
531
  }
400
- exports.getState = getState;
401
532
  /**
402
533
  * Get a variable by path
403
534
  * @param path path of the variable
@@ -405,6 +536,15 @@ exports.getState = getState;
405
536
  */
406
537
  function getVariable(path) {
407
538
  return __awaiter(this, void 0, void 0, function* () {
539
+ const mockedApi = yield getMockedApi();
540
+ if (mockedApi) {
541
+ if (mockedApi.variables[path]) {
542
+ return mockedApi.variables[path];
543
+ }
544
+ else {
545
+ console.log(`MockedAPI present, but variable not found at ${path}, falling back to real API`);
546
+ }
547
+ }
408
548
  const workspace = getWorkspace();
409
549
  try {
410
550
  return yield index_1.VariableService.getVariableValue({ workspace, path });
@@ -414,7 +554,6 @@ function getVariable(path) {
414
554
  }
415
555
  });
416
556
  }
417
- exports.getVariable = getVariable;
418
557
  /**
419
558
  * Set a variable by path, create if not exist
420
559
  * @param path path of the variable
@@ -424,6 +563,11 @@ exports.getVariable = getVariable;
424
563
  */
425
564
  function setVariable(path, value, isSecretIfNotExist, descriptionIfNotExist) {
426
565
  return __awaiter(this, void 0, void 0, function* () {
566
+ const mockedApi = yield getMockedApi();
567
+ if (mockedApi) {
568
+ mockedApi.variables[path] = value;
569
+ return;
570
+ }
427
571
  const workspace = getWorkspace();
428
572
  if (yield index_1.VariableService.existsVariable({ workspace, path })) {
429
573
  yield index_1.VariableService.updateVariable({
@@ -445,14 +589,12 @@ function setVariable(path, value, isSecretIfNotExist, descriptionIfNotExist) {
445
589
  }
446
590
  });
447
591
  }
448
- exports.setVariable = setVariable;
449
592
  function databaseUrlFromResource(path) {
450
593
  return __awaiter(this, void 0, void 0, function* () {
451
594
  const resource = yield getResource(path);
452
595
  return `postgresql://${resource.user}:${resource.password}@${resource.host}:${resource.port}/${resource.dbname}?sslmode=${resource.sslmode}`;
453
596
  });
454
597
  }
455
- exports.databaseUrlFromResource = databaseUrlFromResource;
456
598
  // TODO(gb): need to investigate more how Polars and DuckDB work in TS
457
599
  // export async function polarsConnectionSettings(s3_resource_path: string | undefined): Promise<any> {
458
600
  // const workspace = getWorkspace();
@@ -485,7 +627,6 @@ function denoS3LightClientSettings(s3_resource_path) {
485
627
  return settings;
486
628
  });
487
629
  }
488
- exports.denoS3LightClientSettings = denoS3LightClientSettings;
489
630
  /**
490
631
  * Load the content of a file stored in S3. If the s3ResourcePath is undefined, it will default to the workspace S3 resource.
491
632
  *
@@ -525,7 +666,6 @@ function loadS3File(s3object_1) {
525
666
  return fileContent;
526
667
  });
527
668
  }
528
- exports.loadS3File = loadS3File;
529
669
  /**
530
670
  * 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.
531
671
  *
@@ -556,7 +696,6 @@ function loadS3FileStream(s3object_1) {
556
696
  return fileContentBlob.blob();
557
697
  });
558
698
  }
559
- exports.loadS3FileStream = loadS3FileStream;
560
699
  /**
561
700
  * Persist a file to the S3 bucket. If the s3ResourcePath is undefined, it will default to the workspace S3 resource.
562
701
  *
@@ -567,7 +706,7 @@ exports.loadS3FileStream = loadS3FileStream;
567
706
  * ```
568
707
  */
569
708
  function writeS3File(s3object_1, fileContent_1) {
570
- return __awaiter(this, arguments, void 0, function* (s3object, fileContent, s3ResourcePath = undefined) {
709
+ return __awaiter(this, arguments, void 0, function* (s3object, fileContent, s3ResourcePath = undefined, contentType = undefined, contentDisposition = undefined) {
571
710
  let fileContentBlob;
572
711
  if (typeof fileContent === "string") {
573
712
  fileContentBlob = new Blob([fileContent], {
@@ -584,13 +723,14 @@ function writeS3File(s3object_1, fileContent_1) {
584
723
  s3ResourcePath: s3ResourcePath,
585
724
  requestBody: fileContentBlob,
586
725
  storage: s3object === null || s3object === void 0 ? void 0 : s3object.storage,
726
+ contentType,
727
+ contentDisposition,
587
728
  });
588
729
  return {
589
730
  s3: response.file_key,
590
731
  };
591
732
  });
592
733
  }
593
- exports.writeS3File = writeS3File;
594
734
  /**
595
735
  * Get URLs needed for resuming a flow after this step
596
736
  * @param approver approver name
@@ -609,14 +749,12 @@ function getResumeUrls(approver) {
609
749
  });
610
750
  });
611
751
  }
612
- exports.getResumeUrls = getResumeUrls;
613
752
  /**
614
753
  * @deprecated use getResumeUrls instead
615
754
  */
616
755
  function getResumeEndpoints(approver) {
617
756
  return getResumeUrls(approver);
618
757
  }
619
- exports.getResumeEndpoints = getResumeEndpoints;
620
758
  /**
621
759
  * Get an OIDC jwt token for auth to external services (e.g: Vault, AWS) (ee only)
622
760
  * @param audience audience of the token
@@ -631,11 +769,9 @@ function getIdToken(audience) {
631
769
  });
632
770
  });
633
771
  }
634
- exports.getIdToken = getIdToken;
635
772
  function base64ToUint8Array(data) {
636
773
  return Uint8Array.from(atob(data), (c) => c.charCodeAt(0));
637
774
  }
638
- exports.base64ToUint8Array = base64ToUint8Array;
639
775
  function uint8ArrayToBase64(arrayBuffer) {
640
776
  let base64 = "";
641
777
  const encodings = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@@ -675,7 +811,6 @@ function uint8ArrayToBase64(arrayBuffer) {
675
811
  }
676
812
  return base64;
677
813
  }
678
- exports.uint8ArrayToBase64 = uint8ArrayToBase64;
679
814
  /**
680
815
  * Get email from workspace username
681
816
  * This method is particularly useful for apps that require the email address of the viewer.
@@ -689,4 +824,107 @@ function usernameToEmail(username) {
689
824
  return yield index_1.UserService.usernameToEmail({ username, workspace });
690
825
  });
691
826
  }
692
- exports.usernameToEmail = usernameToEmail;
827
+ /**
828
+ * Sends an interactive approval request via Slack, allowing optional customization of the message, approver, and form fields.
829
+ *
830
+ * **[Enterprise Edition Only]** To include form fields in the Slack approval request, go to **Advanced -> Suspend -> Form**
831
+ * and define a form. Learn more at [Windmill Documentation](https://www.windmill.dev/docs/flows/flow_approval#form).
832
+ *
833
+ * @param {Object} options - The configuration options for the Slack approval request.
834
+ * @param {string} options.slackResourcePath - The path to the Slack resource in Windmill.
835
+ * @param {string} options.channelId - The Slack channel ID where the approval request will be sent.
836
+ * @param {string} [options.message] - Optional custom message to include in the Slack approval request.
837
+ * @param {string} [options.approver] - Optional user ID or name of the approver for the request.
838
+ * @param {DefaultArgs} [options.defaultArgsJson] - Optional object defining or overriding the default arguments to a form field.
839
+ * @param {Enums} [options.dynamicEnumsJson] - Optional object overriding the enum default values of an enum form field.
840
+ *
841
+ * @returns {Promise<void>} Resolves when the Slack approval request is successfully sent.
842
+ *
843
+ * @throws {Error} If the function is not called within a flow or flow preview.
844
+ * @throws {Error} If the `JobService.getSlackApprovalPayload` call fails.
845
+ *
846
+ * **Usage Example:**
847
+ * ```typescript
848
+ * await requestInteractiveSlackApproval({
849
+ * slackResourcePath: "/u/alex/my_slack_resource",
850
+ * channelId: "admins-slack-channel",
851
+ * message: "Please approve this request",
852
+ * approver: "approver123",
853
+ * defaultArgsJson: { key1: "value1", key2: 42 },
854
+ * dynamicEnumsJson: { foo: ["choice1", "choice2"], bar: ["optionA", "optionB"] },
855
+ * });
856
+ * ```
857
+ *
858
+ * **Note:** This function requires execution within a Windmill flow or flow preview.
859
+ */
860
+ function requestInteractiveSlackApproval(_a) {
861
+ return __awaiter(this, arguments, void 0, function* ({ slackResourcePath, channelId, message, approver, defaultArgsJson, dynamicEnumsJson, }) {
862
+ var _b;
863
+ const workspace = getWorkspace();
864
+ const flowJobId = getEnv("WM_FLOW_JOB_ID");
865
+ if (!flowJobId) {
866
+ throw new Error("You can't use this function in a standalone script or flow step preview. Please use it in a flow or a flow preview.");
867
+ }
868
+ const flowStepId = getEnv("WM_FLOW_STEP_ID");
869
+ if (!flowStepId) {
870
+ throw new Error("This function can only be called as a flow step");
871
+ }
872
+ // Only include non-empty parameters
873
+ const params = {
874
+ slackResourcePath,
875
+ channelId,
876
+ flowStepId,
877
+ };
878
+ if (message) {
879
+ params.message = message;
880
+ }
881
+ if (approver) {
882
+ params.approver = approver;
883
+ }
884
+ if (defaultArgsJson) {
885
+ params.defaultArgsJson = JSON.stringify(defaultArgsJson);
886
+ }
887
+ if (dynamicEnumsJson) {
888
+ params.dynamicEnumsJson = JSON.stringify(dynamicEnumsJson);
889
+ }
890
+ yield index_1.JobService.getSlackApprovalPayload(Object.assign(Object.assign({ workspace }, params), { id: (_b = getEnv("WM_JOB_ID")) !== null && _b !== void 0 ? _b : "NO_JOB_ID" }));
891
+ });
892
+ }
893
+ function getMockedApi() {
894
+ return __awaiter(this, void 0, void 0, function* () {
895
+ const mockedPath = getEnv("WM_MOCKED_API_FILE");
896
+ if (mockedApi) {
897
+ return mockedApi;
898
+ }
899
+ if (mockedPath) {
900
+ console.info("Using mocked API from", mockedPath);
901
+ }
902
+ const path = getEnv("WM_MOCKED_API_FILE");
903
+ if (!path) {
904
+ console.warn("No mocked API file path provided at env variable WM_MOCKED_API_FILE");
905
+ return undefined;
906
+ }
907
+ try {
908
+ const fs = yield Promise.resolve().then(() => require("node:fs/promises"));
909
+ const file = yield fs.readFile(path, "utf-8");
910
+ try {
911
+ mockedApi = JSON.parse(file);
912
+ if (!mockedApi.variables) {
913
+ mockedApi.variables = {};
914
+ }
915
+ if (!mockedApi.resources) {
916
+ mockedApi.resources = {};
917
+ }
918
+ return mockedApi;
919
+ }
920
+ catch (_a) {
921
+ console.warn("Error parsing mocked API file at path", path);
922
+ return undefined;
923
+ }
924
+ }
925
+ catch (_b) {
926
+ console.warn("Error reading mocked API file at path", path);
927
+ return undefined;
928
+ }
929
+ });
930
+ }