@uipath/data-fabric-tool 1.0.4 → 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.
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  type CommandExample,
3
3
  catchError,
4
+ createHiddenDeprecatedTenantOption,
4
5
  extractErrorMessage,
5
6
  OutputFormatter,
6
7
  processContext,
@@ -10,7 +11,8 @@ import { getFileSystem } from "@uipath/filesystem";
10
11
  import type { EntityRecord } from "@uipath/uipath-typescript";
11
12
  import type { Command } from "commander";
12
13
  import { readFileBinary, readJsonInput } from "../utils/input";
13
- import { createDataFabricClient } from "../utils/sdk-client";
14
+ import { fail } from "../utils/output";
15
+ import { connectOrFail } from "../utils/sdk-client";
14
16
 
15
17
  interface ListOptions {
16
18
  tenant?: string;
@@ -60,14 +62,13 @@ interface BatchResult {
60
62
 
61
63
  const RECORDS_LIST_EXAMPLES: CommandExample[] = [
62
64
  {
63
- Description: "List records in an entity",
65
+ Description: "List records in an entity.",
64
66
  Command:
65
67
  "uip df records list a1b2c3d4-0000-0000-0000-000000000001 --limit 2",
66
68
  Output: {
67
69
  Code: "RecordList",
68
70
  Data: {
69
- TotalCount: 2,
70
- Records: [
71
+ items: [
71
72
  {
72
73
  Id: "b2c3d4e5-0000-0000-0000-000000000001",
73
74
  amount: 1500,
@@ -77,7 +78,8 @@ const RECORDS_LIST_EXAMPLES: CommandExample[] = [
77
78
  amount: 2750,
78
79
  },
79
80
  ],
80
- HasNextPage: false,
81
+ totalCount: 2,
82
+ hasNextPage: false,
81
83
  },
82
84
  },
83
85
  },
@@ -113,6 +115,25 @@ const RECORDS_INSERT_EXAMPLES: CommandExample[] = [
113
115
  },
114
116
  },
115
117
  },
118
+ {
119
+ Description:
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 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
+ Command:
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
+ Output: {
127
+ Code: "RecordInserted",
128
+ Data: {
129
+ Id: "b2c3d4e5-0000-0000-0000-000000000020",
130
+ category: 0,
131
+ tags: [1, 3],
132
+ submitter: "e1f2a3b4-0000-0000-0000-000000000001",
133
+ amount: 250,
134
+ },
135
+ },
136
+ },
116
137
  ];
117
138
 
118
139
  const RECORDS_UPDATE_EXAMPLES: CommandExample[] = [
@@ -158,7 +179,9 @@ export const registerRecordsCommand = (program: Command) => {
158
179
  .command("list")
159
180
  .description("List records in a Data Fabric entity")
160
181
  .argument("<id>", "Entity ID")
161
- .option("-t, --tenant <tenant-name>", "Tenant name")
182
+ .addOption(
183
+ createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>"),
184
+ )
162
185
  .option(
163
186
  "-l, --limit <number>",
164
187
  "Number of records to return per page",
@@ -178,58 +201,36 @@ export const registerRecordsCommand = (program: Command) => {
178
201
  async (entityId: string, options: ListOptions) => {
179
202
  const pageSize = Number(options.limit);
180
203
  if (Number.isNaN(pageSize) || pageSize < 1) {
181
- OutputFormatter.error({
182
- Result: RESULTS.Failure,
183
- Message: "Invalid --limit value",
184
- Instructions: "Provide a positive integer for --limit.",
185
- });
186
- processContext.exit(1);
187
- return;
204
+ return fail(
205
+ "Invalid --limit value",
206
+ "Provide a positive integer for --limit.",
207
+ );
188
208
  }
189
209
 
190
210
  if (
191
211
  options.cursor !== undefined &&
192
212
  options.offset !== undefined
193
213
  ) {
194
- OutputFormatter.error({
195
- Result: RESULTS.Failure,
196
- Message: "--offset and --cursor are mutually exclusive",
197
- Instructions:
198
- "Use --offset to jump to a position by record count, or --cursor to continue from a previous response.",
199
- });
200
- processContext.exit(1);
201
- 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
+ );
202
218
  }
203
219
 
204
220
  let jumpToPage: number | undefined;
205
221
  if (options.offset !== undefined) {
206
222
  const offsetValue = Number(options.offset);
207
223
  if (Number.isNaN(offsetValue) || offsetValue < 0) {
208
- OutputFormatter.error({
209
- Result: RESULTS.Failure,
210
- Message: "Invalid --offset value",
211
- Instructions:
212
- "Provide a non-negative integer for --offset.",
213
- });
214
- processContext.exit(1);
215
- return;
224
+ return fail(
225
+ "Invalid --offset value",
226
+ "Provide a non-negative integer for --offset.",
227
+ );
216
228
  }
217
229
  jumpToPage = Math.floor(offsetValue / pageSize) + 1;
218
230
  }
219
231
 
220
- const [clientError, sdk] = await catchError(
221
- createDataFabricClient(options.tenant),
222
- );
223
-
224
- if (clientError) {
225
- OutputFormatter.error({
226
- Result: RESULTS.Failure,
227
- Message: "Error connecting to Data Fabric",
228
- Instructions: await extractErrorMessage(clientError),
229
- });
230
- processContext.exit(1);
231
- return;
232
- }
232
+ const sdk = await connectOrFail(options.tenant);
233
+ if (!sdk) return;
233
234
 
234
235
  const [listError, result] = await catchError(
235
236
  sdk.entities.getAllRecords(entityId, {
@@ -242,42 +243,16 @@ export const registerRecordsCommand = (program: Command) => {
242
243
  );
243
244
 
244
245
  if (listError) {
245
- OutputFormatter.error({
246
- Result: RESULTS.Failure,
247
- Message: "Error listing records",
248
- Instructions: await extractErrorMessage(listError),
249
- });
250
- processContext.exit(1);
251
- return;
246
+ return fail(
247
+ "Error listing records",
248
+ await extractErrorMessage(listError),
249
+ );
252
250
  }
253
251
 
254
- const r = result as {
255
- items: unknown[];
256
- totalCount?: number;
257
- hasNextPage?: boolean;
258
- nextCursor?: unknown;
259
- currentPage?: number;
260
- totalPages?: number;
261
- };
262
- const nextCursor = extractCursorValue(r.nextCursor);
263
-
264
252
  OutputFormatter.success({
265
253
  Result: RESULTS.Success,
266
254
  Code: "RecordList",
267
- Data: {
268
- TotalCount: r.totalCount ?? r.items.length,
269
- Records: r.items,
270
- HasNextPage: r.hasNextPage ?? false,
271
- ...(nextCursor !== undefined && {
272
- NextCursor: nextCursor,
273
- }),
274
- ...(r.currentPage !== undefined && {
275
- CurrentPage: r.currentPage,
276
- }),
277
- ...(r.totalPages !== undefined && {
278
- TotalPages: r.totalPages,
279
- }),
280
- },
255
+ Data: result,
281
256
  });
282
257
  },
283
258
  );
@@ -287,48 +262,32 @@ export const registerRecordsCommand = (program: Command) => {
287
262
  .description("Get a single record by ID")
288
263
  .argument("<id>", "Entity ID")
289
264
  .argument("<key>", "Record ID")
290
- .option("-t, --tenant <tenant-name>", "Tenant name")
265
+ .addOption(
266
+ createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>"),
267
+ )
291
268
  .examples(RECORDS_GET_EXAMPLES)
292
269
  .trackedAction(
293
270
  processContext,
294
271
  async (entityId: string, recordId: string, options: GetOptions) => {
295
- const [clientError, sdk] = await catchError(
296
- createDataFabricClient(options.tenant),
297
- );
298
-
299
- if (clientError) {
300
- OutputFormatter.error({
301
- Result: RESULTS.Failure,
302
- Message: "Error connecting to Data Fabric",
303
- Instructions: await extractErrorMessage(clientError),
304
- });
305
- processContext.exit(1);
306
- return;
307
- }
272
+ const sdk = await connectOrFail(options.tenant);
273
+ if (!sdk) return;
308
274
 
309
275
  const [getError, record] = await catchError(
310
276
  sdk.entities.getRecordById(entityId, recordId),
311
277
  );
312
278
 
313
279
  if (getError) {
314
- OutputFormatter.error({
315
- Result: RESULTS.Failure,
316
- Message: `Error getting record '${recordId}'`,
317
- Instructions: await extractErrorMessage(getError),
318
- });
319
- processContext.exit(1);
320
- return;
280
+ return fail(
281
+ `Error getting record '${recordId}'`,
282
+ await extractErrorMessage(getError),
283
+ );
321
284
  }
322
285
 
323
286
  if (!record) {
324
- OutputFormatter.error({
325
- Result: RESULTS.Failure,
326
- Message: `Record '${recordId}' not found in entity '${entityId}'`,
327
- Instructions:
328
- "Verify the record ID exists. Use 'df records list' to see available records.",
329
- });
330
- processContext.exit(1);
331
- 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
+ );
332
291
  }
333
292
 
334
293
  OutputFormatter.success({
@@ -343,7 +302,9 @@ export const registerRecordsCommand = (program: Command) => {
343
302
  .command("insert")
344
303
  .description("Insert records into a Data Fabric entity")
345
304
  .argument("<id>", "Entity ID")
346
- .option("-t, --tenant <tenant-name>", "Tenant name")
305
+ .addOption(
306
+ createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>"),
307
+ )
347
308
  .option(
348
309
  "-f, --file <path>",
349
310
  "Path to JSON file with record data (object or array of objects)",
@@ -361,28 +322,11 @@ export const registerRecordsCommand = (program: Command) => {
361
322
  );
362
323
 
363
324
  if (parseError) {
364
- OutputFormatter.error({
365
- Result: RESULTS.Failure,
366
- Message: "Error parsing input data",
367
- Instructions: parseError.message,
368
- });
369
- processContext.exit(1);
370
- return;
325
+ return fail("Error parsing input data", parseError.message);
371
326
  }
372
327
 
373
- const [clientError, sdk] = await catchError(
374
- createDataFabricClient(options.tenant),
375
- );
376
-
377
- if (clientError) {
378
- OutputFormatter.error({
379
- Result: RESULTS.Failure,
380
- Message: "Error connecting to Data Fabric",
381
- Instructions: await extractErrorMessage(clientError),
382
- });
383
- processContext.exit(1);
384
- return;
385
- }
328
+ const sdk = await connectOrFail(options.tenant);
329
+ if (!sdk) return;
386
330
 
387
331
  const data = rawData as
388
332
  | Record<string, unknown>
@@ -395,14 +339,10 @@ export const registerRecordsCommand = (program: Command) => {
395
339
  );
396
340
 
397
341
  if (insertError) {
398
- OutputFormatter.error({
399
- Result: RESULTS.Failure,
400
- Message: "Error inserting record",
401
- Instructions:
402
- await extractErrorMessage(insertError),
403
- });
404
- processContext.exit(1);
405
- return;
342
+ return fail(
343
+ "Error inserting record",
344
+ await extractErrorMessage(insertError),
345
+ );
406
346
  }
407
347
 
408
348
  OutputFormatter.success({
@@ -416,14 +356,10 @@ export const registerRecordsCommand = (program: Command) => {
416
356
  );
417
357
 
418
358
  if (insertError) {
419
- OutputFormatter.error({
420
- Result: RESULTS.Failure,
421
- Message: "Error inserting records",
422
- Instructions:
423
- await extractErrorMessage(insertError),
424
- });
425
- processContext.exit(1);
426
- return;
359
+ return fail(
360
+ "Error inserting records",
361
+ await extractErrorMessage(insertError),
362
+ );
427
363
  }
428
364
 
429
365
  const r = result as BatchResult;
@@ -449,7 +385,9 @@ export const registerRecordsCommand = (program: Command) => {
449
385
  .command("update")
450
386
  .description("Update records in a Data Fabric entity")
451
387
  .argument("<id>", "Entity ID")
452
- .option("-t, --tenant <tenant-name>", "Tenant name")
388
+ .addOption(
389
+ createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>"),
390
+ )
453
391
  .option(
454
392
  "-f, --file <path>",
455
393
  "Path to JSON file with record data (must include Id field)",
@@ -467,28 +405,11 @@ export const registerRecordsCommand = (program: Command) => {
467
405
  );
468
406
 
469
407
  if (parseError) {
470
- OutputFormatter.error({
471
- Result: RESULTS.Failure,
472
- Message: "Error parsing input data",
473
- Instructions: parseError.message,
474
- });
475
- processContext.exit(1);
476
- return;
408
+ return fail("Error parsing input data", parseError.message);
477
409
  }
478
410
 
479
- const [clientError, sdk] = await catchError(
480
- createDataFabricClient(options.tenant),
481
- );
482
-
483
- if (clientError) {
484
- OutputFormatter.error({
485
- Result: RESULTS.Failure,
486
- Message: "Error connecting to Data Fabric",
487
- Instructions: await extractErrorMessage(clientError),
488
- });
489
- processContext.exit(1);
490
- return;
491
- }
411
+ const sdk = await connectOrFail(options.tenant);
412
+ if (!sdk) return;
492
413
 
493
414
  const data = rawData as
494
415
  | Record<string, unknown>
@@ -500,14 +421,10 @@ export const registerRecordsCommand = (program: Command) => {
500
421
  const recordId =
501
422
  record.Id !== undefined ? record.Id : record.id;
502
423
  if (recordId === undefined || recordId === null) {
503
- OutputFormatter.error({
504
- Result: RESULTS.Failure,
505
- Message: "Record must include an 'Id' field",
506
- Instructions:
507
- "Provide the record ID in the JSON data.",
508
- });
509
- processContext.exit(1);
510
- return;
424
+ return fail(
425
+ "Record must include an 'Id' field",
426
+ "Provide the record ID in the JSON data.",
427
+ );
511
428
  }
512
429
 
513
430
  const [updateError, result] = await catchError(
@@ -519,14 +436,10 @@ export const registerRecordsCommand = (program: Command) => {
519
436
  );
520
437
 
521
438
  if (updateError) {
522
- OutputFormatter.error({
523
- Result: RESULTS.Failure,
524
- Message: "Error updating record",
525
- Instructions:
526
- await extractErrorMessage(updateError),
527
- });
528
- processContext.exit(1);
529
- return;
439
+ return fail(
440
+ "Error updating record",
441
+ await extractErrorMessage(updateError),
442
+ );
530
443
  }
531
444
 
532
445
  OutputFormatter.success({
@@ -539,14 +452,10 @@ export const registerRecordsCommand = (program: Command) => {
539
452
  (r) => r.Id == null && r.id == null,
540
453
  );
541
454
  if (missingId) {
542
- OutputFormatter.error({
543
- Result: RESULTS.Failure,
544
- Message: "All records must include an 'Id' field",
545
- Instructions:
546
- "Provide the record ID in each JSON object.",
547
- });
548
- processContext.exit(1);
549
- return;
455
+ return fail(
456
+ "All records must include an 'Id' field",
457
+ "Provide the record ID in each JSON object.",
458
+ );
550
459
  }
551
460
 
552
461
  const [updateError, result] = await catchError(
@@ -557,14 +466,10 @@ export const registerRecordsCommand = (program: Command) => {
557
466
  );
558
467
 
559
468
  if (updateError) {
560
- OutputFormatter.error({
561
- Result: RESULTS.Failure,
562
- Message: "Error updating records",
563
- Instructions:
564
- await extractErrorMessage(updateError),
565
- });
566
- processContext.exit(1);
567
- return;
469
+ return fail(
470
+ "Error updating records",
471
+ await extractErrorMessage(updateError),
472
+ );
568
473
  }
569
474
 
570
475
  const r = result as BatchResult;
@@ -595,7 +500,9 @@ export const registerRecordsCommand = (program: Command) => {
595
500
  "aggregates (function: COUNT/SUM/AVG/MIN/MAX, field, alias?), groupBy.",
596
501
  )
597
502
  .argument("<id>", "Entity ID")
598
- .option("-t, --tenant <tenant-name>", "Tenant name")
503
+ .addOption(
504
+ createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>"),
505
+ )
599
506
  .option(
600
507
  "-f, --file <path>",
601
508
  "Path to JSON file with query options (filterGroup, selectedFields, sortOptions, aggregates, groupBy)",
@@ -622,41 +529,30 @@ export const registerRecordsCommand = (program: Command) => {
622
529
  async (entityId: string, options: QueryOptions) => {
623
530
  const pageSize = Number(options.limit);
624
531
  if (Number.isNaN(pageSize) || pageSize < 1) {
625
- OutputFormatter.error({
626
- Result: RESULTS.Failure,
627
- Message: "Invalid --limit value",
628
- Instructions: "Provide a positive integer for --limit.",
629
- });
630
- processContext.exit(1);
631
- return;
532
+ return fail(
533
+ "Invalid --limit value",
534
+ "Provide a positive integer for --limit.",
535
+ );
632
536
  }
633
537
 
634
538
  if (
635
539
  options.cursor !== undefined &&
636
540
  options.offset !== undefined
637
541
  ) {
638
- OutputFormatter.error({
639
- Result: RESULTS.Failure,
640
- Message: "--offset and --cursor are mutually exclusive",
641
- Instructions:
642
- "Use --offset to jump to a position by record count, or --cursor to continue from a previous response.",
643
- });
644
- processContext.exit(1);
645
- 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
+ );
646
546
  }
647
547
 
648
548
  let jumpToPage: number | undefined;
649
549
  if (options.offset !== undefined) {
650
550
  const offsetValue = Number(options.offset);
651
551
  if (Number.isNaN(offsetValue) || offsetValue < 0) {
652
- OutputFormatter.error({
653
- Result: RESULTS.Failure,
654
- Message: "Invalid --offset value",
655
- Instructions:
656
- "Provide a non-negative integer for --offset.",
657
- });
658
- processContext.exit(1);
659
- return;
552
+ return fail(
553
+ "Invalid --offset value",
554
+ "Provide a non-negative integer for --offset.",
555
+ );
660
556
  }
661
557
  jumpToPage = Math.floor(offsetValue / pageSize) + 1;
662
558
  }
@@ -671,44 +567,26 @@ export const registerRecordsCommand = (program: Command) => {
671
567
  ),
672
568
  );
673
569
  if (parseError) {
674
- OutputFormatter.error({
675
- Result: RESULTS.Failure,
676
- Message: "Error parsing query options",
677
- Instructions: parseError.message,
678
- });
679
- processContext.exit(1);
680
- return;
570
+ return fail(
571
+ "Error parsing query options",
572
+ parseError.message,
573
+ );
681
574
  }
682
575
  if (
683
576
  typeof parsed !== "object" ||
684
577
  parsed === null ||
685
578
  Array.isArray(parsed)
686
579
  ) {
687
- OutputFormatter.error({
688
- Result: RESULTS.Failure,
689
- Message: "Query options must be a JSON object",
690
- Instructions:
691
- "Provide a JSON object (not an array) with filterGroup, selectedFields, sortOptions, aggregates, or groupBy.",
692
- });
693
- processContext.exit(1);
694
- 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
+ );
695
584
  }
696
585
  queryBody = parsed as Record<string, unknown>;
697
586
  }
698
587
 
699
- const [clientError, sdk] = await catchError(
700
- createDataFabricClient(options.tenant),
701
- );
702
-
703
- if (clientError) {
704
- OutputFormatter.error({
705
- Result: RESULTS.Failure,
706
- Message: "Error connecting to Data Fabric",
707
- Instructions: await extractErrorMessage(clientError),
708
- });
709
- processContext.exit(1);
710
- return;
711
- }
588
+ const sdk = await connectOrFail(options.tenant);
589
+ if (!sdk) return;
712
590
 
713
591
  const [queryError, result] = await catchError(
714
592
  sdk.entities.queryRecordsById(entityId, {
@@ -722,42 +600,16 @@ export const registerRecordsCommand = (program: Command) => {
722
600
  );
723
601
 
724
602
  if (queryError) {
725
- OutputFormatter.error({
726
- Result: RESULTS.Failure,
727
- Message: "Error querying records",
728
- Instructions: await extractErrorMessage(queryError),
729
- });
730
- processContext.exit(1);
731
- return;
603
+ return fail(
604
+ "Error querying records",
605
+ await extractErrorMessage(queryError),
606
+ );
732
607
  }
733
608
 
734
- const r = result as {
735
- items: unknown[];
736
- totalCount?: number;
737
- hasNextPage?: boolean;
738
- nextCursor?: unknown;
739
- currentPage?: number;
740
- totalPages?: number;
741
- };
742
- const nextCursor = extractCursorValue(r.nextCursor);
743
-
744
609
  OutputFormatter.success({
745
610
  Result: RESULTS.Success,
746
611
  Code: "RecordQuery",
747
- Data: {
748
- TotalCount: r.totalCount ?? r.items.length,
749
- Records: r.items,
750
- HasNextPage: r.hasNextPage ?? false,
751
- ...(nextCursor !== undefined && {
752
- NextCursor: nextCursor,
753
- }),
754
- ...(r.currentPage !== undefined && {
755
- CurrentPage: r.currentPage,
756
- }),
757
- ...(r.totalPages !== undefined && {
758
- TotalPages: r.totalPages,
759
- }),
760
- },
612
+ Data: result,
761
613
  });
762
614
  },
763
615
  );
@@ -766,19 +618,18 @@ export const registerRecordsCommand = (program: Command) => {
766
618
  .command("import")
767
619
  .description("Import records from a CSV file into a Data Fabric entity")
768
620
  .argument("<id>", "Entity ID")
769
- .option("-t, --tenant <tenant-name>", "Tenant name")
621
+ .addOption(
622
+ createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>"),
623
+ )
770
624
  .option("-f, --file <path>", "Path to the CSV file to import")
771
625
  .trackedAction(
772
626
  processContext,
773
627
  async (entityId: string, options: ImportOptions) => {
774
628
  if (options.file === undefined) {
775
- OutputFormatter.error({
776
- Result: RESULTS.Failure,
777
- Message: "A CSV file path is required",
778
- Instructions: "Provide a CSV file path via --file.",
779
- });
780
- processContext.exit(1);
781
- return;
629
+ return fail(
630
+ "A CSV file path is required",
631
+ "Provide a CSV file path via --file.",
632
+ );
782
633
  }
783
634
 
784
635
  const [readError, fileContent] = await catchError(
@@ -786,28 +637,11 @@ export const registerRecordsCommand = (program: Command) => {
786
637
  );
787
638
 
788
639
  if (readError) {
789
- OutputFormatter.error({
790
- Result: RESULTS.Failure,
791
- Message: "Error reading CSV file",
792
- Instructions: readError.message,
793
- });
794
- processContext.exit(1);
795
- return;
640
+ return fail("Error reading CSV file", readError.message);
796
641
  }
797
642
 
798
- const [clientError, sdk] = await catchError(
799
- createDataFabricClient(options.tenant),
800
- );
801
-
802
- if (clientError) {
803
- OutputFormatter.error({
804
- Result: RESULTS.Failure,
805
- Message: "Error connecting to Data Fabric",
806
- Instructions: await extractErrorMessage(clientError),
807
- });
808
- processContext.exit(1);
809
- return;
810
- }
643
+ const sdk = await connectOrFail(options.tenant);
644
+ if (!sdk) return;
811
645
 
812
646
  const fs = getFileSystem();
813
647
  const fileName = fs.path.basename(options.file) || "import.csv";
@@ -821,13 +655,10 @@ export const registerRecordsCommand = (program: Command) => {
821
655
  );
822
656
 
823
657
  if (importError) {
824
- OutputFormatter.error({
825
- Result: RESULTS.Failure,
826
- Message: "Error importing records",
827
- Instructions: await extractErrorMessage(importError),
828
- });
829
- processContext.exit(1);
830
- return;
658
+ return fail(
659
+ "Error importing records",
660
+ await extractErrorMessage(importError),
661
+ );
831
662
  }
832
663
 
833
664
  const r = result as {
@@ -855,7 +686,9 @@ export const registerRecordsCommand = (program: Command) => {
855
686
  .description("Delete records from a Data Fabric entity")
856
687
  .argument("<id>", "Entity ID")
857
688
  .argument("<key...>", "Record IDs to delete")
858
- .option("-t, --tenant <tenant-name>", "Tenant name")
689
+ .addOption(
690
+ createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>"),
691
+ )
859
692
  .examples(RECORDS_DELETE_EXAMPLES)
860
693
  .trackedAction(
861
694
  processContext,
@@ -864,32 +697,18 @@ export const registerRecordsCommand = (program: Command) => {
864
697
  recordIds: string[],
865
698
  options: DeleteOptions,
866
699
  ) => {
867
- const [clientError, sdk] = await catchError(
868
- createDataFabricClient(options.tenant),
869
- );
870
-
871
- if (clientError) {
872
- OutputFormatter.error({
873
- Result: RESULTS.Failure,
874
- Message: "Error connecting to Data Fabric",
875
- Instructions: await extractErrorMessage(clientError),
876
- });
877
- processContext.exit(1);
878
- return;
879
- }
700
+ const sdk = await connectOrFail(options.tenant);
701
+ if (!sdk) return;
880
702
 
881
703
  const [deleteError, result] = await catchError(
882
704
  sdk.entities.deleteRecordsById(entityId, recordIds),
883
705
  );
884
706
 
885
707
  if (deleteError) {
886
- OutputFormatter.error({
887
- Result: RESULTS.Failure,
888
- Message: "Error deleting records",
889
- Instructions: await extractErrorMessage(deleteError),
890
- });
891
- processContext.exit(1);
892
- return;
708
+ return fail(
709
+ "Error deleting records",
710
+ await extractErrorMessage(deleteError),
711
+ );
893
712
  }
894
713
 
895
714
  const r = result as BatchResult;
@@ -911,17 +730,6 @@ export const registerRecordsCommand = (program: Command) => {
911
730
  );
912
731
  };
913
732
 
914
- /** Normalises the SDK cursor to a plain string for CLI output.
915
- * The SDK returns `PaginationCursor = { value: string }` but we want
916
- * to expose just the string so the user can pass it directly to --cursor. */
917
- function extractCursorValue(cursor: unknown): string | undefined {
918
- if (cursor === undefined || cursor === null) return undefined;
919
- if (typeof cursor === "string") return cursor;
920
- const c = cursor as Record<string, unknown>;
921
- if (typeof c.value === "string") return c.value;
922
- return undefined;
923
- }
924
-
925
733
  const isRecordObject = (value: unknown): value is Record<string, unknown> =>
926
734
  typeof value === "object" && value !== null && !Array.isArray(value);
927
735