@uipath/data-fabric-tool 1.1.0 → 1.196.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.
@@ -9,10 +9,10 @@ import {
9
9
  } from "@uipath/common";
10
10
  import { getFileSystem } from "@uipath/filesystem";
11
11
  import type { EntityRecord } from "@uipath/uipath-typescript";
12
- import type { Command } from "commander";
12
+ import { type Command, Option } 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, requireDestructiveConfirmation } from "../utils/output";
15
+ import { connectOrFail } from "../utils/sdk-client";
16
16
 
17
17
  interface ListOptions {
18
18
  tenant?: string;
@@ -39,6 +39,9 @@ interface UpdateOptions {
39
39
 
40
40
  interface DeleteOptions {
41
41
  tenant?: string;
42
+ yes?: boolean;
43
+ confirm?: boolean;
44
+ reason?: string;
42
45
  }
43
46
 
44
47
  interface QueryOptions {
@@ -62,14 +65,13 @@ interface BatchResult {
62
65
 
63
66
  const RECORDS_LIST_EXAMPLES: CommandExample[] = [
64
67
  {
65
- Description: "List records in an entity",
68
+ Description: "List records in an entity.",
66
69
  Command:
67
70
  "uip df records list a1b2c3d4-0000-0000-0000-000000000001 --limit 2",
68
71
  Output: {
69
72
  Code: "RecordList",
70
73
  Data: {
71
- TotalCount: 2,
72
- Records: [
74
+ items: [
73
75
  {
74
76
  Id: "b2c3d4e5-0000-0000-0000-000000000001",
75
77
  amount: 1500,
@@ -79,7 +81,8 @@ const RECORDS_LIST_EXAMPLES: CommandExample[] = [
79
81
  amount: 2750,
80
82
  },
81
83
  ],
82
- HasNextPage: false,
84
+ totalCount: 2,
85
+ hasNextPage: false,
83
86
  },
84
87
  },
85
88
  },
@@ -118,9 +121,9 @@ const RECORDS_INSERT_EXAMPLES: CommandExample[] = [
118
121
  {
119
122
  Description:
120
123
  "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).",
124
+ "CHOICE_SET_SINGLE → pass the choice value's 'numberId' (integer, NOT the name string — look it up via 'df choice-sets list-values <id>'). " +
125
+ "CHOICE_SET_MULTIPLE → pass an array of numberId integers. " +
126
+ "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
127
  Command:
125
128
  'uip df records insert a1b2c3d4-0000-0000-0000-000000000004 --body \'{"category":0,"tags":[1,3],"submitter":"e1f2a3b4-0000-0000-0000-000000000001","amount":250}\'',
126
129
  Output: {
@@ -201,58 +204,36 @@ export const registerRecordsCommand = (program: Command) => {
201
204
  async (entityId: string, options: ListOptions) => {
202
205
  const pageSize = Number(options.limit);
203
206
  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;
207
+ return fail(
208
+ "Invalid --limit value",
209
+ "Provide a positive integer for --limit.",
210
+ );
211
211
  }
212
212
 
213
213
  if (
214
214
  options.cursor !== undefined &&
215
215
  options.offset !== undefined
216
216
  ) {
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;
217
+ return fail(
218
+ "--offset and --cursor are mutually exclusive",
219
+ "Use --offset to jump to a position by record count, or --cursor to continue from a previous response.",
220
+ );
225
221
  }
226
222
 
227
223
  let jumpToPage: number | undefined;
228
224
  if (options.offset !== undefined) {
229
225
  const offsetValue = Number(options.offset);
230
226
  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;
227
+ return fail(
228
+ "Invalid --offset value",
229
+ "Provide a non-negative integer for --offset.",
230
+ );
239
231
  }
240
232
  jumpToPage = Math.floor(offsetValue / pageSize) + 1;
241
233
  }
242
234
 
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
- }
235
+ const sdk = await connectOrFail(options.tenant);
236
+ if (!sdk) return;
256
237
 
257
238
  const [listError, result] = await catchError(
258
239
  sdk.entities.getAllRecords(entityId, {
@@ -265,42 +246,16 @@ export const registerRecordsCommand = (program: Command) => {
265
246
  );
266
247
 
267
248
  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;
249
+ return fail(
250
+ "Error listing records",
251
+ await extractErrorMessage(listError),
252
+ );
275
253
  }
276
254
 
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
255
  OutputFormatter.success({
288
256
  Result: RESULTS.Success,
289
257
  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
- },
258
+ Data: result,
304
259
  });
305
260
  },
306
261
  );
@@ -317,43 +272,25 @@ export const registerRecordsCommand = (program: Command) => {
317
272
  .trackedAction(
318
273
  processContext,
319
274
  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
- }
275
+ const sdk = await connectOrFail(options.tenant);
276
+ if (!sdk) return;
333
277
 
334
278
  const [getError, record] = await catchError(
335
279
  sdk.entities.getRecordById(entityId, recordId),
336
280
  );
337
281
 
338
282
  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;
283
+ return fail(
284
+ `Error getting record '${recordId}'`,
285
+ await extractErrorMessage(getError),
286
+ );
346
287
  }
347
288
 
348
289
  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;
290
+ return fail(
291
+ `Record '${recordId}' not found in entity '${entityId}'`,
292
+ "Verify the record ID exists. Use 'df records list' to see available records.",
293
+ );
357
294
  }
358
295
 
359
296
  OutputFormatter.success({
@@ -377,7 +314,7 @@ export const registerRecordsCommand = (program: Command) => {
377
314
  )
378
315
  .option(
379
316
  "--body <json>",
380
- "Inline JSON record data (object or array of objects)",
317
+ "Inline JSON record data (object or array of objects; use `-` to read from stdin)",
381
318
  )
382
319
  .examples(RECORDS_INSERT_EXAMPLES)
383
320
  .trackedAction(
@@ -388,28 +325,11 @@ export const registerRecordsCommand = (program: Command) => {
388
325
  );
389
326
 
390
327
  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;
328
+ return fail("Error parsing input data", parseError.message);
398
329
  }
399
330
 
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
- }
331
+ const sdk = await connectOrFail(options.tenant);
332
+ if (!sdk) return;
413
333
 
414
334
  const data = rawData as
415
335
  | Record<string, unknown>
@@ -422,14 +342,10 @@ export const registerRecordsCommand = (program: Command) => {
422
342
  );
423
343
 
424
344
  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;
345
+ return fail(
346
+ "Error inserting record",
347
+ await extractErrorMessage(insertError),
348
+ );
433
349
  }
434
350
 
435
351
  OutputFormatter.success({
@@ -443,14 +359,10 @@ export const registerRecordsCommand = (program: Command) => {
443
359
  );
444
360
 
445
361
  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;
362
+ return fail(
363
+ "Error inserting records",
364
+ await extractErrorMessage(insertError),
365
+ );
454
366
  }
455
367
 
456
368
  const r = result as BatchResult;
@@ -485,7 +397,7 @@ export const registerRecordsCommand = (program: Command) => {
485
397
  )
486
398
  .option(
487
399
  "--body <json>",
488
- "Inline JSON record data (must include Id field)",
400
+ "Inline JSON record data (must include Id field; use `-` to read from stdin)",
489
401
  )
490
402
  .examples(RECORDS_UPDATE_EXAMPLES)
491
403
  .trackedAction(
@@ -496,28 +408,11 @@ export const registerRecordsCommand = (program: Command) => {
496
408
  );
497
409
 
498
410
  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;
411
+ return fail("Error parsing input data", parseError.message);
506
412
  }
507
413
 
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
- }
414
+ const sdk = await connectOrFail(options.tenant);
415
+ if (!sdk) return;
521
416
 
522
417
  const data = rawData as
523
418
  | Record<string, unknown>
@@ -529,14 +424,10 @@ export const registerRecordsCommand = (program: Command) => {
529
424
  const recordId =
530
425
  record.Id !== undefined ? record.Id : record.id;
531
426
  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;
427
+ return fail(
428
+ "Record must include an 'Id' field",
429
+ "Provide the record ID in the JSON data.",
430
+ );
540
431
  }
541
432
 
542
433
  const [updateError, result] = await catchError(
@@ -548,14 +439,10 @@ export const registerRecordsCommand = (program: Command) => {
548
439
  );
549
440
 
550
441
  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;
442
+ return fail(
443
+ "Error updating record",
444
+ await extractErrorMessage(updateError),
445
+ );
559
446
  }
560
447
 
561
448
  OutputFormatter.success({
@@ -568,14 +455,10 @@ export const registerRecordsCommand = (program: Command) => {
568
455
  (r) => r.Id == null && r.id == null,
569
456
  );
570
457
  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;
458
+ return fail(
459
+ "All records must include an 'Id' field",
460
+ "Provide the record ID in each JSON object.",
461
+ );
579
462
  }
580
463
 
581
464
  const [updateError, result] = await catchError(
@@ -586,14 +469,10 @@ export const registerRecordsCommand = (program: Command) => {
586
469
  );
587
470
 
588
471
  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;
472
+ return fail(
473
+ "Error updating records",
474
+ await extractErrorMessage(updateError),
475
+ );
597
476
  }
598
477
 
599
478
  const r = result as BatchResult;
@@ -633,7 +512,7 @@ export const registerRecordsCommand = (program: Command) => {
633
512
  )
634
513
  .option(
635
514
  "--body <json>",
636
- "Inline JSON query options (filterGroup, selectedFields, sortOptions, aggregates, groupBy)",
515
+ "Inline JSON query options (filterGroup, selectedFields, sortOptions, aggregates, groupBy; use `-` to read from stdin)",
637
516
  )
638
517
  .option(
639
518
  "-l, --limit <number>",
@@ -653,41 +532,30 @@ export const registerRecordsCommand = (program: Command) => {
653
532
  async (entityId: string, options: QueryOptions) => {
654
533
  const pageSize = Number(options.limit);
655
534
  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;
535
+ return fail(
536
+ "Invalid --limit value",
537
+ "Provide a positive integer for --limit.",
538
+ );
663
539
  }
664
540
 
665
541
  if (
666
542
  options.cursor !== undefined &&
667
543
  options.offset !== undefined
668
544
  ) {
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;
545
+ return fail(
546
+ "--offset and --cursor are mutually exclusive",
547
+ "Use --offset to jump to a position by record count, or --cursor to continue from a previous response.",
548
+ );
677
549
  }
678
550
 
679
551
  let jumpToPage: number | undefined;
680
552
  if (options.offset !== undefined) {
681
553
  const offsetValue = Number(options.offset);
682
554
  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;
555
+ return fail(
556
+ "Invalid --offset value",
557
+ "Provide a non-negative integer for --offset.",
558
+ );
691
559
  }
692
560
  jumpToPage = Math.floor(offsetValue / pageSize) + 1;
693
561
  }
@@ -702,44 +570,26 @@ export const registerRecordsCommand = (program: Command) => {
702
570
  ),
703
571
  );
704
572
  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;
573
+ return fail(
574
+ "Error parsing query options",
575
+ parseError.message,
576
+ );
712
577
  }
713
578
  if (
714
579
  typeof parsed !== "object" ||
715
580
  parsed === null ||
716
581
  Array.isArray(parsed)
717
582
  ) {
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;
583
+ return fail(
584
+ "Query options must be a JSON object",
585
+ "Provide a JSON object (not an array) with filterGroup, selectedFields, sortOptions, aggregates, or groupBy.",
586
+ );
726
587
  }
727
588
  queryBody = parsed as Record<string, unknown>;
728
589
  }
729
590
 
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
- }
591
+ const sdk = await connectOrFail(options.tenant);
592
+ if (!sdk) return;
743
593
 
744
594
  const [queryError, result] = await catchError(
745
595
  sdk.entities.queryRecordsById(entityId, {
@@ -753,42 +603,16 @@ export const registerRecordsCommand = (program: Command) => {
753
603
  );
754
604
 
755
605
  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;
606
+ return fail(
607
+ "Error querying records",
608
+ await extractErrorMessage(queryError),
609
+ );
763
610
  }
764
611
 
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
612
  OutputFormatter.success({
776
613
  Result: RESULTS.Success,
777
614
  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
- },
615
+ Data: result,
792
616
  });
793
617
  },
794
618
  );
@@ -805,13 +629,10 @@ export const registerRecordsCommand = (program: Command) => {
805
629
  processContext,
806
630
  async (entityId: string, options: ImportOptions) => {
807
631
  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;
632
+ return fail(
633
+ "A CSV file path is required",
634
+ "Provide a CSV file path via --file.",
635
+ );
815
636
  }
816
637
 
817
638
  const [readError, fileContent] = await catchError(
@@ -819,28 +640,11 @@ export const registerRecordsCommand = (program: Command) => {
819
640
  );
820
641
 
821
642
  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;
643
+ return fail("Error reading CSV file", readError.message);
829
644
  }
830
645
 
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
- }
646
+ const sdk = await connectOrFail(options.tenant);
647
+ if (!sdk) return;
844
648
 
845
649
  const fs = getFileSystem();
846
650
  const fileName = fs.path.basename(options.file) || "import.csv";
@@ -854,13 +658,10 @@ export const registerRecordsCommand = (program: Command) => {
854
658
  );
855
659
 
856
660
  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;
661
+ return fail(
662
+ "Error importing records",
663
+ await extractErrorMessage(importError),
664
+ );
864
665
  }
865
666
 
866
667
  const r = result as {
@@ -891,6 +692,14 @@ export const registerRecordsCommand = (program: Command) => {
891
692
  .addOption(
892
693
  createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>"),
893
694
  )
695
+ .option("-y, --yes", "Acknowledge this is an irreversible operation")
696
+ .addOption(
697
+ new Option("--confirm", "Deprecated alias for --yes").hideHelp(),
698
+ )
699
+ .option(
700
+ "--reason <reason>",
701
+ "Reason for the deletion — echoed back in the response so the caller can log it",
702
+ )
894
703
  .examples(RECORDS_DELETE_EXAMPLES)
895
704
  .trackedAction(
896
705
  processContext,
@@ -899,32 +708,25 @@ export const registerRecordsCommand = (program: Command) => {
899
708
  recordIds: string[],
900
709
  options: DeleteOptions,
901
710
  ) => {
902
- const [clientError, sdk] = await catchError(
903
- createDataFabricClient(options.tenant),
711
+ const reason = requireDestructiveConfirmation(
712
+ options,
713
+ `delete ${recordIds.length} record(s) from entity '${entityId}'`,
714
+ 'Pass --reason "<text>" to record why the records are being deleted.',
904
715
  );
716
+ if (reason === null) return;
905
717
 
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
- }
718
+ const sdk = await connectOrFail(options.tenant);
719
+ if (!sdk) return;
915
720
 
916
721
  const [deleteError, result] = await catchError(
917
722
  sdk.entities.deleteRecordsById(entityId, recordIds),
918
723
  );
919
724
 
920
725
  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;
726
+ return fail(
727
+ "Error deleting records",
728
+ await extractErrorMessage(deleteError),
729
+ );
928
730
  }
929
731
 
930
732
  const r = result as BatchResult;
@@ -937,6 +739,7 @@ export const registerRecordsCommand = (program: Command) => {
937
739
  FailureCount: failureCount,
938
740
  SuccessRecords: r.successRecords ?? [],
939
741
  FailureRecords: r.failureRecords ?? [],
742
+ Reason: reason,
940
743
  },
941
744
  });
942
745
  if (failureCount > 0) {