@uipath/data-fabric-tool 1.1.0 → 1.195.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/tool.js +1638 -1164
- package/package.json +16 -24
- package/src/commands/choice-sets.spec.ts +538 -83
- package/src/commands/choice-sets.ts +550 -146
- package/src/commands/entities.spec.ts +58 -145
- package/src/commands/entities.ts +160 -367
- package/src/commands/files.spec.ts +18 -32
- package/src/commands/files.ts +33 -89
- package/src/commands/records.spec.ts +102 -207
- package/src/commands/records.ts +112 -328
- package/src/tool.ts +5 -1
- package/src/utils/output.spec.ts +78 -0
- package/src/utils/output.ts +51 -0
- package/src/utils/sdk-client.spec.ts +59 -0
- package/src/utils/sdk-client.ts +23 -0
- package/src/utils/pagination.ts +0 -10
|
@@ -1,14 +1,32 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type CommandExample,
|
|
3
3
|
catchError,
|
|
4
|
+
createHiddenDeprecatedTenantOption,
|
|
4
5
|
extractErrorMessage,
|
|
5
6
|
OutputFormatter,
|
|
6
7
|
processContext,
|
|
7
8
|
RESULTS,
|
|
8
9
|
} from "@uipath/common";
|
|
10
|
+
import type {
|
|
11
|
+
ChoiceSetCreateOptions,
|
|
12
|
+
ChoiceSetServiceModel,
|
|
13
|
+
ChoiceSetUpdateOptions,
|
|
14
|
+
ChoiceSetValueInsertOptions,
|
|
15
|
+
} from "@uipath/uipath-typescript";
|
|
9
16
|
import type { Command } from "commander";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
17
|
+
import { fail, requireDestructiveConfirmation } from "../utils/output";
|
|
18
|
+
import { connectOrFail } from "../utils/sdk-client";
|
|
19
|
+
|
|
20
|
+
const OUTPUT_CODES = {
|
|
21
|
+
ChoiceSetList: "ChoiceSetList",
|
|
22
|
+
ChoiceSetValues: "ChoiceSetValues",
|
|
23
|
+
ChoiceSetCreated: "ChoiceSetCreated",
|
|
24
|
+
ChoiceSetUpdated: "ChoiceSetUpdated",
|
|
25
|
+
ChoiceSetDeleted: "ChoiceSetDeleted",
|
|
26
|
+
ChoiceSetValueCreated: "ChoiceSetValueCreated",
|
|
27
|
+
ChoiceSetValueUpdated: "ChoiceSetValueUpdated",
|
|
28
|
+
ChoiceSetValuesDeleted: "ChoiceSetValuesDeleted",
|
|
29
|
+
} as const;
|
|
12
30
|
|
|
13
31
|
interface ListOptions {
|
|
14
32
|
tenant?: string;
|
|
@@ -21,24 +39,59 @@ interface GetOptions {
|
|
|
21
39
|
cursor?: string;
|
|
22
40
|
}
|
|
23
41
|
|
|
42
|
+
interface CreateOptions {
|
|
43
|
+
tenant?: string;
|
|
44
|
+
displayName?: string;
|
|
45
|
+
description?: string;
|
|
46
|
+
folderKey?: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface UpdateOptions {
|
|
50
|
+
tenant?: string;
|
|
51
|
+
displayName?: string;
|
|
52
|
+
description?: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
interface DeleteOptions {
|
|
56
|
+
tenant?: string;
|
|
57
|
+
confirm?: boolean;
|
|
58
|
+
reason?: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
interface ValueCreateOptions {
|
|
62
|
+
tenant?: string;
|
|
63
|
+
displayName?: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
interface ValueUpdateOptions {
|
|
67
|
+
tenant?: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
interface ValueDeleteOptions {
|
|
71
|
+
tenant?: string;
|
|
72
|
+
ids?: string;
|
|
73
|
+
confirm?: boolean;
|
|
74
|
+
reason?: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
24
77
|
const CHOICE_SETS_LIST_EXAMPLES: CommandExample[] = [
|
|
25
78
|
{
|
|
26
79
|
Description:
|
|
27
|
-
"List all Data Fabric choice sets. The returned '
|
|
80
|
+
"List all Data Fabric choice sets. The returned 'id' is the value to pass as 'choiceSetId' on a CHOICE_SET_SINGLE/CHOICE_SET_MULTIPLE entity field, or to 'df choice-sets list-values <id>'.",
|
|
28
81
|
Command: "uip df choice-sets list",
|
|
29
82
|
Output: {
|
|
30
|
-
Code:
|
|
83
|
+
Code: OUTPUT_CODES.ChoiceSetList,
|
|
31
84
|
Data: [
|
|
32
85
|
{
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
86
|
+
id: "c1d2e3f4-0000-0000-0000-000000000001",
|
|
87
|
+
name: "ExpenseTypes",
|
|
88
|
+
displayName: "Expense Types",
|
|
89
|
+
description: "Categories of expenses",
|
|
90
|
+
folderId: "f1000000-0000-0000-0000-000000000001",
|
|
91
|
+
createdBy: "u1000000-0000-0000-0000-000000000001",
|
|
92
|
+
updatedBy: "u1000000-0000-0000-0000-000000000001",
|
|
93
|
+
createdTime: "2026-01-01T00:00:00Z",
|
|
94
|
+
updatedTime: "2026-01-02T00:00:00Z",
|
|
42
95
|
},
|
|
43
96
|
],
|
|
44
97
|
},
|
|
@@ -48,28 +101,70 @@ const CHOICE_SETS_LIST_EXAMPLES: CommandExample[] = [
|
|
|
48
101
|
const CHOICE_SETS_GET_EXAMPLES: CommandExample[] = [
|
|
49
102
|
{
|
|
50
103
|
Description:
|
|
51
|
-
"
|
|
104
|
+
"List the values of a choice set. The 'numberId' on each value is the integer to pass when inserting or updating a record into a CHOICE_SET_SINGLE field (or in an array for CHOICE_SET_MULTIPLE).",
|
|
52
105
|
Command:
|
|
53
|
-
"uip df choice-sets
|
|
106
|
+
"uip df choice-sets list-values c1d2e3f4-0000-0000-0000-000000000001 --limit 2",
|
|
54
107
|
Output: {
|
|
55
|
-
Code:
|
|
108
|
+
Code: OUTPUT_CODES.ChoiceSetValues,
|
|
56
109
|
Data: {
|
|
57
|
-
|
|
58
|
-
Values: [
|
|
110
|
+
items: [
|
|
59
111
|
{
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
112
|
+
id: "v1000000-0000-0000-0000-000000000001",
|
|
113
|
+
name: "travel",
|
|
114
|
+
displayName: "Travel",
|
|
115
|
+
numberId: 0,
|
|
64
116
|
},
|
|
65
117
|
{
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
118
|
+
id: "v1000000-0000-0000-0000-000000000002",
|
|
119
|
+
name: "meals",
|
|
120
|
+
displayName: "Meals",
|
|
121
|
+
numberId: 1,
|
|
70
122
|
},
|
|
71
123
|
],
|
|
72
|
-
|
|
124
|
+
totalCount: 2,
|
|
125
|
+
hasNextPage: false,
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
];
|
|
130
|
+
|
|
131
|
+
const CHOICE_SETS_CREATE_EXAMPLES: CommandExample[] = [
|
|
132
|
+
{
|
|
133
|
+
Description:
|
|
134
|
+
"Create a choice set. The returned 'ID' is used as 'choiceSetId' on CHOICE_SET_SINGLE/CHOICE_SET_MULTIPLE entity fields. Add values with 'df choice-set-values create'.",
|
|
135
|
+
Command:
|
|
136
|
+
'uip df choice-sets create ExpenseTypes --display-name "Expense Types" --description "Categories of expenses"',
|
|
137
|
+
Output: {
|
|
138
|
+
Code: OUTPUT_CODES.ChoiceSetCreated,
|
|
139
|
+
Data: { ID: "c1d2e3f4-0000-0000-0000-000000000001" },
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
];
|
|
143
|
+
|
|
144
|
+
const CHOICE_SETS_UPDATE_EXAMPLES: CommandExample[] = [
|
|
145
|
+
{
|
|
146
|
+
Description:
|
|
147
|
+
"Update a choice set's display name and/or description. At least one of --display-name or --description is required.",
|
|
148
|
+
Command:
|
|
149
|
+
'uip df choice-sets update c1d2e3f4-0000-0000-0000-000000000001 --display-name "Expense Categories"',
|
|
150
|
+
Output: {
|
|
151
|
+
Code: OUTPUT_CODES.ChoiceSetUpdated,
|
|
152
|
+
Data: { ID: "c1d2e3f4-0000-0000-0000-000000000001" },
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
];
|
|
156
|
+
|
|
157
|
+
const CHOICE_SETS_DELETE_EXAMPLES: CommandExample[] = [
|
|
158
|
+
{
|
|
159
|
+
Description:
|
|
160
|
+
"Delete a choice set (irreversible — requires --confirm and --reason).",
|
|
161
|
+
Command:
|
|
162
|
+
'uip df choice-sets delete c1d2e3f4-0000-0000-0000-000000000001 --confirm --reason "no longer used"',
|
|
163
|
+
Output: {
|
|
164
|
+
Code: OUTPUT_CODES.ChoiceSetDeleted,
|
|
165
|
+
Data: {
|
|
166
|
+
ID: "c1d2e3f4-0000-0000-0000-000000000001",
|
|
167
|
+
Reason: "no longer used",
|
|
73
168
|
},
|
|
74
169
|
},
|
|
75
170
|
},
|
|
@@ -79,68 +174,46 @@ export const registerChoiceSetsCommand = (program: Command) => {
|
|
|
79
174
|
const choiceSets = program
|
|
80
175
|
.command("choice-sets")
|
|
81
176
|
.description(
|
|
82
|
-
"
|
|
83
|
-
"Use 'list' to
|
|
177
|
+
"Manage Data Fabric choice sets — the enumerated value lists referenced by CHOICE_SET_SINGLE/CHOICE_SET_MULTIPLE entity fields. " +
|
|
178
|
+
"Use 'list'/'list-values' to inspect, and 'create'/'update'/'delete' to manage them. Manage individual values with 'df choice-set-values'.",
|
|
84
179
|
);
|
|
85
180
|
|
|
86
181
|
choiceSets
|
|
87
182
|
.command("list")
|
|
88
183
|
.description("List all Data Fabric choice sets")
|
|
89
|
-
.
|
|
184
|
+
.addOption(
|
|
185
|
+
createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>"),
|
|
186
|
+
)
|
|
90
187
|
.examples(CHOICE_SETS_LIST_EXAMPLES)
|
|
91
188
|
.trackedAction(processContext, async (options: ListOptions) => {
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
);
|
|
95
|
-
|
|
96
|
-
if (clientError) {
|
|
97
|
-
OutputFormatter.error({
|
|
98
|
-
Result: RESULTS.Failure,
|
|
99
|
-
Message: "Error connecting to Data Fabric",
|
|
100
|
-
Instructions: await extractErrorMessage(clientError),
|
|
101
|
-
});
|
|
102
|
-
processContext.exit(1);
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
189
|
+
const sdk = await connectOrFail(options.tenant);
|
|
190
|
+
if (!sdk) return;
|
|
105
191
|
|
|
106
192
|
const [listError, result] = await catchError(
|
|
107
193
|
sdk.entities.choicesets.getAll(),
|
|
108
194
|
);
|
|
109
195
|
|
|
110
196
|
if (listError) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
});
|
|
116
|
-
processContext.exit(1);
|
|
117
|
-
return;
|
|
197
|
+
return fail(
|
|
198
|
+
"Error listing choice sets",
|
|
199
|
+
await extractErrorMessage(listError),
|
|
200
|
+
);
|
|
118
201
|
}
|
|
119
202
|
|
|
120
|
-
const items = (result ?? []).map((cs) => ({
|
|
121
|
-
ID: (cs as { id?: string }).id,
|
|
122
|
-
Name: cs.name,
|
|
123
|
-
DisplayName: cs.displayName || cs.name,
|
|
124
|
-
Description: cs.description || "",
|
|
125
|
-
FolderId: cs.folderId,
|
|
126
|
-
CreatedBy: cs.createdBy,
|
|
127
|
-
UpdatedBy: cs.updatedBy,
|
|
128
|
-
CreatedTime: cs.createdTime,
|
|
129
|
-
UpdatedTime: cs.updatedTime,
|
|
130
|
-
}));
|
|
131
|
-
|
|
132
203
|
OutputFormatter.success({
|
|
133
204
|
Result: RESULTS.Success,
|
|
134
|
-
Code:
|
|
135
|
-
Data:
|
|
205
|
+
Code: OUTPUT_CODES.ChoiceSetList,
|
|
206
|
+
Data: result ?? [],
|
|
136
207
|
});
|
|
137
208
|
});
|
|
138
209
|
|
|
139
210
|
choiceSets
|
|
140
|
-
.command("
|
|
141
|
-
.description("
|
|
211
|
+
.command("list-values")
|
|
212
|
+
.description("List the values of a Data Fabric choice set")
|
|
142
213
|
.argument("<choice-set-id>", "Choice set ID")
|
|
143
|
-
.
|
|
214
|
+
.addOption(
|
|
215
|
+
createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>"),
|
|
216
|
+
)
|
|
144
217
|
.option(
|
|
145
218
|
"-l, --limit <number>",
|
|
146
219
|
"Number of values to return per page",
|
|
@@ -160,58 +233,36 @@ export const registerChoiceSetsCommand = (program: Command) => {
|
|
|
160
233
|
async (choiceSetId: string, options: GetOptions) => {
|
|
161
234
|
const pageSize = Number(options.limit ?? "50");
|
|
162
235
|
if (Number.isNaN(pageSize) || pageSize < 1) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
});
|
|
168
|
-
processContext.exit(1);
|
|
169
|
-
return;
|
|
236
|
+
return fail(
|
|
237
|
+
"Invalid --limit value",
|
|
238
|
+
"Provide a positive integer for --limit.",
|
|
239
|
+
);
|
|
170
240
|
}
|
|
171
241
|
|
|
172
242
|
if (
|
|
173
243
|
options.cursor !== undefined &&
|
|
174
244
|
options.offset !== undefined
|
|
175
245
|
) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
"Use --offset to jump to a position by record count, or --cursor to continue from a previous response.",
|
|
181
|
-
});
|
|
182
|
-
processContext.exit(1);
|
|
183
|
-
return;
|
|
246
|
+
return fail(
|
|
247
|
+
"--offset and --cursor are mutually exclusive",
|
|
248
|
+
"Use --offset to jump to a position by record count, or --cursor to continue from a previous response.",
|
|
249
|
+
);
|
|
184
250
|
}
|
|
185
251
|
|
|
186
252
|
let jumpToPage: number | undefined;
|
|
187
253
|
if (options.offset !== undefined) {
|
|
188
254
|
const offsetValue = Number(options.offset);
|
|
189
255
|
if (Number.isNaN(offsetValue) || offsetValue < 0) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
"Provide a non-negative integer for --offset.",
|
|
195
|
-
});
|
|
196
|
-
processContext.exit(1);
|
|
197
|
-
return;
|
|
256
|
+
return fail(
|
|
257
|
+
"Invalid --offset value",
|
|
258
|
+
"Provide a non-negative integer for --offset.",
|
|
259
|
+
);
|
|
198
260
|
}
|
|
199
261
|
jumpToPage = Math.floor(offsetValue / pageSize) + 1;
|
|
200
262
|
}
|
|
201
263
|
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
);
|
|
205
|
-
|
|
206
|
-
if (clientError) {
|
|
207
|
-
OutputFormatter.error({
|
|
208
|
-
Result: RESULTS.Failure,
|
|
209
|
-
Message: "Error connecting to Data Fabric",
|
|
210
|
-
Instructions: await extractErrorMessage(clientError),
|
|
211
|
-
});
|
|
212
|
-
processContext.exit(1);
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
264
|
+
const sdk = await connectOrFail(options.tenant);
|
|
265
|
+
if (!sdk) return;
|
|
215
266
|
|
|
216
267
|
const paginationOptions =
|
|
217
268
|
options.cursor !== undefined
|
|
@@ -228,57 +279,410 @@ export const registerChoiceSetsCommand = (program: Command) => {
|
|
|
228
279
|
);
|
|
229
280
|
|
|
230
281
|
if (getError) {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
});
|
|
236
|
-
processContext.exit(1);
|
|
237
|
-
return;
|
|
282
|
+
return fail(
|
|
283
|
+
`Error getting choice set '${choiceSetId}'`,
|
|
284
|
+
await extractErrorMessage(getError),
|
|
285
|
+
);
|
|
238
286
|
}
|
|
239
287
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
288
|
+
OutputFormatter.success({
|
|
289
|
+
Result: RESULTS.Success,
|
|
290
|
+
Code: OUTPUT_CODES.ChoiceSetValues,
|
|
291
|
+
Data: result,
|
|
292
|
+
});
|
|
293
|
+
},
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
choiceSets
|
|
297
|
+
.command("create")
|
|
298
|
+
.description("Create a new Data Fabric choice set")
|
|
299
|
+
.argument(
|
|
300
|
+
"<name>",
|
|
301
|
+
"Choice set name (must start with a letter; letters, numbers, and underscores only)",
|
|
302
|
+
)
|
|
303
|
+
.addOption(
|
|
304
|
+
createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>"),
|
|
305
|
+
)
|
|
306
|
+
.option("--display-name <name>", "Human-readable display name")
|
|
307
|
+
.option("--description <text>", "Choice set description")
|
|
308
|
+
.option(
|
|
309
|
+
"--folder-key <uuid>",
|
|
310
|
+
"UUID of the folder to place the choice set in (defaults to the tenant-level folder)",
|
|
311
|
+
)
|
|
312
|
+
.examples(CHOICE_SETS_CREATE_EXAMPLES)
|
|
313
|
+
.trackedAction(
|
|
314
|
+
processContext,
|
|
315
|
+
async (name: string, options: CreateOptions) => {
|
|
316
|
+
const sdk = await connectOrFail(options.tenant);
|
|
317
|
+
if (!sdk) return;
|
|
318
|
+
|
|
319
|
+
const createOpts: ChoiceSetCreateOptions = {
|
|
320
|
+
...(options.displayName !== undefined && {
|
|
321
|
+
displayName: options.displayName,
|
|
322
|
+
}),
|
|
323
|
+
...(options.description !== undefined && {
|
|
324
|
+
description: options.description,
|
|
325
|
+
}),
|
|
326
|
+
...(options.folderKey !== undefined && {
|
|
327
|
+
folderKey: options.folderKey,
|
|
328
|
+
}),
|
|
247
329
|
};
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
330
|
+
|
|
331
|
+
const choiceSetService: ChoiceSetServiceModel =
|
|
332
|
+
sdk.entities.choicesets;
|
|
333
|
+
const [createError, choiceSetId] = await catchError(
|
|
334
|
+
choiceSetService.create(
|
|
335
|
+
name,
|
|
336
|
+
Object.keys(createOpts).length > 0
|
|
337
|
+
? createOpts
|
|
338
|
+
: undefined,
|
|
339
|
+
),
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
if (createError) {
|
|
343
|
+
return fail(
|
|
344
|
+
"Error creating choice set",
|
|
345
|
+
await extractErrorMessage(createError),
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
OutputFormatter.success({
|
|
350
|
+
Result: RESULTS.Success,
|
|
351
|
+
Code: OUTPUT_CODES.ChoiceSetCreated,
|
|
352
|
+
Data: { ID: choiceSetId },
|
|
353
|
+
});
|
|
354
|
+
},
|
|
355
|
+
);
|
|
356
|
+
|
|
357
|
+
choiceSets
|
|
358
|
+
.command("update")
|
|
359
|
+
.description("Update the metadata of a Data Fabric choice set")
|
|
360
|
+
.argument("<choice-set-id>", "Choice set ID")
|
|
361
|
+
.addOption(
|
|
362
|
+
createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>"),
|
|
363
|
+
)
|
|
364
|
+
.option("--display-name <name>", "New display name")
|
|
365
|
+
.option("--description <text>", "New description")
|
|
366
|
+
.examples(CHOICE_SETS_UPDATE_EXAMPLES)
|
|
367
|
+
.trackedAction(
|
|
368
|
+
processContext,
|
|
369
|
+
async (choiceSetId: string, options: UpdateOptions) => {
|
|
370
|
+
if (
|
|
371
|
+
options.displayName === undefined &&
|
|
372
|
+
options.description === undefined
|
|
373
|
+
) {
|
|
374
|
+
return fail(
|
|
375
|
+
"No update fields provided",
|
|
376
|
+
"Provide at least one of --display-name or --description.",
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const sdk = await connectOrFail(options.tenant);
|
|
381
|
+
if (!sdk) return;
|
|
382
|
+
|
|
383
|
+
const updateOpts: ChoiceSetUpdateOptions = {
|
|
384
|
+
...(options.displayName !== undefined && {
|
|
385
|
+
displayName: options.displayName,
|
|
386
|
+
}),
|
|
387
|
+
...(options.description !== undefined && {
|
|
388
|
+
description: options.description,
|
|
389
|
+
}),
|
|
255
390
|
};
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
391
|
+
|
|
392
|
+
const choiceSetService: ChoiceSetServiceModel =
|
|
393
|
+
sdk.entities.choicesets;
|
|
394
|
+
const [updateError] = await catchError(
|
|
395
|
+
choiceSetService.updateById(choiceSetId, updateOpts),
|
|
396
|
+
);
|
|
397
|
+
|
|
398
|
+
if (updateError) {
|
|
399
|
+
return fail(
|
|
400
|
+
`Error updating choice set '${choiceSetId}'`,
|
|
401
|
+
await extractErrorMessage(updateError),
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
OutputFormatter.success({
|
|
406
|
+
Result: RESULTS.Success,
|
|
407
|
+
Code: OUTPUT_CODES.ChoiceSetUpdated,
|
|
408
|
+
Data: { ID: choiceSetId },
|
|
409
|
+
});
|
|
410
|
+
},
|
|
411
|
+
);
|
|
412
|
+
|
|
413
|
+
choiceSets
|
|
414
|
+
.command("delete")
|
|
415
|
+
.description("Delete a Data Fabric choice set (irreversible)")
|
|
416
|
+
.argument("<choice-set-id>", "Choice set ID")
|
|
417
|
+
.addOption(
|
|
418
|
+
createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>"),
|
|
419
|
+
)
|
|
420
|
+
.option("--confirm", "Acknowledge this is an irreversible operation")
|
|
421
|
+
.option(
|
|
422
|
+
"--reason <reason>",
|
|
423
|
+
"Reason for the deletion — echoed back in the response so the caller can log it",
|
|
424
|
+
)
|
|
425
|
+
.examples(CHOICE_SETS_DELETE_EXAMPLES)
|
|
426
|
+
.trackedAction(
|
|
427
|
+
processContext,
|
|
428
|
+
async (choiceSetId: string, options: DeleteOptions) => {
|
|
429
|
+
const reason = requireDestructiveConfirmation(
|
|
430
|
+
options,
|
|
431
|
+
'Pass --reason "<text>" to record why the choice set is being deleted.',
|
|
432
|
+
);
|
|
433
|
+
if (reason === null) return;
|
|
434
|
+
|
|
435
|
+
const sdk = await connectOrFail(options.tenant);
|
|
436
|
+
if (!sdk) return;
|
|
437
|
+
|
|
438
|
+
const choiceSetService: ChoiceSetServiceModel =
|
|
439
|
+
sdk.entities.choicesets;
|
|
440
|
+
const [deleteError] = await catchError(
|
|
441
|
+
choiceSetService.deleteById(choiceSetId),
|
|
442
|
+
);
|
|
443
|
+
|
|
444
|
+
if (deleteError) {
|
|
445
|
+
return fail(
|
|
446
|
+
`Error deleting choice set '${choiceSetId}'`,
|
|
447
|
+
await extractErrorMessage(deleteError),
|
|
448
|
+
);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
OutputFormatter.success({
|
|
452
|
+
Result: RESULTS.Success,
|
|
453
|
+
Code: OUTPUT_CODES.ChoiceSetDeleted,
|
|
454
|
+
Data: { ID: choiceSetId, Reason: reason },
|
|
455
|
+
});
|
|
456
|
+
},
|
|
457
|
+
);
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
const CHOICE_SET_VALUES_CREATE_EXAMPLES: CommandExample[] = [
|
|
461
|
+
{
|
|
462
|
+
Description:
|
|
463
|
+
"Add a value to a choice set. The returned 'numberId' is the integer to pass when inserting or updating records into a CHOICE_SET_SINGLE field (or in an array for CHOICE_SET_MULTIPLE).",
|
|
464
|
+
Command:
|
|
465
|
+
'uip df choice-set-values create c1d2e3f4-0000-0000-0000-000000000001 travel --display-name "Travel"',
|
|
466
|
+
Output: {
|
|
467
|
+
Code: OUTPUT_CODES.ChoiceSetValueCreated,
|
|
468
|
+
Data: {
|
|
469
|
+
id: "v1000000-0000-0000-0000-000000000001",
|
|
470
|
+
name: "travel",
|
|
471
|
+
displayName: "Travel",
|
|
472
|
+
numberId: 0,
|
|
473
|
+
},
|
|
474
|
+
},
|
|
475
|
+
},
|
|
476
|
+
];
|
|
477
|
+
|
|
478
|
+
const CHOICE_SET_VALUES_UPDATE_EXAMPLES: CommandExample[] = [
|
|
479
|
+
{
|
|
480
|
+
Description:
|
|
481
|
+
"Update the display name of an existing choice set value. Find value IDs with 'df choice-sets list-values <choice-set-id>'.",
|
|
482
|
+
Command:
|
|
483
|
+
'uip df choice-set-values update c1d2e3f4-0000-0000-0000-000000000001 v1000000-0000-0000-0000-000000000001 "Business Travel"',
|
|
484
|
+
Output: {
|
|
485
|
+
Code: OUTPUT_CODES.ChoiceSetValueUpdated,
|
|
486
|
+
Data: {
|
|
487
|
+
id: "v1000000-0000-0000-0000-000000000001",
|
|
488
|
+
name: "travel",
|
|
489
|
+
displayName: "Business Travel",
|
|
490
|
+
numberId: 0,
|
|
491
|
+
},
|
|
492
|
+
},
|
|
493
|
+
},
|
|
494
|
+
];
|
|
495
|
+
|
|
496
|
+
const CHOICE_SET_VALUES_DELETE_EXAMPLES: CommandExample[] = [
|
|
497
|
+
{
|
|
498
|
+
Description:
|
|
499
|
+
"Delete one or more values from a choice set (irreversible — requires --confirm and --reason). Pass value IDs as a comma-separated list.",
|
|
500
|
+
Command:
|
|
501
|
+
'uip df choice-set-values delete c1d2e3f4-0000-0000-0000-000000000001 --ids v1000000-0000-0000-0000-000000000001,v1000000-0000-0000-0000-000000000002 --confirm --reason "deprecated categories"',
|
|
502
|
+
Output: {
|
|
503
|
+
Code: OUTPUT_CODES.ChoiceSetValuesDeleted,
|
|
504
|
+
Data: {
|
|
505
|
+
ChoiceSetId: "c1d2e3f4-0000-0000-0000-000000000001",
|
|
506
|
+
DeletedIds: [
|
|
507
|
+
"v1000000-0000-0000-0000-000000000001",
|
|
508
|
+
"v1000000-0000-0000-0000-000000000002",
|
|
509
|
+
],
|
|
510
|
+
Reason: "deprecated categories",
|
|
511
|
+
},
|
|
512
|
+
},
|
|
513
|
+
},
|
|
514
|
+
];
|
|
515
|
+
|
|
516
|
+
export const registerChoiceSetValuesCommand = (program: Command) => {
|
|
517
|
+
const values = program
|
|
518
|
+
.command("choice-set-values")
|
|
519
|
+
.description(
|
|
520
|
+
"Manage the individual values of a Data Fabric choice set. " +
|
|
521
|
+
"Use 'df choice-sets list-values <choice-set-id>' to list existing values and their IDs.",
|
|
522
|
+
);
|
|
523
|
+
|
|
524
|
+
values
|
|
525
|
+
.command("create")
|
|
526
|
+
.description("Add a value to a Data Fabric choice set")
|
|
527
|
+
.argument("<choice-set-id>", "Choice set ID")
|
|
528
|
+
.argument(
|
|
529
|
+
"<name>",
|
|
530
|
+
"Value name (must start with a letter; letters, numbers, and underscores only)",
|
|
531
|
+
)
|
|
532
|
+
.addOption(
|
|
533
|
+
createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>"),
|
|
534
|
+
)
|
|
535
|
+
.option("--display-name <name>", "Human-readable display name")
|
|
536
|
+
.examples(CHOICE_SET_VALUES_CREATE_EXAMPLES)
|
|
537
|
+
.trackedAction(
|
|
538
|
+
processContext,
|
|
539
|
+
async (
|
|
540
|
+
choiceSetId: string,
|
|
541
|
+
name: string,
|
|
542
|
+
options: ValueCreateOptions,
|
|
543
|
+
) => {
|
|
544
|
+
const sdk = await connectOrFail(options.tenant);
|
|
545
|
+
if (!sdk) return;
|
|
546
|
+
|
|
547
|
+
const insertOpts: ChoiceSetValueInsertOptions = {
|
|
548
|
+
...(options.displayName !== undefined && {
|
|
549
|
+
displayName: options.displayName,
|
|
550
|
+
}),
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
const choiceSetService: ChoiceSetServiceModel =
|
|
554
|
+
sdk.entities.choicesets;
|
|
555
|
+
const [createError, result] = await catchError(
|
|
556
|
+
choiceSetService.insertValueById(
|
|
557
|
+
choiceSetId,
|
|
558
|
+
name,
|
|
559
|
+
Object.keys(insertOpts).length > 0
|
|
560
|
+
? insertOpts
|
|
561
|
+
: undefined,
|
|
562
|
+
),
|
|
563
|
+
);
|
|
564
|
+
|
|
565
|
+
if (createError) {
|
|
566
|
+
return fail(
|
|
567
|
+
`Error creating value in choice set '${choiceSetId}'`,
|
|
568
|
+
await extractErrorMessage(createError),
|
|
569
|
+
);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
OutputFormatter.success({
|
|
573
|
+
Result: RESULTS.Success,
|
|
574
|
+
Code: OUTPUT_CODES.ChoiceSetValueCreated,
|
|
575
|
+
Data: result,
|
|
576
|
+
});
|
|
577
|
+
},
|
|
578
|
+
);
|
|
579
|
+
|
|
580
|
+
values
|
|
581
|
+
.command("update")
|
|
582
|
+
.description("Update the display name of a choice set value")
|
|
583
|
+
.argument("<choice-set-id>", "Choice set ID")
|
|
584
|
+
.argument("<value-id>", "Choice set value ID")
|
|
585
|
+
.argument("<display-name>", "New display name for the value")
|
|
586
|
+
.addOption(
|
|
587
|
+
createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>"),
|
|
588
|
+
)
|
|
589
|
+
.examples(CHOICE_SET_VALUES_UPDATE_EXAMPLES)
|
|
590
|
+
.trackedAction(
|
|
591
|
+
processContext,
|
|
592
|
+
async (
|
|
593
|
+
choiceSetId: string,
|
|
594
|
+
valueId: string,
|
|
595
|
+
displayName: string,
|
|
596
|
+
options: ValueUpdateOptions,
|
|
597
|
+
) => {
|
|
598
|
+
const sdk = await connectOrFail(options.tenant);
|
|
599
|
+
if (!sdk) return;
|
|
600
|
+
|
|
601
|
+
const choiceSetService: ChoiceSetServiceModel =
|
|
602
|
+
sdk.entities.choicesets;
|
|
603
|
+
const [updateError, result] = await catchError(
|
|
604
|
+
choiceSetService.updateValueById(
|
|
605
|
+
choiceSetId,
|
|
606
|
+
valueId,
|
|
607
|
+
displayName,
|
|
608
|
+
),
|
|
609
|
+
);
|
|
610
|
+
|
|
611
|
+
if (updateError) {
|
|
612
|
+
return fail(
|
|
613
|
+
`Error updating value '${valueId}' in choice set '${choiceSetId}'`,
|
|
614
|
+
await extractErrorMessage(updateError),
|
|
615
|
+
);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
OutputFormatter.success({
|
|
619
|
+
Result: RESULTS.Success,
|
|
620
|
+
Code: OUTPUT_CODES.ChoiceSetValueUpdated,
|
|
621
|
+
Data: result,
|
|
622
|
+
});
|
|
623
|
+
},
|
|
624
|
+
);
|
|
625
|
+
|
|
626
|
+
values
|
|
627
|
+
.command("delete")
|
|
628
|
+
.description(
|
|
629
|
+
"Delete values from a Data Fabric choice set (irreversible)",
|
|
630
|
+
)
|
|
631
|
+
.argument("<choice-set-id>", "Choice set ID")
|
|
632
|
+
.addOption(
|
|
633
|
+
createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>"),
|
|
634
|
+
)
|
|
635
|
+
.option("--ids <ids>", "Comma-separated list of value IDs to delete")
|
|
636
|
+
.option("--confirm", "Acknowledge this is an irreversible operation")
|
|
637
|
+
.option(
|
|
638
|
+
"--reason <reason>",
|
|
639
|
+
"Reason for the deletion — echoed back in the response so the caller can log it",
|
|
640
|
+
)
|
|
641
|
+
.examples(CHOICE_SET_VALUES_DELETE_EXAMPLES)
|
|
642
|
+
.trackedAction(
|
|
643
|
+
processContext,
|
|
644
|
+
async (choiceSetId: string, options: ValueDeleteOptions) => {
|
|
645
|
+
const valueIds = (options.ids ?? "")
|
|
646
|
+
.split(",")
|
|
647
|
+
.map((id) => id.trim())
|
|
648
|
+
.filter((id) => id.length > 0);
|
|
649
|
+
|
|
650
|
+
if (valueIds.length === 0) {
|
|
651
|
+
return fail(
|
|
652
|
+
"No value IDs provided",
|
|
653
|
+
"Pass --ids <id,id,...> with at least one value ID to delete.",
|
|
654
|
+
);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
const reason = requireDestructiveConfirmation(
|
|
658
|
+
options,
|
|
659
|
+
'Pass --reason "<text>" to record why the values are being deleted.',
|
|
660
|
+
);
|
|
661
|
+
if (reason === null) return;
|
|
662
|
+
|
|
663
|
+
const sdk = await connectOrFail(options.tenant);
|
|
664
|
+
if (!sdk) return;
|
|
665
|
+
|
|
666
|
+
const choiceSetService: ChoiceSetServiceModel =
|
|
667
|
+
sdk.entities.choicesets;
|
|
668
|
+
const [deleteError] = await catchError(
|
|
669
|
+
choiceSetService.deleteValuesById(choiceSetId, valueIds),
|
|
670
|
+
);
|
|
671
|
+
|
|
672
|
+
if (deleteError) {
|
|
673
|
+
return fail(
|
|
674
|
+
`Error deleting values from choice set '${choiceSetId}'`,
|
|
675
|
+
await extractErrorMessage(deleteError),
|
|
676
|
+
);
|
|
677
|
+
}
|
|
265
678
|
|
|
266
679
|
OutputFormatter.success({
|
|
267
680
|
Result: RESULTS.Success,
|
|
268
|
-
Code:
|
|
681
|
+
Code: OUTPUT_CODES.ChoiceSetValuesDeleted,
|
|
269
682
|
Data: {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
...(nextCursor !== undefined && {
|
|
274
|
-
NextCursor: nextCursor,
|
|
275
|
-
}),
|
|
276
|
-
...(response.currentPage !== undefined && {
|
|
277
|
-
CurrentPage: response.currentPage,
|
|
278
|
-
}),
|
|
279
|
-
...(response.totalPages !== undefined && {
|
|
280
|
-
TotalPages: response.totalPages,
|
|
281
|
-
}),
|
|
683
|
+
ChoiceSetId: choiceSetId,
|
|
684
|
+
DeletedIds: valueIds,
|
|
685
|
+
Reason: reason,
|
|
282
686
|
},
|
|
283
687
|
});
|
|
284
688
|
},
|