@uipath/data-fabric-tool 0.9.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/index.js +57923 -0
- package/dist/tool.js +57914 -0
- package/package.json +34 -0
- package/src/commands/entities.spec.ts +970 -0
- package/src/commands/entities.ts +564 -0
- package/src/commands/files.spec.ts +344 -0
- package/src/commands/files.ts +339 -0
- package/src/commands/records.spec.ts +2106 -0
- package/src/commands/records.ts +875 -0
- package/src/index.ts +17 -0
- package/src/tool.ts +19 -0
- package/src/utils/input.ts +32 -0
- package/src/utils/sdk-client.ts +23 -0
- package/tsconfig.json +9 -0
- package/vitest.config.ts +1 -0
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type CommandExample,
|
|
3
|
+
catchError,
|
|
4
|
+
extractErrorMessage,
|
|
5
|
+
OutputFormatter,
|
|
6
|
+
processContext,
|
|
7
|
+
RESULTS,
|
|
8
|
+
} from "@uipath/common";
|
|
9
|
+
import type {
|
|
10
|
+
EntityCreateFieldOptions,
|
|
11
|
+
EntityServiceModel,
|
|
12
|
+
EntityUpdateByIdOptions,
|
|
13
|
+
ExternalSourceFields,
|
|
14
|
+
RawEntityGetResponse,
|
|
15
|
+
} from "@uipath/uipath-typescript";
|
|
16
|
+
import { EntityFieldDataType } from "@uipath/uipath-typescript";
|
|
17
|
+
import type { Command } from "commander";
|
|
18
|
+
import { readJsonInput } from "../utils/input";
|
|
19
|
+
import { createDataFabricClient } from "../utils/sdk-client";
|
|
20
|
+
|
|
21
|
+
interface ListOptions {
|
|
22
|
+
tenant?: string;
|
|
23
|
+
nativeOnly?: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface GetOptions {
|
|
27
|
+
tenant?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface CreateOptions {
|
|
31
|
+
tenant?: string;
|
|
32
|
+
file?: string;
|
|
33
|
+
body?: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface UpdateEntityOptions {
|
|
37
|
+
tenant?: string;
|
|
38
|
+
file?: string;
|
|
39
|
+
body?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const ENTITIES_LIST_EXAMPLES: CommandExample[] = [
|
|
43
|
+
{
|
|
44
|
+
Description: "List Data Fabric entities",
|
|
45
|
+
Command: "uip df entities list --native-only",
|
|
46
|
+
Output: {
|
|
47
|
+
Code: "EntityList",
|
|
48
|
+
Data: [
|
|
49
|
+
{
|
|
50
|
+
Name: "Invoice",
|
|
51
|
+
DisplayName: "Invoice",
|
|
52
|
+
ID: "a1b2c3d4-0000-0000-0000-000000000001",
|
|
53
|
+
Type: "Standard",
|
|
54
|
+
Source: "Native",
|
|
55
|
+
Description: "Invoice records",
|
|
56
|
+
FieldCount: 8,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
Name: "Customer",
|
|
60
|
+
DisplayName: "Customer",
|
|
61
|
+
ID: "a1b2c3d4-0000-0000-0000-000000000002",
|
|
62
|
+
Type: "Standard",
|
|
63
|
+
Source: "Native",
|
|
64
|
+
Description: "Customer records",
|
|
65
|
+
FieldCount: 6,
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
const ENTITIES_GET_EXAMPLES: CommandExample[] = [
|
|
73
|
+
{
|
|
74
|
+
Description: "Get entity schema by ID",
|
|
75
|
+
Command: "uip df entities get a1b2c3d4-0000-0000-0000-000000000001",
|
|
76
|
+
Output: {
|
|
77
|
+
Code: "EntitySchema",
|
|
78
|
+
Data: {
|
|
79
|
+
Name: "Invoice",
|
|
80
|
+
DisplayName: "Invoice",
|
|
81
|
+
ID: "a1b2c3d4-0000-0000-0000-000000000001",
|
|
82
|
+
Type: "Standard",
|
|
83
|
+
Description: "Invoice records",
|
|
84
|
+
Fields: [
|
|
85
|
+
{
|
|
86
|
+
ID: "f1000000-0000-0000-0000-000000000001",
|
|
87
|
+
Name: "id",
|
|
88
|
+
DisplayName: "ID",
|
|
89
|
+
Type: "Guid",
|
|
90
|
+
Required: true,
|
|
91
|
+
PrimaryKey: true,
|
|
92
|
+
System: true,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
ID: "f1000000-0000-0000-0000-000000000002",
|
|
96
|
+
Name: "amount",
|
|
97
|
+
DisplayName: "Amount",
|
|
98
|
+
Type: "Decimal",
|
|
99
|
+
Required: true,
|
|
100
|
+
PrimaryKey: false,
|
|
101
|
+
System: false,
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
const VALID_FIELD_TYPES = new Set(Object.values(EntityFieldDataType));
|
|
110
|
+
const VALID_FIELD_TYPES_LIST = [...VALID_FIELD_TYPES].join(", ");
|
|
111
|
+
|
|
112
|
+
function hasInvalidFieldType(fields: unknown[]): boolean {
|
|
113
|
+
return fields.some((f) => {
|
|
114
|
+
const field = f as Record<string, unknown>;
|
|
115
|
+
return (
|
|
116
|
+
field.type !== undefined &&
|
|
117
|
+
!VALID_FIELD_TYPES.has(field.type as EntityFieldDataType)
|
|
118
|
+
);
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export const registerEntitiesCommand = (program: Command) => {
|
|
123
|
+
const entities = program
|
|
124
|
+
.command("entities")
|
|
125
|
+
.description("Browse Data Fabric entity schemas");
|
|
126
|
+
|
|
127
|
+
entities
|
|
128
|
+
.command("list")
|
|
129
|
+
.description("List all Data Fabric entities")
|
|
130
|
+
.option("-t, --tenant <tenant-name>", "Tenant name")
|
|
131
|
+
.option(
|
|
132
|
+
"--native-only",
|
|
133
|
+
"Show only native entities (exclude federated entities with external connections)",
|
|
134
|
+
)
|
|
135
|
+
.examples(ENTITIES_LIST_EXAMPLES)
|
|
136
|
+
.trackedAction(processContext, async (options: ListOptions) => {
|
|
137
|
+
const [clientError, sdk] = await catchError(
|
|
138
|
+
createDataFabricClient(options.tenant),
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
if (clientError) {
|
|
142
|
+
OutputFormatter.error({
|
|
143
|
+
Result: RESULTS.Failure,
|
|
144
|
+
Message: "Error connecting to Data Fabric",
|
|
145
|
+
Instructions: await extractErrorMessage(clientError),
|
|
146
|
+
});
|
|
147
|
+
processContext.exit(1);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const [listError, result] = await catchError(sdk.entities.getAll());
|
|
152
|
+
|
|
153
|
+
if (listError) {
|
|
154
|
+
OutputFormatter.error({
|
|
155
|
+
Result: RESULTS.Failure,
|
|
156
|
+
Message: "Error listing entities",
|
|
157
|
+
Instructions: await extractErrorMessage(listError),
|
|
158
|
+
});
|
|
159
|
+
processContext.exit(1);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const entityList = (result ?? [])
|
|
164
|
+
.map((e) => {
|
|
165
|
+
const entity = e as unknown as RawEntityGetResponse;
|
|
166
|
+
const externalFields: ExternalSourceFields[] =
|
|
167
|
+
entity.externalFields ?? [];
|
|
168
|
+
const isNative = externalFields.length === 0;
|
|
169
|
+
const connectorName =
|
|
170
|
+
externalFields[0]?.externalConnectionDetail
|
|
171
|
+
?.connectorName;
|
|
172
|
+
return {
|
|
173
|
+
Name: entity.name,
|
|
174
|
+
DisplayName: entity.displayName || entity.name,
|
|
175
|
+
ID: entity.id,
|
|
176
|
+
Type: entity.entityType,
|
|
177
|
+
Source: isNative
|
|
178
|
+
? "Native"
|
|
179
|
+
: `Federated${connectorName ? ` (${connectorName})` : ""}`,
|
|
180
|
+
Description: entity.description || "",
|
|
181
|
+
FieldCount: entity.fields.length,
|
|
182
|
+
};
|
|
183
|
+
})
|
|
184
|
+
.filter((e) => !options.nativeOnly || e.Source === "Native");
|
|
185
|
+
|
|
186
|
+
OutputFormatter.success({
|
|
187
|
+
Result: RESULTS.Success,
|
|
188
|
+
Code: "EntityList",
|
|
189
|
+
Data: entityList,
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
entities
|
|
194
|
+
.command("get")
|
|
195
|
+
.description("Get schema details of a Data Fabric entity")
|
|
196
|
+
.argument("<id>", "Entity ID")
|
|
197
|
+
.option("-t, --tenant <tenant-name>", "Tenant name")
|
|
198
|
+
.examples(ENTITIES_GET_EXAMPLES)
|
|
199
|
+
.trackedAction(
|
|
200
|
+
processContext,
|
|
201
|
+
async (id: string, options: GetOptions) => {
|
|
202
|
+
const [clientError, sdk] = await catchError(
|
|
203
|
+
createDataFabricClient(options.tenant),
|
|
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
|
+
}
|
|
215
|
+
|
|
216
|
+
const [getError, entity] = await catchError(
|
|
217
|
+
sdk.entities.getById(id),
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
if (getError) {
|
|
221
|
+
OutputFormatter.error({
|
|
222
|
+
Result: RESULTS.Failure,
|
|
223
|
+
Message: `Error getting entity schema '${id}'`,
|
|
224
|
+
Instructions: await extractErrorMessage(getError),
|
|
225
|
+
});
|
|
226
|
+
processContext.exit(1);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const e = entity as unknown as RawEntityGetResponse;
|
|
231
|
+
|
|
232
|
+
if (!e?.fields) {
|
|
233
|
+
OutputFormatter.error({
|
|
234
|
+
Result: RESULTS.Failure,
|
|
235
|
+
Message: `Entity '${id}' not found`,
|
|
236
|
+
Instructions:
|
|
237
|
+
"Verify the entity ID exists. Use 'df entities list' to see available entities.",
|
|
238
|
+
});
|
|
239
|
+
processContext.exit(1);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const fields = e.fields.map((field) => ({
|
|
244
|
+
ID: field.id,
|
|
245
|
+
Name: field.name,
|
|
246
|
+
DisplayName: field.displayName,
|
|
247
|
+
Type: field.fieldDataType?.name,
|
|
248
|
+
Required: field.isRequired,
|
|
249
|
+
PrimaryKey: field.isPrimaryKey,
|
|
250
|
+
System: field.isSystemField,
|
|
251
|
+
}));
|
|
252
|
+
|
|
253
|
+
OutputFormatter.success({
|
|
254
|
+
Result: RESULTS.Success,
|
|
255
|
+
Code: "EntitySchema",
|
|
256
|
+
Data: {
|
|
257
|
+
Name: e.name,
|
|
258
|
+
DisplayName: e.displayName || e.name,
|
|
259
|
+
ID: e.id,
|
|
260
|
+
Type: e.entityType,
|
|
261
|
+
Description: e.description || "",
|
|
262
|
+
Fields: fields,
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
},
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
entities
|
|
269
|
+
.command("create")
|
|
270
|
+
.description("Create a new Data Fabric entity")
|
|
271
|
+
.argument(
|
|
272
|
+
"<name>",
|
|
273
|
+
"Entity name (must start with a letter; letters, numbers, and underscores only)",
|
|
274
|
+
)
|
|
275
|
+
.option("-t, --tenant <tenant-name>", "Tenant name")
|
|
276
|
+
.option(
|
|
277
|
+
"-f, --file <path>",
|
|
278
|
+
"Path to JSON file with entity definition (fields array required; displayName, description, isRbacEnabled optional)",
|
|
279
|
+
)
|
|
280
|
+
.option("--body <json>", "Inline JSON entity definition")
|
|
281
|
+
.trackedAction(
|
|
282
|
+
processContext,
|
|
283
|
+
async (name: string, options: CreateOptions) => {
|
|
284
|
+
const [parseError, parsed] = await catchError(
|
|
285
|
+
readJsonInput(
|
|
286
|
+
options.file,
|
|
287
|
+
options.body,
|
|
288
|
+
"Provide entity definition via --file or --body.",
|
|
289
|
+
),
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
if (parseError) {
|
|
293
|
+
OutputFormatter.error({
|
|
294
|
+
Result: RESULTS.Failure,
|
|
295
|
+
Message: "Error parsing entity definition",
|
|
296
|
+
Instructions: parseError.message,
|
|
297
|
+
});
|
|
298
|
+
processContext.exit(1);
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (
|
|
303
|
+
typeof parsed !== "object" ||
|
|
304
|
+
parsed === null ||
|
|
305
|
+
Array.isArray(parsed)
|
|
306
|
+
) {
|
|
307
|
+
OutputFormatter.error({
|
|
308
|
+
Result: RESULTS.Failure,
|
|
309
|
+
Message: "Entity definition must be a JSON object",
|
|
310
|
+
Instructions:
|
|
311
|
+
"Provide a JSON object with a 'fields' array and optional displayName, description, isRbacEnabled.",
|
|
312
|
+
});
|
|
313
|
+
processContext.exit(1);
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const definition = parsed as Record<string, unknown>;
|
|
318
|
+
if (!Array.isArray(definition.fields)) {
|
|
319
|
+
OutputFormatter.error({
|
|
320
|
+
Result: RESULTS.Failure,
|
|
321
|
+
Message:
|
|
322
|
+
"Entity definition must include a 'fields' array",
|
|
323
|
+
Instructions:
|
|
324
|
+
"Provide a JSON object with a 'fields' array containing field definitions.",
|
|
325
|
+
});
|
|
326
|
+
processContext.exit(1);
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const hasInvalidField = (definition.fields as unknown[]).some(
|
|
331
|
+
(f) =>
|
|
332
|
+
typeof f !== "object" ||
|
|
333
|
+
f === null ||
|
|
334
|
+
typeof (f as Record<string, unknown>).fieldName !==
|
|
335
|
+
"string",
|
|
336
|
+
);
|
|
337
|
+
if (hasInvalidField) {
|
|
338
|
+
OutputFormatter.error({
|
|
339
|
+
Result: RESULTS.Failure,
|
|
340
|
+
Message: "Each field must include a 'fieldName' string",
|
|
341
|
+
Instructions:
|
|
342
|
+
'Example: {"fieldName":"title","type":"STRING"}',
|
|
343
|
+
});
|
|
344
|
+
processContext.exit(1);
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
if (hasInvalidFieldType(definition.fields as unknown[])) {
|
|
349
|
+
OutputFormatter.error({
|
|
350
|
+
Result: RESULTS.Failure,
|
|
351
|
+
Message: "Invalid field type in fields",
|
|
352
|
+
Instructions: `Valid types: ${VALID_FIELD_TYPES_LIST}`,
|
|
353
|
+
});
|
|
354
|
+
processContext.exit(1);
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
const [clientError, sdk] = await catchError(
|
|
359
|
+
createDataFabricClient(options.tenant),
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
if (clientError) {
|
|
363
|
+
OutputFormatter.error({
|
|
364
|
+
Result: RESULTS.Failure,
|
|
365
|
+
Message: "Error connecting to Data Fabric",
|
|
366
|
+
Instructions: await extractErrorMessage(clientError),
|
|
367
|
+
});
|
|
368
|
+
processContext.exit(1);
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
const createOpts = {
|
|
373
|
+
...(definition.displayName !== undefined && {
|
|
374
|
+
displayName: definition.displayName as string,
|
|
375
|
+
}),
|
|
376
|
+
...(definition.description !== undefined && {
|
|
377
|
+
description: definition.description as string,
|
|
378
|
+
}),
|
|
379
|
+
...(definition.isRbacEnabled !== undefined && {
|
|
380
|
+
isRbacEnabled: definition.isRbacEnabled as boolean,
|
|
381
|
+
}),
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
const entityService: EntityServiceModel = sdk.entities;
|
|
385
|
+
const [createError, entityId] = await catchError(
|
|
386
|
+
entityService.create(
|
|
387
|
+
name,
|
|
388
|
+
definition.fields as EntityCreateFieldOptions[],
|
|
389
|
+
Object.keys(createOpts).length > 0
|
|
390
|
+
? createOpts
|
|
391
|
+
: undefined,
|
|
392
|
+
),
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
if (createError) {
|
|
396
|
+
OutputFormatter.error({
|
|
397
|
+
Result: RESULTS.Failure,
|
|
398
|
+
Message: "Error creating entity",
|
|
399
|
+
Instructions: await extractErrorMessage(createError),
|
|
400
|
+
});
|
|
401
|
+
processContext.exit(1);
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
OutputFormatter.success({
|
|
406
|
+
Result: RESULTS.Success,
|
|
407
|
+
Code: "EntityCreated",
|
|
408
|
+
Data: { ID: entityId },
|
|
409
|
+
});
|
|
410
|
+
},
|
|
411
|
+
);
|
|
412
|
+
|
|
413
|
+
entities
|
|
414
|
+
.command("update")
|
|
415
|
+
.description("Update schema or metadata of a Data Fabric entity")
|
|
416
|
+
.argument("<id>", "Entity ID")
|
|
417
|
+
.option("-t, --tenant <tenant-name>", "Tenant name")
|
|
418
|
+
.option(
|
|
419
|
+
"-f, --file <path>",
|
|
420
|
+
"Path to JSON file with update options (addFields, updateFields, displayName, description, isRbacEnabled)",
|
|
421
|
+
)
|
|
422
|
+
.option("--body <json>", "Inline JSON update options")
|
|
423
|
+
.trackedAction(
|
|
424
|
+
processContext,
|
|
425
|
+
async (id: string, options: UpdateEntityOptions) => {
|
|
426
|
+
const [parseError, parsed] = await catchError(
|
|
427
|
+
readJsonInput(
|
|
428
|
+
options.file,
|
|
429
|
+
options.body,
|
|
430
|
+
"Provide update options via --file or --body.",
|
|
431
|
+
),
|
|
432
|
+
);
|
|
433
|
+
|
|
434
|
+
if (parseError) {
|
|
435
|
+
OutputFormatter.error({
|
|
436
|
+
Result: RESULTS.Failure,
|
|
437
|
+
Message: "Error parsing update options",
|
|
438
|
+
Instructions: parseError.message,
|
|
439
|
+
});
|
|
440
|
+
processContext.exit(1);
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (
|
|
445
|
+
typeof parsed !== "object" ||
|
|
446
|
+
parsed === null ||
|
|
447
|
+
Array.isArray(parsed)
|
|
448
|
+
) {
|
|
449
|
+
OutputFormatter.error({
|
|
450
|
+
Result: RESULTS.Failure,
|
|
451
|
+
Message: "Update options must be a JSON object",
|
|
452
|
+
Instructions:
|
|
453
|
+
"Provide a JSON object with addFields, updateFields, displayName, description, or isRbacEnabled.",
|
|
454
|
+
});
|
|
455
|
+
processContext.exit(1);
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
const input = parsed as Record<string, unknown>;
|
|
460
|
+
if (input.removeFields !== undefined) {
|
|
461
|
+
OutputFormatter.error({
|
|
462
|
+
Result: RESULTS.Failure,
|
|
463
|
+
Message: "removeFields is not supported",
|
|
464
|
+
Instructions:
|
|
465
|
+
"Removing fields is not supported at this time. Use addFields or updateFields instead.",
|
|
466
|
+
});
|
|
467
|
+
processContext.exit(1);
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
if (Array.isArray(input.addFields)) {
|
|
472
|
+
const hasInvalidField = (input.addFields as unknown[]).some(
|
|
473
|
+
(f) =>
|
|
474
|
+
typeof f !== "object" ||
|
|
475
|
+
f === null ||
|
|
476
|
+
typeof (f as Record<string, unknown>).fieldName !==
|
|
477
|
+
"string",
|
|
478
|
+
);
|
|
479
|
+
if (hasInvalidField) {
|
|
480
|
+
OutputFormatter.error({
|
|
481
|
+
Result: RESULTS.Failure,
|
|
482
|
+
Message:
|
|
483
|
+
"Each field in addFields must include a 'fieldName' string",
|
|
484
|
+
Instructions:
|
|
485
|
+
'Example: {"fieldName":"title","type":"STRING"}',
|
|
486
|
+
});
|
|
487
|
+
processContext.exit(1);
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
if (hasInvalidFieldType(input.addFields as unknown[])) {
|
|
492
|
+
OutputFormatter.error({
|
|
493
|
+
Result: RESULTS.Failure,
|
|
494
|
+
Message: "Invalid field type in addFields",
|
|
495
|
+
Instructions: `Valid types: ${VALID_FIELD_TYPES_LIST}`,
|
|
496
|
+
});
|
|
497
|
+
processContext.exit(1);
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
if (Array.isArray(input.updateFields)) {
|
|
503
|
+
const hasInvalidField = (
|
|
504
|
+
input.updateFields as unknown[]
|
|
505
|
+
).some(
|
|
506
|
+
(f) =>
|
|
507
|
+
typeof f !== "object" ||
|
|
508
|
+
f === null ||
|
|
509
|
+
typeof (f as Record<string, unknown>).id !==
|
|
510
|
+
"string",
|
|
511
|
+
);
|
|
512
|
+
if (hasInvalidField) {
|
|
513
|
+
OutputFormatter.error({
|
|
514
|
+
Result: RESULTS.Failure,
|
|
515
|
+
Message:
|
|
516
|
+
"Each field in updateFields must include an 'id' string",
|
|
517
|
+
Instructions:
|
|
518
|
+
'Use \'df entities get <entityId>\' to find field IDs. Example: {"id":"<fieldId>","displayName":"Total Amount","isRequired":true}',
|
|
519
|
+
});
|
|
520
|
+
processContext.exit(1);
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
const [clientError, sdk] = await catchError(
|
|
526
|
+
createDataFabricClient(options.tenant),
|
|
527
|
+
);
|
|
528
|
+
|
|
529
|
+
if (clientError) {
|
|
530
|
+
OutputFormatter.error({
|
|
531
|
+
Result: RESULTS.Failure,
|
|
532
|
+
Message: "Error connecting to Data Fabric",
|
|
533
|
+
Instructions: await extractErrorMessage(clientError),
|
|
534
|
+
});
|
|
535
|
+
processContext.exit(1);
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
const entityService: EntityServiceModel = sdk.entities;
|
|
540
|
+
const [updateError] = await catchError(
|
|
541
|
+
entityService.updateById(
|
|
542
|
+
id,
|
|
543
|
+
input as EntityUpdateByIdOptions,
|
|
544
|
+
),
|
|
545
|
+
);
|
|
546
|
+
|
|
547
|
+
if (updateError) {
|
|
548
|
+
OutputFormatter.error({
|
|
549
|
+
Result: RESULTS.Failure,
|
|
550
|
+
Message: "Error updating entity",
|
|
551
|
+
Instructions: await extractErrorMessage(updateError),
|
|
552
|
+
});
|
|
553
|
+
processContext.exit(1);
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
OutputFormatter.success({
|
|
558
|
+
Result: RESULTS.Success,
|
|
559
|
+
Code: "EntityUpdated",
|
|
560
|
+
Data: { ID: id },
|
|
561
|
+
});
|
|
562
|
+
},
|
|
563
|
+
);
|
|
564
|
+
};
|