@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.
@@ -11,8 +11,8 @@ import { getFileSystem } from "@uipath/filesystem";
11
11
  import type { EntityRecord } from "@uipath/uipath-typescript";
12
12
  import type { Command } from "commander";
13
13
  import { readFileBinary, readJsonInput } from "../utils/input";
14
- import { extractCursorValue } from "../utils/pagination";
15
- import { createDataFabricClient } from "../utils/sdk-client";
14
+ import { fail } from "../utils/output";
15
+ import { connectOrFail } from "../utils/sdk-client";
16
16
 
17
17
  interface ListOptions {
18
18
  tenant?: string;
@@ -62,14 +62,13 @@ interface BatchResult {
62
62
 
63
63
  const RECORDS_LIST_EXAMPLES: CommandExample[] = [
64
64
  {
65
- Description: "List records in an entity",
65
+ Description: "List records in an entity.",
66
66
  Command:
67
67
  "uip df records list a1b2c3d4-0000-0000-0000-000000000001 --limit 2",
68
68
  Output: {
69
69
  Code: "RecordList",
70
70
  Data: {
71
- TotalCount: 2,
72
- Records: [
71
+ items: [
73
72
  {
74
73
  Id: "b2c3d4e5-0000-0000-0000-000000000001",
75
74
  amount: 1500,
@@ -79,7 +78,8 @@ const RECORDS_LIST_EXAMPLES: CommandExample[] = [
79
78
  amount: 2750,
80
79
  },
81
80
  ],
82
- HasNextPage: false,
81
+ totalCount: 2,
82
+ hasNextPage: false,
83
83
  },
84
84
  },
85
85
  },
@@ -118,9 +118,9 @@ const RECORDS_INSERT_EXAMPLES: CommandExample[] = [
118
118
  {
119
119
  Description:
120
120
  "Insert a record into an entity that has choice-set and relationship fields. " +
121
- "CHOICE_SET_SINGLE → pass the choice value's 'NumberId' (integer, NOT the Name string — look it up via 'df choice-sets get <id>'). " +
122
- "CHOICE_SET_MULTIPLE → pass an array of NumberId integers. " +
123
- "RELATIONSHIP → always pass the target record's Id (UUID), even if the field was declared with a 'referenceFieldName' other than 'Id' (the referenceFieldName configures the join, not the stored value).",
121
+ "CHOICE_SET_SINGLE → pass the choice value's 'numberId' (integer, NOT the name string — look it up via 'df choice-sets list-values <id>'). " +
122
+ "CHOICE_SET_MULTIPLE → pass an array of numberId integers. " +
123
+ "RELATIONSHIP → always pass the target record's Id (UUID), regardless of which 'referenceFieldId' the schema uses for the join (the referenceFieldId configures the join, not the stored value).",
124
124
  Command:
125
125
  'uip df records insert a1b2c3d4-0000-0000-0000-000000000004 --body \'{"category":0,"tags":[1,3],"submitter":"e1f2a3b4-0000-0000-0000-000000000001","amount":250}\'',
126
126
  Output: {
@@ -201,58 +201,36 @@ export const registerRecordsCommand = (program: Command) => {
201
201
  async (entityId: string, options: ListOptions) => {
202
202
  const pageSize = Number(options.limit);
203
203
  if (Number.isNaN(pageSize) || pageSize < 1) {
204
- OutputFormatter.error({
205
- Result: RESULTS.Failure,
206
- Message: "Invalid --limit value",
207
- Instructions: "Provide a positive integer for --limit.",
208
- });
209
- processContext.exit(1);
210
- return;
204
+ return fail(
205
+ "Invalid --limit value",
206
+ "Provide a positive integer for --limit.",
207
+ );
211
208
  }
212
209
 
213
210
  if (
214
211
  options.cursor !== undefined &&
215
212
  options.offset !== undefined
216
213
  ) {
217
- OutputFormatter.error({
218
- Result: RESULTS.Failure,
219
- Message: "--offset and --cursor are mutually exclusive",
220
- Instructions:
221
- "Use --offset to jump to a position by record count, or --cursor to continue from a previous response.",
222
- });
223
- processContext.exit(1);
224
- return;
214
+ return fail(
215
+ "--offset and --cursor are mutually exclusive",
216
+ "Use --offset to jump to a position by record count, or --cursor to continue from a previous response.",
217
+ );
225
218
  }
226
219
 
227
220
  let jumpToPage: number | undefined;
228
221
  if (options.offset !== undefined) {
229
222
  const offsetValue = Number(options.offset);
230
223
  if (Number.isNaN(offsetValue) || offsetValue < 0) {
231
- OutputFormatter.error({
232
- Result: RESULTS.Failure,
233
- Message: "Invalid --offset value",
234
- Instructions:
235
- "Provide a non-negative integer for --offset.",
236
- });
237
- processContext.exit(1);
238
- return;
224
+ return fail(
225
+ "Invalid --offset value",
226
+ "Provide a non-negative integer for --offset.",
227
+ );
239
228
  }
240
229
  jumpToPage = Math.floor(offsetValue / pageSize) + 1;
241
230
  }
242
231
 
243
- const [clientError, sdk] = await catchError(
244
- createDataFabricClient(options.tenant),
245
- );
246
-
247
- if (clientError) {
248
- OutputFormatter.error({
249
- Result: RESULTS.Failure,
250
- Message: "Error connecting to Data Fabric",
251
- Instructions: await extractErrorMessage(clientError),
252
- });
253
- processContext.exit(1);
254
- return;
255
- }
232
+ const sdk = await connectOrFail(options.tenant);
233
+ if (!sdk) return;
256
234
 
257
235
  const [listError, result] = await catchError(
258
236
  sdk.entities.getAllRecords(entityId, {
@@ -265,42 +243,16 @@ export const registerRecordsCommand = (program: Command) => {
265
243
  );
266
244
 
267
245
  if (listError) {
268
- OutputFormatter.error({
269
- Result: RESULTS.Failure,
270
- Message: "Error listing records",
271
- Instructions: await extractErrorMessage(listError),
272
- });
273
- processContext.exit(1);
274
- return;
246
+ return fail(
247
+ "Error listing records",
248
+ await extractErrorMessage(listError),
249
+ );
275
250
  }
276
251
 
277
- const r = result as {
278
- items: unknown[];
279
- totalCount?: number;
280
- hasNextPage?: boolean;
281
- nextCursor?: unknown;
282
- currentPage?: number;
283
- totalPages?: number;
284
- };
285
- const nextCursor = extractCursorValue(r.nextCursor);
286
-
287
252
  OutputFormatter.success({
288
253
  Result: RESULTS.Success,
289
254
  Code: "RecordList",
290
- Data: {
291
- TotalCount: r.totalCount ?? r.items.length,
292
- Records: r.items,
293
- HasNextPage: r.hasNextPage ?? false,
294
- ...(nextCursor !== undefined && {
295
- NextCursor: nextCursor,
296
- }),
297
- ...(r.currentPage !== undefined && {
298
- CurrentPage: r.currentPage,
299
- }),
300
- ...(r.totalPages !== undefined && {
301
- TotalPages: r.totalPages,
302
- }),
303
- },
255
+ Data: result,
304
256
  });
305
257
  },
306
258
  );
@@ -317,43 +269,25 @@ export const registerRecordsCommand = (program: Command) => {
317
269
  .trackedAction(
318
270
  processContext,
319
271
  async (entityId: string, recordId: string, options: GetOptions) => {
320
- const [clientError, sdk] = await catchError(
321
- createDataFabricClient(options.tenant),
322
- );
323
-
324
- if (clientError) {
325
- OutputFormatter.error({
326
- Result: RESULTS.Failure,
327
- Message: "Error connecting to Data Fabric",
328
- Instructions: await extractErrorMessage(clientError),
329
- });
330
- processContext.exit(1);
331
- return;
332
- }
272
+ const sdk = await connectOrFail(options.tenant);
273
+ if (!sdk) return;
333
274
 
334
275
  const [getError, record] = await catchError(
335
276
  sdk.entities.getRecordById(entityId, recordId),
336
277
  );
337
278
 
338
279
  if (getError) {
339
- OutputFormatter.error({
340
- Result: RESULTS.Failure,
341
- Message: `Error getting record '${recordId}'`,
342
- Instructions: await extractErrorMessage(getError),
343
- });
344
- processContext.exit(1);
345
- return;
280
+ return fail(
281
+ `Error getting record '${recordId}'`,
282
+ await extractErrorMessage(getError),
283
+ );
346
284
  }
347
285
 
348
286
  if (!record) {
349
- OutputFormatter.error({
350
- Result: RESULTS.Failure,
351
- Message: `Record '${recordId}' not found in entity '${entityId}'`,
352
- Instructions:
353
- "Verify the record ID exists. Use 'df records list' to see available records.",
354
- });
355
- processContext.exit(1);
356
- return;
287
+ return fail(
288
+ `Record '${recordId}' not found in entity '${entityId}'`,
289
+ "Verify the record ID exists. Use 'df records list' to see available records.",
290
+ );
357
291
  }
358
292
 
359
293
  OutputFormatter.success({
@@ -388,28 +322,11 @@ export const registerRecordsCommand = (program: Command) => {
388
322
  );
389
323
 
390
324
  if (parseError) {
391
- OutputFormatter.error({
392
- Result: RESULTS.Failure,
393
- Message: "Error parsing input data",
394
- Instructions: parseError.message,
395
- });
396
- processContext.exit(1);
397
- return;
325
+ return fail("Error parsing input data", parseError.message);
398
326
  }
399
327
 
400
- const [clientError, sdk] = await catchError(
401
- createDataFabricClient(options.tenant),
402
- );
403
-
404
- if (clientError) {
405
- OutputFormatter.error({
406
- Result: RESULTS.Failure,
407
- Message: "Error connecting to Data Fabric",
408
- Instructions: await extractErrorMessage(clientError),
409
- });
410
- processContext.exit(1);
411
- return;
412
- }
328
+ const sdk = await connectOrFail(options.tenant);
329
+ if (!sdk) return;
413
330
 
414
331
  const data = rawData as
415
332
  | Record<string, unknown>
@@ -422,14 +339,10 @@ export const registerRecordsCommand = (program: Command) => {
422
339
  );
423
340
 
424
341
  if (insertError) {
425
- OutputFormatter.error({
426
- Result: RESULTS.Failure,
427
- Message: "Error inserting record",
428
- Instructions:
429
- await extractErrorMessage(insertError),
430
- });
431
- processContext.exit(1);
432
- return;
342
+ return fail(
343
+ "Error inserting record",
344
+ await extractErrorMessage(insertError),
345
+ );
433
346
  }
434
347
 
435
348
  OutputFormatter.success({
@@ -443,14 +356,10 @@ export const registerRecordsCommand = (program: Command) => {
443
356
  );
444
357
 
445
358
  if (insertError) {
446
- OutputFormatter.error({
447
- Result: RESULTS.Failure,
448
- Message: "Error inserting records",
449
- Instructions:
450
- await extractErrorMessage(insertError),
451
- });
452
- processContext.exit(1);
453
- return;
359
+ return fail(
360
+ "Error inserting records",
361
+ await extractErrorMessage(insertError),
362
+ );
454
363
  }
455
364
 
456
365
  const r = result as BatchResult;
@@ -496,28 +405,11 @@ export const registerRecordsCommand = (program: Command) => {
496
405
  );
497
406
 
498
407
  if (parseError) {
499
- OutputFormatter.error({
500
- Result: RESULTS.Failure,
501
- Message: "Error parsing input data",
502
- Instructions: parseError.message,
503
- });
504
- processContext.exit(1);
505
- return;
408
+ return fail("Error parsing input data", parseError.message);
506
409
  }
507
410
 
508
- const [clientError, sdk] = await catchError(
509
- createDataFabricClient(options.tenant),
510
- );
511
-
512
- if (clientError) {
513
- OutputFormatter.error({
514
- Result: RESULTS.Failure,
515
- Message: "Error connecting to Data Fabric",
516
- Instructions: await extractErrorMessage(clientError),
517
- });
518
- processContext.exit(1);
519
- return;
520
- }
411
+ const sdk = await connectOrFail(options.tenant);
412
+ if (!sdk) return;
521
413
 
522
414
  const data = rawData as
523
415
  | Record<string, unknown>
@@ -529,14 +421,10 @@ export const registerRecordsCommand = (program: Command) => {
529
421
  const recordId =
530
422
  record.Id !== undefined ? record.Id : record.id;
531
423
  if (recordId === undefined || recordId === null) {
532
- OutputFormatter.error({
533
- Result: RESULTS.Failure,
534
- Message: "Record must include an 'Id' field",
535
- Instructions:
536
- "Provide the record ID in the JSON data.",
537
- });
538
- processContext.exit(1);
539
- return;
424
+ return fail(
425
+ "Record must include an 'Id' field",
426
+ "Provide the record ID in the JSON data.",
427
+ );
540
428
  }
541
429
 
542
430
  const [updateError, result] = await catchError(
@@ -548,14 +436,10 @@ export const registerRecordsCommand = (program: Command) => {
548
436
  );
549
437
 
550
438
  if (updateError) {
551
- OutputFormatter.error({
552
- Result: RESULTS.Failure,
553
- Message: "Error updating record",
554
- Instructions:
555
- await extractErrorMessage(updateError),
556
- });
557
- processContext.exit(1);
558
- return;
439
+ return fail(
440
+ "Error updating record",
441
+ await extractErrorMessage(updateError),
442
+ );
559
443
  }
560
444
 
561
445
  OutputFormatter.success({
@@ -568,14 +452,10 @@ export const registerRecordsCommand = (program: Command) => {
568
452
  (r) => r.Id == null && r.id == null,
569
453
  );
570
454
  if (missingId) {
571
- OutputFormatter.error({
572
- Result: RESULTS.Failure,
573
- Message: "All records must include an 'Id' field",
574
- Instructions:
575
- "Provide the record ID in each JSON object.",
576
- });
577
- processContext.exit(1);
578
- return;
455
+ return fail(
456
+ "All records must include an 'Id' field",
457
+ "Provide the record ID in each JSON object.",
458
+ );
579
459
  }
580
460
 
581
461
  const [updateError, result] = await catchError(
@@ -586,14 +466,10 @@ export const registerRecordsCommand = (program: Command) => {
586
466
  );
587
467
 
588
468
  if (updateError) {
589
- OutputFormatter.error({
590
- Result: RESULTS.Failure,
591
- Message: "Error updating records",
592
- Instructions:
593
- await extractErrorMessage(updateError),
594
- });
595
- processContext.exit(1);
596
- return;
469
+ return fail(
470
+ "Error updating records",
471
+ await extractErrorMessage(updateError),
472
+ );
597
473
  }
598
474
 
599
475
  const r = result as BatchResult;
@@ -653,41 +529,30 @@ export const registerRecordsCommand = (program: Command) => {
653
529
  async (entityId: string, options: QueryOptions) => {
654
530
  const pageSize = Number(options.limit);
655
531
  if (Number.isNaN(pageSize) || pageSize < 1) {
656
- OutputFormatter.error({
657
- Result: RESULTS.Failure,
658
- Message: "Invalid --limit value",
659
- Instructions: "Provide a positive integer for --limit.",
660
- });
661
- processContext.exit(1);
662
- return;
532
+ return fail(
533
+ "Invalid --limit value",
534
+ "Provide a positive integer for --limit.",
535
+ );
663
536
  }
664
537
 
665
538
  if (
666
539
  options.cursor !== undefined &&
667
540
  options.offset !== undefined
668
541
  ) {
669
- OutputFormatter.error({
670
- Result: RESULTS.Failure,
671
- Message: "--offset and --cursor are mutually exclusive",
672
- Instructions:
673
- "Use --offset to jump to a position by record count, or --cursor to continue from a previous response.",
674
- });
675
- processContext.exit(1);
676
- return;
542
+ return fail(
543
+ "--offset and --cursor are mutually exclusive",
544
+ "Use --offset to jump to a position by record count, or --cursor to continue from a previous response.",
545
+ );
677
546
  }
678
547
 
679
548
  let jumpToPage: number | undefined;
680
549
  if (options.offset !== undefined) {
681
550
  const offsetValue = Number(options.offset);
682
551
  if (Number.isNaN(offsetValue) || offsetValue < 0) {
683
- OutputFormatter.error({
684
- Result: RESULTS.Failure,
685
- Message: "Invalid --offset value",
686
- Instructions:
687
- "Provide a non-negative integer for --offset.",
688
- });
689
- processContext.exit(1);
690
- return;
552
+ return fail(
553
+ "Invalid --offset value",
554
+ "Provide a non-negative integer for --offset.",
555
+ );
691
556
  }
692
557
  jumpToPage = Math.floor(offsetValue / pageSize) + 1;
693
558
  }
@@ -702,44 +567,26 @@ export const registerRecordsCommand = (program: Command) => {
702
567
  ),
703
568
  );
704
569
  if (parseError) {
705
- OutputFormatter.error({
706
- Result: RESULTS.Failure,
707
- Message: "Error parsing query options",
708
- Instructions: parseError.message,
709
- });
710
- processContext.exit(1);
711
- return;
570
+ return fail(
571
+ "Error parsing query options",
572
+ parseError.message,
573
+ );
712
574
  }
713
575
  if (
714
576
  typeof parsed !== "object" ||
715
577
  parsed === null ||
716
578
  Array.isArray(parsed)
717
579
  ) {
718
- OutputFormatter.error({
719
- Result: RESULTS.Failure,
720
- Message: "Query options must be a JSON object",
721
- Instructions:
722
- "Provide a JSON object (not an array) with filterGroup, selectedFields, sortOptions, aggregates, or groupBy.",
723
- });
724
- processContext.exit(1);
725
- return;
580
+ return fail(
581
+ "Query options must be a JSON object",
582
+ "Provide a JSON object (not an array) with filterGroup, selectedFields, sortOptions, aggregates, or groupBy.",
583
+ );
726
584
  }
727
585
  queryBody = parsed as Record<string, unknown>;
728
586
  }
729
587
 
730
- const [clientError, sdk] = await catchError(
731
- createDataFabricClient(options.tenant),
732
- );
733
-
734
- if (clientError) {
735
- OutputFormatter.error({
736
- Result: RESULTS.Failure,
737
- Message: "Error connecting to Data Fabric",
738
- Instructions: await extractErrorMessage(clientError),
739
- });
740
- processContext.exit(1);
741
- return;
742
- }
588
+ const sdk = await connectOrFail(options.tenant);
589
+ if (!sdk) return;
743
590
 
744
591
  const [queryError, result] = await catchError(
745
592
  sdk.entities.queryRecordsById(entityId, {
@@ -753,42 +600,16 @@ export const registerRecordsCommand = (program: Command) => {
753
600
  );
754
601
 
755
602
  if (queryError) {
756
- OutputFormatter.error({
757
- Result: RESULTS.Failure,
758
- Message: "Error querying records",
759
- Instructions: await extractErrorMessage(queryError),
760
- });
761
- processContext.exit(1);
762
- return;
603
+ return fail(
604
+ "Error querying records",
605
+ await extractErrorMessage(queryError),
606
+ );
763
607
  }
764
608
 
765
- const r = result as {
766
- items: unknown[];
767
- totalCount?: number;
768
- hasNextPage?: boolean;
769
- nextCursor?: unknown;
770
- currentPage?: number;
771
- totalPages?: number;
772
- };
773
- const nextCursor = extractCursorValue(r.nextCursor);
774
-
775
609
  OutputFormatter.success({
776
610
  Result: RESULTS.Success,
777
611
  Code: "RecordQuery",
778
- Data: {
779
- TotalCount: r.totalCount ?? r.items.length,
780
- Records: r.items,
781
- HasNextPage: r.hasNextPage ?? false,
782
- ...(nextCursor !== undefined && {
783
- NextCursor: nextCursor,
784
- }),
785
- ...(r.currentPage !== undefined && {
786
- CurrentPage: r.currentPage,
787
- }),
788
- ...(r.totalPages !== undefined && {
789
- TotalPages: r.totalPages,
790
- }),
791
- },
612
+ Data: result,
792
613
  });
793
614
  },
794
615
  );
@@ -805,13 +626,10 @@ export const registerRecordsCommand = (program: Command) => {
805
626
  processContext,
806
627
  async (entityId: string, options: ImportOptions) => {
807
628
  if (options.file === undefined) {
808
- OutputFormatter.error({
809
- Result: RESULTS.Failure,
810
- Message: "A CSV file path is required",
811
- Instructions: "Provide a CSV file path via --file.",
812
- });
813
- processContext.exit(1);
814
- return;
629
+ return fail(
630
+ "A CSV file path is required",
631
+ "Provide a CSV file path via --file.",
632
+ );
815
633
  }
816
634
 
817
635
  const [readError, fileContent] = await catchError(
@@ -819,28 +637,11 @@ export const registerRecordsCommand = (program: Command) => {
819
637
  );
820
638
 
821
639
  if (readError) {
822
- OutputFormatter.error({
823
- Result: RESULTS.Failure,
824
- Message: "Error reading CSV file",
825
- Instructions: readError.message,
826
- });
827
- processContext.exit(1);
828
- return;
640
+ return fail("Error reading CSV file", readError.message);
829
641
  }
830
642
 
831
- const [clientError, sdk] = await catchError(
832
- createDataFabricClient(options.tenant),
833
- );
834
-
835
- if (clientError) {
836
- OutputFormatter.error({
837
- Result: RESULTS.Failure,
838
- Message: "Error connecting to Data Fabric",
839
- Instructions: await extractErrorMessage(clientError),
840
- });
841
- processContext.exit(1);
842
- return;
843
- }
643
+ const sdk = await connectOrFail(options.tenant);
644
+ if (!sdk) return;
844
645
 
845
646
  const fs = getFileSystem();
846
647
  const fileName = fs.path.basename(options.file) || "import.csv";
@@ -854,13 +655,10 @@ export const registerRecordsCommand = (program: Command) => {
854
655
  );
855
656
 
856
657
  if (importError) {
857
- OutputFormatter.error({
858
- Result: RESULTS.Failure,
859
- Message: "Error importing records",
860
- Instructions: await extractErrorMessage(importError),
861
- });
862
- processContext.exit(1);
863
- return;
658
+ return fail(
659
+ "Error importing records",
660
+ await extractErrorMessage(importError),
661
+ );
864
662
  }
865
663
 
866
664
  const r = result as {
@@ -899,32 +697,18 @@ export const registerRecordsCommand = (program: Command) => {
899
697
  recordIds: string[],
900
698
  options: DeleteOptions,
901
699
  ) => {
902
- const [clientError, sdk] = await catchError(
903
- createDataFabricClient(options.tenant),
904
- );
905
-
906
- if (clientError) {
907
- OutputFormatter.error({
908
- Result: RESULTS.Failure,
909
- Message: "Error connecting to Data Fabric",
910
- Instructions: await extractErrorMessage(clientError),
911
- });
912
- processContext.exit(1);
913
- return;
914
- }
700
+ const sdk = await connectOrFail(options.tenant);
701
+ if (!sdk) return;
915
702
 
916
703
  const [deleteError, result] = await catchError(
917
704
  sdk.entities.deleteRecordsById(entityId, recordIds),
918
705
  );
919
706
 
920
707
  if (deleteError) {
921
- OutputFormatter.error({
922
- Result: RESULTS.Failure,
923
- Message: "Error deleting records",
924
- Instructions: await extractErrorMessage(deleteError),
925
- });
926
- processContext.exit(1);
927
- return;
708
+ return fail(
709
+ "Error deleting records",
710
+ await extractErrorMessage(deleteError),
711
+ );
928
712
  }
929
713
 
930
714
  const r = result as BatchResult;