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 +59 -2
- package/dist/client.js +274 -36
- package/dist/core/OpenAPI.js +7 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +6 -1
- package/dist/services.gen.d.ts +1085 -36
- package/dist/services.gen.js +2261 -128
- package/dist/types.gen.d.ts +6497 -2981
- package/package.json +1 -1
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
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
+
}
|