@uipath/tasks-tool 1.201.0-preview.115 → 1.201.0-preview.121
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/browser.json +2 -1
- package/dist/folder-picker-interactive-2kj361mt.js +1850 -0
- package/dist/folder-resolver-htdmzdhy.js +92 -0
- package/dist/index.js +5 -3
- package/dist/tool-0n9mj887.js +2448 -0
- package/dist/tool-rsk1xt86.js +6026 -0
- package/dist/{tool-vw6gha5d.js → tool-ww671age.js} +7469 -10469
- package/dist/tool.js +3 -2
- package/package.json +2 -2
- package/src/commands/_shared/catalog-options.spec.ts +114 -0
- package/src/commands/_shared/catalog-options.ts +122 -0
- package/src/commands/_shared/connect.spec.ts +52 -0
- package/src/commands/_shared/connect.ts +31 -0
- package/src/commands/_shared/constants.ts +1 -0
- package/src/commands/_shared/folder-picker-interactive.spec.ts +92 -0
- package/src/commands/_shared/folder-picker-interactive.ts +76 -0
- package/src/commands/_shared/folder-picker.spec.ts +159 -0
- package/src/commands/_shared/folder-picker.ts +113 -0
- package/src/commands/_shared/folder-resolver.spec.ts +152 -0
- package/src/commands/_shared/folder-resolver.ts +113 -0
- package/src/commands/_shared/parse.spec.ts +69 -0
- package/src/commands/_shared/parse.ts +43 -0
- package/src/commands/catalogs.ts +277 -0
- package/src/commands/comments.ts +160 -0
- package/src/commands/data.ts +137 -0
- package/src/commands/labels.ts +93 -0
- package/src/commands/metadata.ts +139 -0
- package/src/commands/tasks.spec.ts +1557 -2
- package/src/commands/tasks.ts +191 -280
- package/src/tool.ts +10 -0
- package/src/utils/sdk-client.ts +5 -0
- package/tests/assignable-users.e2e.test.ts +58 -4
- package/tests/catalogs.e2e.test.ts +393 -0
- package/tests/comments.e2e.test.ts +223 -0
- package/tests/complete.e2e.test.ts +9 -9
- package/tests/data.e2e.test.ts +187 -0
- package/tests/get.e2e.test.ts +4 -2
- package/tests/labels.e2e.test.ts +184 -0
- package/tests/list.e2e.test.ts +110 -0
- package/tests/metadata.e2e.test.ts +186 -0
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import {
|
|
2
|
+
catchError,
|
|
3
|
+
extractErrorMessage,
|
|
4
|
+
OutputFormatter,
|
|
5
|
+
processContext,
|
|
6
|
+
RESULTS,
|
|
7
|
+
} from "@uipath/common";
|
|
8
|
+
import type { Command } from "commander";
|
|
9
|
+
|
|
10
|
+
import { createTaskCatalogsClient } from "../utils/sdk-client";
|
|
11
|
+
import {
|
|
12
|
+
buildCatalogCreateOptions,
|
|
13
|
+
buildCatalogUpdateOptions,
|
|
14
|
+
type CatalogCreateOptions,
|
|
15
|
+
type CatalogGetOptions,
|
|
16
|
+
type CatalogListOptions,
|
|
17
|
+
type CatalogUpdateOptions,
|
|
18
|
+
} from "./_shared/catalog-options";
|
|
19
|
+
import { connectTasksClient } from "./_shared/connect";
|
|
20
|
+
import { DEFAULT_PAGE_SIZE } from "./_shared/constants";
|
|
21
|
+
import {
|
|
22
|
+
addFolderScopeOptions,
|
|
23
|
+
resolveFolderId,
|
|
24
|
+
} from "./_shared/folder-picker";
|
|
25
|
+
import { parseIntArg } from "./_shared/parse";
|
|
26
|
+
|
|
27
|
+
export const registerCatalogsCommand = (program: Command) => {
|
|
28
|
+
const catalogs = program
|
|
29
|
+
.command("catalogs")
|
|
30
|
+
.description("Manage task catalogs");
|
|
31
|
+
|
|
32
|
+
addFolderScopeOptions(
|
|
33
|
+
catalogs.command("list").description("List task catalogs in a folder"),
|
|
34
|
+
)
|
|
35
|
+
.option(
|
|
36
|
+
"-l, --limit <number>",
|
|
37
|
+
"Maximum number of items to return (fetches all if omitted)",
|
|
38
|
+
)
|
|
39
|
+
.trackedAction(processContext, async (options: CatalogListOptions) => {
|
|
40
|
+
const sdk = await connectTasksClient();
|
|
41
|
+
if (!sdk) return;
|
|
42
|
+
|
|
43
|
+
const folderId = await resolveFolderId(options);
|
|
44
|
+
if (folderId === null) return;
|
|
45
|
+
|
|
46
|
+
let limit: number | undefined;
|
|
47
|
+
if (options.limit) {
|
|
48
|
+
const parsed = parseIntArg(options.limit, "--limit");
|
|
49
|
+
if (parsed === null) return;
|
|
50
|
+
limit = parsed;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const taskCatalogs = createTaskCatalogsClient(sdk);
|
|
54
|
+
const allItems: unknown[] = [];
|
|
55
|
+
let cursor: { value: string } | undefined;
|
|
56
|
+
|
|
57
|
+
do {
|
|
58
|
+
const getOptions: Record<string, unknown> = {
|
|
59
|
+
folderId,
|
|
60
|
+
pageSize: DEFAULT_PAGE_SIZE,
|
|
61
|
+
};
|
|
62
|
+
if (cursor) {
|
|
63
|
+
getOptions.cursor = cursor;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const [listError, result] = await catchError(
|
|
67
|
+
taskCatalogs.getAll(getOptions),
|
|
68
|
+
);
|
|
69
|
+
if (listError) {
|
|
70
|
+
OutputFormatter.error({
|
|
71
|
+
Result: RESULTS.Failure,
|
|
72
|
+
Message: "Error listing task catalogs",
|
|
73
|
+
Instructions: await extractErrorMessage(listError),
|
|
74
|
+
});
|
|
75
|
+
processContext.exit(1);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (Array.isArray(result)) {
|
|
80
|
+
allItems.push(...result);
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const page = result as unknown as Record<string, unknown>;
|
|
85
|
+
allItems.push(...((page.items ?? []) as unknown[]));
|
|
86
|
+
cursor = page.hasNextPage
|
|
87
|
+
? (page.nextCursor as { value: string })
|
|
88
|
+
: undefined;
|
|
89
|
+
|
|
90
|
+
if (limit && allItems.length >= limit) {
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
} while (cursor);
|
|
94
|
+
|
|
95
|
+
OutputFormatter.success({
|
|
96
|
+
Result: RESULTS.Success,
|
|
97
|
+
Code: "TaskCatalogList",
|
|
98
|
+
Data: limit ? allItems.slice(0, limit) : allItems,
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
addFolderScopeOptions(
|
|
103
|
+
catalogs
|
|
104
|
+
.command("get")
|
|
105
|
+
.description("Get a task catalog by ID")
|
|
106
|
+
.argument("<id>", "Task catalog ID"),
|
|
107
|
+
).trackedAction(
|
|
108
|
+
processContext,
|
|
109
|
+
async (id: string, options: CatalogGetOptions) => {
|
|
110
|
+
const sdk = await connectTasksClient();
|
|
111
|
+
if (!sdk) return;
|
|
112
|
+
|
|
113
|
+
const parsedId = parseIntArg(id, "<id>");
|
|
114
|
+
if (parsedId === null) return;
|
|
115
|
+
|
|
116
|
+
const folderId = await resolveFolderId(options);
|
|
117
|
+
if (folderId === null) return;
|
|
118
|
+
|
|
119
|
+
const taskCatalogs = createTaskCatalogsClient(sdk);
|
|
120
|
+
const [getError, catalog] = await catchError(
|
|
121
|
+
taskCatalogs.getById(parsedId, { folderId }),
|
|
122
|
+
);
|
|
123
|
+
if (getError) {
|
|
124
|
+
OutputFormatter.error({
|
|
125
|
+
Result: RESULTS.Failure,
|
|
126
|
+
Message: `Error getting task catalog '${id}'`,
|
|
127
|
+
Instructions: await extractErrorMessage(getError),
|
|
128
|
+
});
|
|
129
|
+
processContext.exit(1);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
OutputFormatter.success({
|
|
134
|
+
Result: RESULTS.Success,
|
|
135
|
+
Code: "TaskCatalogDetails",
|
|
136
|
+
Data: catalog,
|
|
137
|
+
});
|
|
138
|
+
},
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
addFolderScopeOptions(
|
|
142
|
+
catalogs
|
|
143
|
+
.command("create")
|
|
144
|
+
.description("Create a task catalog in a folder")
|
|
145
|
+
.requiredOption("--name <name>", "Catalog name (required)"),
|
|
146
|
+
)
|
|
147
|
+
.option("--description <text>", "Catalog description")
|
|
148
|
+
.option("--encrypted", "Encrypt the data of tasks in this catalog")
|
|
149
|
+
.option(
|
|
150
|
+
"--retention-action <action>",
|
|
151
|
+
"Action at the retention limit (Delete, Archive)",
|
|
152
|
+
)
|
|
153
|
+
.option("--retention-period <days>", "Retention period in days")
|
|
154
|
+
.option(
|
|
155
|
+
"--retention-bucket-id <id>",
|
|
156
|
+
"Storage bucket ID (used when retention action is Archive)",
|
|
157
|
+
)
|
|
158
|
+
.trackedAction(
|
|
159
|
+
processContext,
|
|
160
|
+
async (options: CatalogCreateOptions) => {
|
|
161
|
+
const sdk = await connectTasksClient();
|
|
162
|
+
if (!sdk) return;
|
|
163
|
+
|
|
164
|
+
const folderId = await resolveFolderId(options);
|
|
165
|
+
if (folderId === null) return;
|
|
166
|
+
|
|
167
|
+
const writeOptions = buildCatalogCreateOptions(
|
|
168
|
+
options,
|
|
169
|
+
folderId,
|
|
170
|
+
);
|
|
171
|
+
if (!writeOptions) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const taskCatalogs = createTaskCatalogsClient(sdk);
|
|
176
|
+
const [createError, catalog] = await catchError(
|
|
177
|
+
taskCatalogs.create(options.name, writeOptions),
|
|
178
|
+
);
|
|
179
|
+
if (createError) {
|
|
180
|
+
OutputFormatter.error({
|
|
181
|
+
Result: RESULTS.Failure,
|
|
182
|
+
Message: `Error creating task catalog '${options.name}'`,
|
|
183
|
+
Instructions: await extractErrorMessage(createError),
|
|
184
|
+
});
|
|
185
|
+
processContext.exit(1);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
OutputFormatter.success({
|
|
190
|
+
Result: RESULTS.Success,
|
|
191
|
+
Code: "TaskCatalogCreated",
|
|
192
|
+
Data: catalog,
|
|
193
|
+
});
|
|
194
|
+
},
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
addFolderScopeOptions(
|
|
198
|
+
catalogs
|
|
199
|
+
.command("update")
|
|
200
|
+
.description("Update a task catalog")
|
|
201
|
+
.argument("<id>", "Task catalog ID"),
|
|
202
|
+
)
|
|
203
|
+
.option("--name <name>", "New catalog name")
|
|
204
|
+
.option("--description <text>", "Catalog description")
|
|
205
|
+
.option(
|
|
206
|
+
"--retention-action <action>",
|
|
207
|
+
"Action at the retention limit (Delete, Archive)",
|
|
208
|
+
)
|
|
209
|
+
.option("--retention-period <days>", "Retention period in days")
|
|
210
|
+
.option(
|
|
211
|
+
"--retention-bucket-id <id>",
|
|
212
|
+
"Storage bucket ID (used when retention action is Archive)",
|
|
213
|
+
)
|
|
214
|
+
.trackedAction(
|
|
215
|
+
processContext,
|
|
216
|
+
async (id: string, options: CatalogUpdateOptions) => {
|
|
217
|
+
const sdk = await connectTasksClient();
|
|
218
|
+
if (!sdk) return;
|
|
219
|
+
|
|
220
|
+
const parsedId = parseIntArg(id, "<id>");
|
|
221
|
+
if (parsedId === null) return;
|
|
222
|
+
|
|
223
|
+
const hasUpdate =
|
|
224
|
+
options.name !== undefined ||
|
|
225
|
+
options.description !== undefined ||
|
|
226
|
+
options.retentionAction !== undefined ||
|
|
227
|
+
options.retentionPeriod !== undefined ||
|
|
228
|
+
options.retentionBucketId !== undefined;
|
|
229
|
+
if (!hasUpdate) {
|
|
230
|
+
OutputFormatter.error({
|
|
231
|
+
Result: RESULTS.Failure,
|
|
232
|
+
Message: "No catalog changes provided",
|
|
233
|
+
Instructions:
|
|
234
|
+
"Pass at least one of --name, --description, --retention-action, --retention-period, or --retention-bucket-id.",
|
|
235
|
+
});
|
|
236
|
+
processContext.exit(1);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const folderId = await resolveFolderId(options);
|
|
241
|
+
if (folderId === null) return;
|
|
242
|
+
|
|
243
|
+
const writeOptions = buildCatalogUpdateOptions(
|
|
244
|
+
options,
|
|
245
|
+
folderId,
|
|
246
|
+
);
|
|
247
|
+
if (!writeOptions) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const taskCatalogs = createTaskCatalogsClient(sdk);
|
|
252
|
+
const [updateError] = await catchError(
|
|
253
|
+
taskCatalogs.updateById(parsedId, writeOptions),
|
|
254
|
+
);
|
|
255
|
+
if (updateError) {
|
|
256
|
+
OutputFormatter.error({
|
|
257
|
+
Result: RESULTS.Failure,
|
|
258
|
+
Message: `Error updating task catalog '${id}'`,
|
|
259
|
+
Instructions: await extractErrorMessage(updateError),
|
|
260
|
+
});
|
|
261
|
+
processContext.exit(1);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
OutputFormatter.success({
|
|
266
|
+
Result: RESULTS.Success,
|
|
267
|
+
Code: "TaskCatalogUpdated",
|
|
268
|
+
Data: {
|
|
269
|
+
id: parsedId,
|
|
270
|
+
...(options.name !== undefined
|
|
271
|
+
? { name: options.name }
|
|
272
|
+
: {}),
|
|
273
|
+
},
|
|
274
|
+
});
|
|
275
|
+
},
|
|
276
|
+
);
|
|
277
|
+
};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import {
|
|
2
|
+
catchError,
|
|
3
|
+
extractErrorMessage,
|
|
4
|
+
OutputFormatter,
|
|
5
|
+
processContext,
|
|
6
|
+
RESULTS,
|
|
7
|
+
} from "@uipath/common";
|
|
8
|
+
import type { Command } from "commander";
|
|
9
|
+
|
|
10
|
+
import { connectTasksClient } from "./_shared/connect";
|
|
11
|
+
import { DEFAULT_PAGE_SIZE } from "./_shared/constants";
|
|
12
|
+
import {
|
|
13
|
+
addFolderScopeOptions,
|
|
14
|
+
type FolderScopeOptions,
|
|
15
|
+
resolveFolderId,
|
|
16
|
+
} from "./_shared/folder-picker";
|
|
17
|
+
import { parseIntArg } from "./_shared/parse";
|
|
18
|
+
|
|
19
|
+
interface CommentListOptions extends FolderScopeOptions {
|
|
20
|
+
limit?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface CommentCreateOptions extends FolderScopeOptions {
|
|
24
|
+
text: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const registerCommentsCommand = (program: Command) => {
|
|
28
|
+
const comments = program
|
|
29
|
+
.command("comments")
|
|
30
|
+
.description("Manage task comments");
|
|
31
|
+
|
|
32
|
+
addFolderScopeOptions(
|
|
33
|
+
comments
|
|
34
|
+
.command("list")
|
|
35
|
+
.description("List the comments on a task")
|
|
36
|
+
.argument("<task-id>", "Task ID"),
|
|
37
|
+
)
|
|
38
|
+
.option(
|
|
39
|
+
"-l, --limit <number>",
|
|
40
|
+
"Maximum number of items to return (fetches all if omitted)",
|
|
41
|
+
)
|
|
42
|
+
.trackedAction(
|
|
43
|
+
processContext,
|
|
44
|
+
async (taskId: string, options: CommentListOptions) => {
|
|
45
|
+
const sdk = await connectTasksClient();
|
|
46
|
+
if (!sdk) return;
|
|
47
|
+
|
|
48
|
+
const parsedTaskId = parseIntArg(taskId, "<task-id>");
|
|
49
|
+
if (parsedTaskId === null) return;
|
|
50
|
+
|
|
51
|
+
const folderId = await resolveFolderId(options);
|
|
52
|
+
if (folderId === null) return;
|
|
53
|
+
|
|
54
|
+
let limit: number | undefined;
|
|
55
|
+
if (options.limit) {
|
|
56
|
+
const parsed = parseIntArg(options.limit, "--limit");
|
|
57
|
+
if (parsed === null) return;
|
|
58
|
+
limit = parsed;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const allItems: unknown[] = [];
|
|
62
|
+
let cursor: { value: string } | undefined;
|
|
63
|
+
|
|
64
|
+
do {
|
|
65
|
+
const getOptions: Record<string, unknown> = {
|
|
66
|
+
folderId,
|
|
67
|
+
pageSize: DEFAULT_PAGE_SIZE,
|
|
68
|
+
};
|
|
69
|
+
if (cursor) {
|
|
70
|
+
getOptions.cursor = cursor;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const [listError, result] = await catchError(
|
|
74
|
+
sdk.tasks.getComments(parsedTaskId, getOptions),
|
|
75
|
+
);
|
|
76
|
+
if (listError) {
|
|
77
|
+
OutputFormatter.error({
|
|
78
|
+
Result: RESULTS.Failure,
|
|
79
|
+
Message: "Error listing task comments",
|
|
80
|
+
Instructions: await extractErrorMessage(listError),
|
|
81
|
+
});
|
|
82
|
+
processContext.exit(1);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (Array.isArray(result)) {
|
|
87
|
+
allItems.push(...result);
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const page = result as unknown as Record<string, unknown>;
|
|
92
|
+
allItems.push(...((page.items ?? []) as unknown[]));
|
|
93
|
+
cursor = page.hasNextPage
|
|
94
|
+
? (page.nextCursor as { value: string })
|
|
95
|
+
: undefined;
|
|
96
|
+
|
|
97
|
+
if (limit && allItems.length >= limit) {
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
} while (cursor);
|
|
101
|
+
|
|
102
|
+
OutputFormatter.success({
|
|
103
|
+
Result: RESULTS.Success,
|
|
104
|
+
Code: "TaskCommentList",
|
|
105
|
+
Data: limit ? allItems.slice(0, limit) : allItems,
|
|
106
|
+
});
|
|
107
|
+
},
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
addFolderScopeOptions(
|
|
111
|
+
comments
|
|
112
|
+
.command("add")
|
|
113
|
+
.description("Add a comment to a task")
|
|
114
|
+
.argument("<task-id>", "Task ID")
|
|
115
|
+
.requiredOption("--text <text>", "Comment text (required)"),
|
|
116
|
+
).trackedAction(
|
|
117
|
+
processContext,
|
|
118
|
+
async (taskId: string, options: CommentCreateOptions) => {
|
|
119
|
+
const sdk = await connectTasksClient();
|
|
120
|
+
if (!sdk) return;
|
|
121
|
+
|
|
122
|
+
const parsedTaskId = parseIntArg(taskId, "<task-id>");
|
|
123
|
+
if (parsedTaskId === null) return;
|
|
124
|
+
|
|
125
|
+
const folderId = await resolveFolderId(options);
|
|
126
|
+
if (folderId === null) return;
|
|
127
|
+
|
|
128
|
+
if (!options.text) {
|
|
129
|
+
OutputFormatter.error({
|
|
130
|
+
Result: RESULTS.Failure,
|
|
131
|
+
Message: "--text cannot be empty",
|
|
132
|
+
Instructions: "Provide comment text with --text <text>.",
|
|
133
|
+
});
|
|
134
|
+
processContext.exit(1);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const [createError, comment] = await catchError(
|
|
139
|
+
sdk.tasks.createComment(parsedTaskId, options.text, {
|
|
140
|
+
folderId,
|
|
141
|
+
}),
|
|
142
|
+
);
|
|
143
|
+
if (createError) {
|
|
144
|
+
OutputFormatter.error({
|
|
145
|
+
Result: RESULTS.Failure,
|
|
146
|
+
Message: `Error adding comment to task '${taskId}'`,
|
|
147
|
+
Instructions: await extractErrorMessage(createError),
|
|
148
|
+
});
|
|
149
|
+
processContext.exit(1);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
OutputFormatter.success({
|
|
154
|
+
Result: RESULTS.Success,
|
|
155
|
+
Code: "TaskCommentCreated",
|
|
156
|
+
Data: comment,
|
|
157
|
+
});
|
|
158
|
+
},
|
|
159
|
+
);
|
|
160
|
+
};
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import {
|
|
2
|
+
catchError,
|
|
3
|
+
extractErrorMessage,
|
|
4
|
+
extractErrorMessageSync,
|
|
5
|
+
OutputFormatter,
|
|
6
|
+
processContext,
|
|
7
|
+
RESULTS,
|
|
8
|
+
} from "@uipath/common";
|
|
9
|
+
import type { Command } from "commander";
|
|
10
|
+
|
|
11
|
+
import { connectTasksClient } from "./_shared/connect";
|
|
12
|
+
import {
|
|
13
|
+
addFolderScopeOptions,
|
|
14
|
+
type FolderScopeOptions,
|
|
15
|
+
resolveFolderId,
|
|
16
|
+
} from "./_shared/folder-picker";
|
|
17
|
+
import { parseIntArg } from "./_shared/parse";
|
|
18
|
+
|
|
19
|
+
type DataGetOptions = FolderScopeOptions;
|
|
20
|
+
|
|
21
|
+
interface DataSaveOptions extends FolderScopeOptions {
|
|
22
|
+
data: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const registerDataCommand = (program: Command) => {
|
|
26
|
+
const data = program.command("data").description("Manage task data");
|
|
27
|
+
|
|
28
|
+
addFolderScopeOptions(
|
|
29
|
+
data
|
|
30
|
+
.command("get")
|
|
31
|
+
.description("Get a task's data")
|
|
32
|
+
.argument("<task-id>", "Task ID"),
|
|
33
|
+
).trackedAction(
|
|
34
|
+
processContext,
|
|
35
|
+
async (taskId: string, options: DataGetOptions) => {
|
|
36
|
+
const sdk = await connectTasksClient();
|
|
37
|
+
if (!sdk) return;
|
|
38
|
+
|
|
39
|
+
const parsedTaskId = parseIntArg(taskId, "<task-id>");
|
|
40
|
+
if (parsedTaskId === null) return;
|
|
41
|
+
|
|
42
|
+
const folderId = await resolveFolderId(options);
|
|
43
|
+
if (folderId === null) return;
|
|
44
|
+
|
|
45
|
+
const [getError, task] = await catchError(
|
|
46
|
+
sdk.tasks.getDataById(parsedTaskId, { folderId }),
|
|
47
|
+
);
|
|
48
|
+
if (getError) {
|
|
49
|
+
OutputFormatter.error({
|
|
50
|
+
Result: RESULTS.Failure,
|
|
51
|
+
Message: `Error getting data for task '${taskId}'`,
|
|
52
|
+
Instructions: await extractErrorMessage(getError),
|
|
53
|
+
});
|
|
54
|
+
processContext.exit(1);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
OutputFormatter.success({
|
|
59
|
+
Result: RESULTS.Success,
|
|
60
|
+
Code: "TaskData",
|
|
61
|
+
Data: task,
|
|
62
|
+
});
|
|
63
|
+
},
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
addFolderScopeOptions(
|
|
67
|
+
data
|
|
68
|
+
.command("save")
|
|
69
|
+
.description("Save a task's data")
|
|
70
|
+
.argument("<task-id>", "Task ID")
|
|
71
|
+
.requiredOption("--data <json>", "Task data as a JSON object"),
|
|
72
|
+
).trackedAction(
|
|
73
|
+
processContext,
|
|
74
|
+
async (taskId: string, options: DataSaveOptions) => {
|
|
75
|
+
const sdk = await connectTasksClient();
|
|
76
|
+
if (!sdk) return;
|
|
77
|
+
|
|
78
|
+
const parsedTaskId = parseIntArg(taskId, "<task-id>");
|
|
79
|
+
if (parsedTaskId === null) return;
|
|
80
|
+
|
|
81
|
+
const folderId = await resolveFolderId(options);
|
|
82
|
+
if (folderId === null) return;
|
|
83
|
+
|
|
84
|
+
const [parseError, parsedData] = await catchError(
|
|
85
|
+
Promise.resolve().then(
|
|
86
|
+
() => JSON.parse(options.data) as unknown,
|
|
87
|
+
),
|
|
88
|
+
);
|
|
89
|
+
if (parseError) {
|
|
90
|
+
OutputFormatter.error({
|
|
91
|
+
Result: RESULTS.Failure,
|
|
92
|
+
Message: "Invalid JSON in --data",
|
|
93
|
+
Instructions: extractErrorMessageSync(parseError),
|
|
94
|
+
});
|
|
95
|
+
processContext.exit(1);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (
|
|
99
|
+
typeof parsedData !== "object" ||
|
|
100
|
+
parsedData === null ||
|
|
101
|
+
Array.isArray(parsedData)
|
|
102
|
+
) {
|
|
103
|
+
OutputFormatter.error({
|
|
104
|
+
Result: RESULTS.Failure,
|
|
105
|
+
Message: "--data must be a JSON object",
|
|
106
|
+
Instructions:
|
|
107
|
+
'Provide a JSON object, e.g. \'{"field":"value"}\'.',
|
|
108
|
+
});
|
|
109
|
+
processContext.exit(1);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const [saveError] = await catchError(
|
|
114
|
+
sdk.tasks.saveData(
|
|
115
|
+
parsedTaskId,
|
|
116
|
+
parsedData as Record<string, unknown>,
|
|
117
|
+
{ folderId },
|
|
118
|
+
),
|
|
119
|
+
);
|
|
120
|
+
if (saveError) {
|
|
121
|
+
OutputFormatter.error({
|
|
122
|
+
Result: RESULTS.Failure,
|
|
123
|
+
Message: `Error saving data for task '${taskId}'`,
|
|
124
|
+
Instructions: await extractErrorMessage(saveError),
|
|
125
|
+
});
|
|
126
|
+
processContext.exit(1);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
OutputFormatter.success({
|
|
131
|
+
Result: RESULTS.Success,
|
|
132
|
+
Code: "TaskDataSaved",
|
|
133
|
+
Data: { taskId: parsedTaskId },
|
|
134
|
+
});
|
|
135
|
+
},
|
|
136
|
+
);
|
|
137
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import {
|
|
2
|
+
catchError,
|
|
3
|
+
extractErrorMessage,
|
|
4
|
+
extractErrorMessageSync,
|
|
5
|
+
OutputFormatter,
|
|
6
|
+
processContext,
|
|
7
|
+
RESULTS,
|
|
8
|
+
} from "@uipath/common";
|
|
9
|
+
import type { Tag } from "@uipath/uipath-typescript";
|
|
10
|
+
import type { Command } from "commander";
|
|
11
|
+
|
|
12
|
+
import { connectTasksClient } from "./_shared/connect";
|
|
13
|
+
import {
|
|
14
|
+
addFolderScopeOptions,
|
|
15
|
+
type FolderScopeOptions,
|
|
16
|
+
resolveFolderId,
|
|
17
|
+
} from "./_shared/folder-picker";
|
|
18
|
+
import { parseIntArg } from "./_shared/parse";
|
|
19
|
+
|
|
20
|
+
interface LabelsOptions extends FolderScopeOptions {
|
|
21
|
+
labels: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const registerLabelsCommand = (program: Command) => {
|
|
25
|
+
addFolderScopeOptions(
|
|
26
|
+
program
|
|
27
|
+
.command("labels")
|
|
28
|
+
.description("Set or clear the labels on a task")
|
|
29
|
+
.argument("<task-id>", "Task ID")
|
|
30
|
+
.requiredOption(
|
|
31
|
+
"--labels <json>",
|
|
32
|
+
'Labels as a JSON array, e.g. \'[{"name":"region","displayName":"Region","displayValue":"EMEA"}]\' (use \'[]\' to clear)',
|
|
33
|
+
),
|
|
34
|
+
).trackedAction(
|
|
35
|
+
processContext,
|
|
36
|
+
async (taskId: string, options: LabelsOptions) => {
|
|
37
|
+
const sdk = await connectTasksClient();
|
|
38
|
+
if (!sdk) return;
|
|
39
|
+
|
|
40
|
+
const parsedTaskId = parseIntArg(taskId, "<task-id>");
|
|
41
|
+
if (parsedTaskId === null) return;
|
|
42
|
+
|
|
43
|
+
const folderId = await resolveFolderId(options);
|
|
44
|
+
if (folderId === null) return;
|
|
45
|
+
|
|
46
|
+
const [parseError, parsedLabels] = await catchError(
|
|
47
|
+
Promise.resolve().then(
|
|
48
|
+
() => JSON.parse(options.labels) as unknown,
|
|
49
|
+
),
|
|
50
|
+
);
|
|
51
|
+
if (parseError) {
|
|
52
|
+
OutputFormatter.error({
|
|
53
|
+
Result: RESULTS.Failure,
|
|
54
|
+
Message: "Invalid JSON in --labels",
|
|
55
|
+
Instructions: extractErrorMessageSync(parseError),
|
|
56
|
+
});
|
|
57
|
+
processContext.exit(1);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (!Array.isArray(parsedLabels)) {
|
|
61
|
+
OutputFormatter.error({
|
|
62
|
+
Result: RESULTS.Failure,
|
|
63
|
+
Message: "--labels must be a JSON array",
|
|
64
|
+
Instructions:
|
|
65
|
+
'Provide a JSON array of labels, e.g. \'[{"name":"region","displayName":"Region","displayValue":"EMEA"}]\'.',
|
|
66
|
+
});
|
|
67
|
+
processContext.exit(1);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const [saveError] = await catchError(
|
|
72
|
+
sdk.tasks.saveTags(parsedTaskId, parsedLabels as Tag[], {
|
|
73
|
+
folderId,
|
|
74
|
+
}),
|
|
75
|
+
);
|
|
76
|
+
if (saveError) {
|
|
77
|
+
OutputFormatter.error({
|
|
78
|
+
Result: RESULTS.Failure,
|
|
79
|
+
Message: `Error saving labels on task '${taskId}'`,
|
|
80
|
+
Instructions: await extractErrorMessage(saveError),
|
|
81
|
+
});
|
|
82
|
+
processContext.exit(1);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
OutputFormatter.success({
|
|
87
|
+
Result: RESULTS.Success,
|
|
88
|
+
Code: "TaskLabelsSaved",
|
|
89
|
+
Data: { taskId: parsedTaskId, labels: parsedLabels },
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
);
|
|
93
|
+
};
|