@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.
@@ -3,6 +3,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
3
3
 
4
4
  vi.mock("../utils/sdk-client", () => ({
5
5
  createDataFabricClient: vi.fn(),
6
+ connectOrFail: vi.fn(),
6
7
  }));
7
8
 
8
9
  vi.mock("@uipath/common", async (importOriginal) => {
@@ -22,7 +23,7 @@ vi.mock("../utils/input", () => ({
22
23
 
23
24
  import { OutputFormatter } from "@uipath/common";
24
25
  import { readJsonInput } from "../utils/input";
25
- import { createDataFabricClient } from "../utils/sdk-client";
26
+ import { connectOrFail } from "../utils/sdk-client";
26
27
  import { registerEntitiesCommand } from "./entities";
27
28
 
28
29
  function buildProgram(): Command {
@@ -43,7 +44,7 @@ function mockSdk(overrides: Record<string, unknown> = {}) {
43
44
  ...overrides,
44
45
  },
45
46
  };
46
- vi.mocked(createDataFabricClient).mockResolvedValue(sdk as never);
47
+ vi.mocked(connectOrFail).mockResolvedValue(sdk as never);
47
48
  return sdk;
48
49
  }
49
50
 
@@ -74,9 +75,9 @@ describe("entities list", () => {
74
75
  ).toBeFalsy();
75
76
  });
76
77
 
77
- it("should list entities successfully", async () => {
78
+ it("should list entities successfully (raw SDK shape)", async () => {
78
79
  const sdk = mockSdk();
79
- vi.mocked(sdk.entities.getAll).mockResolvedValue([
80
+ const rawEntities = [
80
81
  {
81
82
  id: "uuid-1",
82
83
  name: "invoice",
@@ -86,7 +87,8 @@ describe("entities list", () => {
86
87
  fields: [{ name: "amount" }, { name: "date" }],
87
88
  externalFields: [],
88
89
  },
89
- ]);
90
+ ];
91
+ vi.mocked(sdk.entities.getAll).mockResolvedValue(rawEntities);
90
92
 
91
93
  const program = buildProgram();
92
94
  await program.parseAsync(["node", "test", "entities", "list"]);
@@ -95,53 +97,12 @@ describe("entities list", () => {
95
97
  expect.objectContaining({
96
98
  Result: "Success",
97
99
  Code: "EntityList",
98
- Data: expect.arrayContaining([
99
- expect.objectContaining({
100
- Name: "invoice",
101
- ID: "uuid-1",
102
- FieldCount: 2,
103
- Source: "Native",
104
- }),
105
- ]),
100
+ Data: rawEntities,
106
101
  }),
107
102
  );
108
103
  });
109
104
 
110
- it("should label federated entity with connector name", async () => {
111
- const sdk = mockSdk();
112
- vi.mocked(sdk.entities.getAll).mockResolvedValue([
113
- {
114
- id: "uuid-2",
115
- name: "contacts",
116
- displayName: "Contacts",
117
- entityType: "Federated",
118
- description: "",
119
- fields: [],
120
- externalFields: [
121
- {
122
- externalConnectionDetail: {
123
- connectorName: "Salesforce",
124
- },
125
- },
126
- ],
127
- },
128
- ]);
129
-
130
- const program = buildProgram();
131
- await program.parseAsync(["node", "test", "entities", "list"]);
132
-
133
- expect(OutputFormatter.success).toHaveBeenCalledWith(
134
- expect.objectContaining({
135
- Data: expect.arrayContaining([
136
- expect.objectContaining({
137
- Source: "Federated (Salesforce)",
138
- }),
139
- ]),
140
- }),
141
- );
142
- });
143
-
144
- it("should filter out federated entities with --native-only", async () => {
105
+ it("should filter out federated entities with --native-only (raw shape)", async () => {
145
106
  const sdk = mockSdk();
146
107
  vi.mocked(sdk.entities.getAll).mockResolvedValue([
147
108
  {
@@ -168,10 +129,10 @@ describe("entities list", () => {
168
129
  ]);
169
130
 
170
131
  const call = vi.mocked(OutputFormatter.success).mock.calls[0][0] as {
171
- Data: { ID: string }[];
132
+ Data: { id: string }[];
172
133
  };
173
134
  expect(call.Data).toHaveLength(1);
174
- expect(call.Data[0].ID).toBe("uuid-1");
135
+ expect(call.Data[0].id).toBe("uuid-1");
175
136
  });
176
137
 
177
138
  it("should return empty list when no entities exist", async () => {
@@ -189,21 +150,15 @@ describe("entities list", () => {
189
150
  );
190
151
  });
191
152
 
192
- it("should error when SDK connection fails", async () => {
193
- vi.mocked(createDataFabricClient).mockRejectedValue(
194
- new Error("Not logged in"),
195
- );
153
+ it("should bail when SDK connection fails", async () => {
154
+ const sdk = mockSdk();
155
+ vi.mocked(connectOrFail).mockResolvedValue(undefined);
196
156
 
197
157
  const program = buildProgram();
198
158
  await program.parseAsync(["node", "test", "entities", "list"]);
199
159
 
200
- expect(OutputFormatter.error).toHaveBeenCalledWith(
201
- expect.objectContaining({
202
- Result: "Failure",
203
- Message: "Error connecting to Data Fabric",
204
- }),
205
- );
206
- expect(process.exitCode).toBe(1);
160
+ expect(sdk.entities.getAll).not.toHaveBeenCalled();
161
+ expect(OutputFormatter.success).not.toHaveBeenCalled();
207
162
  });
208
163
 
209
164
  it("should error when list API fails", async () => {
@@ -231,23 +186,33 @@ describe("entities get", () => {
231
186
  process.exitCode = undefined;
232
187
  });
233
188
 
234
- it("should return entity schema with fields", async () => {
189
+ it("should return entity schema as the raw SDK response", async () => {
235
190
  const sdk = mockSdk();
236
- vi.mocked(sdk.entities.getById).mockResolvedValue({
191
+ const rawEntity = {
237
192
  id: "uuid-1",
238
193
  name: "invoice",
239
194
  displayName: "Invoice",
240
195
  entityType: "Local",
241
196
  description: "Invoice entity",
197
+ isRbacEnabled: false,
242
198
  fields: [
243
199
  {
244
200
  id: "field-uuid-1",
245
201
  name: "amount",
246
202
  displayName: "Amount",
247
203
  fieldDataType: { name: "DECIMAL" },
204
+ sqlType: {
205
+ name: "DECIMAL",
206
+ decimalPrecision: 2,
207
+ },
248
208
  isRequired: true,
249
209
  isPrimaryKey: false,
250
210
  isSystemField: false,
211
+ // SDK-internal fields are no longer projected away
212
+ isForeignKey: false,
213
+ referenceName: "fk_Amount_ab00841b",
214
+ createdTime: "2026-01-01T00:00:00Z",
215
+ createdBy: "u1",
251
216
  },
252
217
  {
253
218
  id: "field-uuid-2",
@@ -259,7 +224,8 @@ describe("entities get", () => {
259
224
  isSystemField: false,
260
225
  },
261
226
  ],
262
- });
227
+ };
228
+ vi.mocked(sdk.entities.getById).mockResolvedValue(rawEntity);
263
229
 
264
230
  const program = buildProgram();
265
231
  await program.parseAsync(["node", "test", "entities", "get", "uuid-1"]);
@@ -268,55 +234,20 @@ describe("entities get", () => {
268
234
  expect.objectContaining({
269
235
  Result: "Success",
270
236
  Code: "EntitySchema",
271
- Data: expect.objectContaining({
272
- ID: "uuid-1",
273
- Name: "invoice",
274
- Fields: expect.arrayContaining([
275
- expect.objectContaining({
276
- ID: "field-uuid-1",
277
- Name: "amount",
278
- Type: "DECIMAL",
279
- Required: true,
280
- }),
281
- ]),
282
- }),
237
+ Data: rawEntity,
283
238
  }),
284
239
  );
285
240
  });
286
241
 
287
- it("should use name as DisplayName when displayName is missing", async () => {
242
+ it("should bail when SDK connection fails", async () => {
288
243
  const sdk = mockSdk();
289
- vi.mocked(sdk.entities.getById).mockResolvedValue({
290
- id: "uuid-1",
291
- name: "invoice",
292
- fields: [],
293
- });
294
-
295
- const program = buildProgram();
296
- await program.parseAsync(["node", "test", "entities", "get", "uuid-1"]);
297
-
298
- expect(OutputFormatter.success).toHaveBeenCalledWith(
299
- expect.objectContaining({
300
- Data: expect.objectContaining({ DisplayName: "invoice" }),
301
- }),
302
- );
303
- });
304
-
305
- it("should error when SDK connection fails", async () => {
306
- vi.mocked(createDataFabricClient).mockRejectedValue(
307
- new Error("Not logged in"),
308
- );
244
+ vi.mocked(connectOrFail).mockResolvedValue(undefined);
309
245
 
310
246
  const program = buildProgram();
311
247
  await program.parseAsync(["node", "test", "entities", "get", "uuid-1"]);
312
248
 
313
- expect(OutputFormatter.error).toHaveBeenCalledWith(
314
- expect.objectContaining({
315
- Result: "Failure",
316
- Message: "Error connecting to Data Fabric",
317
- }),
318
- );
319
- expect(process.exitCode).toBe(1);
249
+ expect(sdk.entities.getById).not.toHaveBeenCalled();
250
+ expect(OutputFormatter.success).not.toHaveBeenCalled();
320
251
  });
321
252
 
322
253
  it("should error when entity is not found (SDK throws)", async () => {
@@ -465,6 +396,128 @@ describe("entities create", () => {
465
396
  );
466
397
  });
467
398
 
399
+ it("should create entity with a CHOICE_SET_SINGLE field carrying choiceSetId", async () => {
400
+ const sdk = mockSdk();
401
+ vi.mocked(sdk.entities.create).mockResolvedValue(
402
+ "entity-choice-single",
403
+ );
404
+ const fields = [
405
+ {
406
+ fieldName: "opType",
407
+ type: "CHOICE_SET_SINGLE",
408
+ choiceSetId: "9db00b66-9952-f111-8ef3-6045bd07956d",
409
+ isRequired: true,
410
+ },
411
+ ];
412
+ vi.mocked(readJsonInput).mockResolvedValue({ fields });
413
+
414
+ const program = buildProgram();
415
+ await program.parseAsync([
416
+ "node",
417
+ "test",
418
+ "entities",
419
+ "create",
420
+ "CliTestExpense",
421
+ "--body",
422
+ JSON.stringify({ fields }),
423
+ ]);
424
+
425
+ expect(sdk.entities.create).toHaveBeenCalledWith(
426
+ "CliTestExpense",
427
+ expect.arrayContaining([
428
+ expect.objectContaining({
429
+ fieldName: "opType",
430
+ type: "CHOICE_SET_SINGLE",
431
+ choiceSetId: "9db00b66-9952-f111-8ef3-6045bd07956d",
432
+ }),
433
+ ]),
434
+ undefined,
435
+ );
436
+ expect(OutputFormatter.success).toHaveBeenCalledWith(
437
+ expect.objectContaining({ Code: "EntityCreated" }),
438
+ );
439
+ });
440
+
441
+ it("should create entity with a CHOICE_SET_MULTIPLE field carrying choiceSetId", async () => {
442
+ const sdk = mockSdk();
443
+ vi.mocked(sdk.entities.create).mockResolvedValue("entity-choice-multi");
444
+ const fields = [
445
+ {
446
+ fieldName: "multiOpType",
447
+ type: "CHOICE_SET_MULTIPLE",
448
+ choiceSetId: "9db00b66-9952-f111-8ef3-6045bd07956d",
449
+ },
450
+ ];
451
+ vi.mocked(readJsonInput).mockResolvedValue({ fields });
452
+
453
+ const program = buildProgram();
454
+ await program.parseAsync([
455
+ "node",
456
+ "test",
457
+ "entities",
458
+ "create",
459
+ "CliTestExpense",
460
+ "--body",
461
+ JSON.stringify({ fields }),
462
+ ]);
463
+
464
+ expect(sdk.entities.create).toHaveBeenCalledWith(
465
+ "CliTestExpense",
466
+ expect.arrayContaining([
467
+ expect.objectContaining({
468
+ fieldName: "multiOpType",
469
+ type: "CHOICE_SET_MULTIPLE",
470
+ choiceSetId: "9db00b66-9952-f111-8ef3-6045bd07956d",
471
+ }),
472
+ ]),
473
+ undefined,
474
+ );
475
+ expect(OutputFormatter.success).toHaveBeenCalledWith(
476
+ expect.objectContaining({ Code: "EntityCreated" }),
477
+ );
478
+ });
479
+
480
+ it("should create entity with a RELATIONSHIP field carrying referenceEntityId and referenceFieldId", async () => {
481
+ const sdk = mockSdk();
482
+ vi.mocked(sdk.entities.create).mockResolvedValue("entity-rel");
483
+ const fields = [
484
+ {
485
+ fieldName: "rel1",
486
+ type: "RELATIONSHIP",
487
+ referenceEntityId: "a1b2c3d4-0000-0000-0000-000000000010",
488
+ referenceFieldId: "f1000000-0000-0000-0000-000000000100",
489
+ },
490
+ ];
491
+ vi.mocked(readJsonInput).mockResolvedValue({ fields });
492
+
493
+ const program = buildProgram();
494
+ await program.parseAsync([
495
+ "node",
496
+ "test",
497
+ "entities",
498
+ "create",
499
+ "CliTestExpense",
500
+ "--body",
501
+ JSON.stringify({ fields }),
502
+ ]);
503
+
504
+ expect(sdk.entities.create).toHaveBeenCalledWith(
505
+ "CliTestExpense",
506
+ expect.arrayContaining([
507
+ expect.objectContaining({
508
+ fieldName: "rel1",
509
+ type: "RELATIONSHIP",
510
+ referenceEntityId: "a1b2c3d4-0000-0000-0000-000000000010",
511
+ referenceFieldId: "f1000000-0000-0000-0000-000000000100",
512
+ }),
513
+ ]),
514
+ undefined,
515
+ );
516
+ expect(OutputFormatter.success).toHaveBeenCalledWith(
517
+ expect.objectContaining({ Code: "EntityCreated" }),
518
+ );
519
+ });
520
+
468
521
  it("should error when no --body or --file provided", async () => {
469
522
  vi.mocked(readJsonInput).mockRejectedValue(
470
523
  new Error("Provide entity definition via --file or --body."),
@@ -588,13 +641,12 @@ describe("entities create", () => {
588
641
  expect(process.exitCode).toBe(1);
589
642
  });
590
643
 
591
- it("should error when SDK connection fails on create", async () => {
644
+ it("should bail when SDK connection fails on create", async () => {
645
+ const sdk = mockSdk();
592
646
  vi.mocked(readJsonInput).mockResolvedValue({
593
647
  fields: [{ fieldName: "title", type: "STRING" }],
594
648
  });
595
- vi.mocked(createDataFabricClient).mockRejectedValue(
596
- new Error("Not logged in"),
597
- );
649
+ vi.mocked(connectOrFail).mockResolvedValue(undefined);
598
650
 
599
651
  const program = buildProgram();
600
652
  await program.parseAsync([
@@ -607,13 +659,8 @@ describe("entities create", () => {
607
659
  '{"fields":[{"fieldName":"title","type":"STRING"}]}',
608
660
  ]);
609
661
 
610
- expect(OutputFormatter.error).toHaveBeenCalledWith(
611
- expect.objectContaining({
612
- Result: "Failure",
613
- Message: "Error connecting to Data Fabric",
614
- }),
615
- );
616
- expect(process.exitCode).toBe(1);
662
+ expect(sdk.entities.create).not.toHaveBeenCalled();
663
+ expect(OutputFormatter.success).not.toHaveBeenCalled();
617
664
  });
618
665
 
619
666
  it("should error when create API fails", async () => {
@@ -684,6 +731,69 @@ describe("entities update", () => {
684
731
  );
685
732
  });
686
733
 
734
+ it("should update entity by adding a RELATIONSHIP field with referenceEntityId and referenceFieldId", async () => {
735
+ const sdk = mockSdk();
736
+ const addFields = [
737
+ {
738
+ fieldName: "rel1",
739
+ type: "RELATIONSHIP",
740
+ referenceEntityId: "a1b2c3d4-0000-0000-0000-000000000010",
741
+ referenceFieldId: "f1000000-0000-0000-0000-000000000100",
742
+ },
743
+ ];
744
+ vi.mocked(readJsonInput).mockResolvedValue({ addFields });
745
+
746
+ const program = buildProgram();
747
+ await program.parseAsync([
748
+ "node",
749
+ "test",
750
+ "entities",
751
+ "update",
752
+ "entity-id",
753
+ "--body",
754
+ JSON.stringify({ addFields }),
755
+ ]);
756
+
757
+ expect(sdk.entities.updateById).toHaveBeenCalledWith(
758
+ "entity-id",
759
+ expect.objectContaining({ addFields }),
760
+ );
761
+ expect(OutputFormatter.success).toHaveBeenCalledWith(
762
+ expect.objectContaining({ Code: "EntityUpdated" }),
763
+ );
764
+ });
765
+
766
+ it("should update entity by adding a CHOICE_SET_MULTIPLE field with choiceSetId", async () => {
767
+ const sdk = mockSdk();
768
+ const addFields = [
769
+ {
770
+ fieldName: "multiOpType",
771
+ type: "CHOICE_SET_MULTIPLE",
772
+ choiceSetId: "9db00b66-9952-f111-8ef3-6045bd07956d",
773
+ },
774
+ ];
775
+ vi.mocked(readJsonInput).mockResolvedValue({ addFields });
776
+
777
+ const program = buildProgram();
778
+ await program.parseAsync([
779
+ "node",
780
+ "test",
781
+ "entities",
782
+ "update",
783
+ "entity-id",
784
+ "--body",
785
+ JSON.stringify({ addFields }),
786
+ ]);
787
+
788
+ expect(sdk.entities.updateById).toHaveBeenCalledWith(
789
+ "entity-id",
790
+ expect.objectContaining({ addFields }),
791
+ );
792
+ expect(OutputFormatter.success).toHaveBeenCalledWith(
793
+ expect.objectContaining({ Code: "EntityUpdated" }),
794
+ );
795
+ });
796
+
687
797
  it("should update entity by modifying existing fields (updateFields)", async () => {
688
798
  const sdk = mockSdk();
689
799
  vi.mocked(readJsonInput).mockResolvedValue({
@@ -727,6 +837,182 @@ describe("entities update", () => {
727
837
  );
728
838
  });
729
839
 
840
+ it("should update displayName on a CHOICE_SET_SINGLE field via updateFields", async () => {
841
+ const sdk = mockSdk();
842
+ const updateFields = [
843
+ {
844
+ id: "f9ccd648-ac52-f111-8ef3-6045bd07956d",
845
+ displayName: "Operator Type",
846
+ },
847
+ ];
848
+ vi.mocked(readJsonInput).mockResolvedValue({ updateFields });
849
+
850
+ const program = buildProgram();
851
+ await program.parseAsync([
852
+ "node",
853
+ "test",
854
+ "entities",
855
+ "update",
856
+ "entity-id",
857
+ "--body",
858
+ JSON.stringify({ updateFields }),
859
+ ]);
860
+
861
+ expect(sdk.entities.updateById).toHaveBeenCalledWith(
862
+ "entity-id",
863
+ expect.objectContaining({ updateFields }),
864
+ );
865
+ expect(OutputFormatter.success).toHaveBeenCalledWith(
866
+ expect.objectContaining({ Code: "EntityUpdated" }),
867
+ );
868
+ });
869
+
870
+ it("should update displayName and isRequired on a CHOICE_SET_MULTIPLE field via updateFields", async () => {
871
+ const sdk = mockSdk();
872
+ const updateFields = [
873
+ {
874
+ id: "8750af08-b252-f111-8ef3-6045bd07956d",
875
+ displayName: "Multi Operator Types",
876
+ isRequired: true,
877
+ },
878
+ ];
879
+ vi.mocked(readJsonInput).mockResolvedValue({ updateFields });
880
+
881
+ const program = buildProgram();
882
+ await program.parseAsync([
883
+ "node",
884
+ "test",
885
+ "entities",
886
+ "update",
887
+ "entity-id",
888
+ "--body",
889
+ JSON.stringify({ updateFields }),
890
+ ]);
891
+
892
+ expect(sdk.entities.updateById).toHaveBeenCalledWith(
893
+ "entity-id",
894
+ expect.objectContaining({ updateFields }),
895
+ );
896
+ expect(OutputFormatter.success).toHaveBeenCalledWith(
897
+ expect.objectContaining({ Code: "EntityUpdated" }),
898
+ );
899
+ });
900
+
901
+ it("should remove a CHOICE_SET_SINGLE field via removeFields with --confirm and --reason", async () => {
902
+ const sdk = mockSdk();
903
+ vi.mocked(readJsonInput).mockResolvedValue({
904
+ removeFields: [{ fieldName: "opType" }],
905
+ });
906
+
907
+ const program = buildProgram();
908
+ await program.parseAsync([
909
+ "node",
910
+ "test",
911
+ "entities",
912
+ "update",
913
+ "entity-id",
914
+ "--body",
915
+ '{"removeFields":[{"fieldName":"opType"}]}',
916
+ "--confirm",
917
+ "--reason",
918
+ "dropping single-select choice-set field",
919
+ ]);
920
+
921
+ expect(sdk.entities.updateById).toHaveBeenCalledWith(
922
+ "entity-id",
923
+ expect.objectContaining({
924
+ removeFields: [{ fieldName: "opType" }],
925
+ }),
926
+ );
927
+ expect(OutputFormatter.success).toHaveBeenCalledWith(
928
+ expect.objectContaining({
929
+ Result: "Success",
930
+ Code: "EntityUpdated",
931
+ Data: expect.objectContaining({
932
+ RemovedFields: ["opType"],
933
+ Reason: "dropping single-select choice-set field",
934
+ }),
935
+ }),
936
+ );
937
+ });
938
+
939
+ it("should remove a CHOICE_SET_MULTIPLE field via removeFields with --confirm and --reason", async () => {
940
+ const sdk = mockSdk();
941
+ vi.mocked(readJsonInput).mockResolvedValue({
942
+ removeFields: [{ fieldName: "multiOpType" }],
943
+ });
944
+
945
+ const program = buildProgram();
946
+ await program.parseAsync([
947
+ "node",
948
+ "test",
949
+ "entities",
950
+ "update",
951
+ "entity-id",
952
+ "--body",
953
+ '{"removeFields":[{"fieldName":"multiOpType"}]}',
954
+ "--confirm",
955
+ "--reason",
956
+ "dropping multi-select choice-set field",
957
+ ]);
958
+
959
+ expect(sdk.entities.updateById).toHaveBeenCalledWith(
960
+ "entity-id",
961
+ expect.objectContaining({
962
+ removeFields: [{ fieldName: "multiOpType" }],
963
+ }),
964
+ );
965
+ expect(OutputFormatter.success).toHaveBeenCalledWith(
966
+ expect.objectContaining({
967
+ Data: expect.objectContaining({
968
+ RemovedFields: ["multiOpType"],
969
+ Reason: "dropping multi-select choice-set field",
970
+ }),
971
+ }),
972
+ );
973
+ });
974
+
975
+ it("should remove both choice-set fields in a single removeFields call", async () => {
976
+ const sdk = mockSdk();
977
+ vi.mocked(readJsonInput).mockResolvedValue({
978
+ removeFields: [
979
+ { fieldName: "opType" },
980
+ { fieldName: "multiOpType" },
981
+ ],
982
+ });
983
+
984
+ const program = buildProgram();
985
+ await program.parseAsync([
986
+ "node",
987
+ "test",
988
+ "entities",
989
+ "update",
990
+ "entity-id",
991
+ "--body",
992
+ '{"removeFields":[{"fieldName":"opType"},{"fieldName":"multiOpType"}]}',
993
+ "--confirm",
994
+ "--reason",
995
+ "dropping all choice-set fields",
996
+ ]);
997
+
998
+ expect(sdk.entities.updateById).toHaveBeenCalledWith(
999
+ "entity-id",
1000
+ expect.objectContaining({
1001
+ removeFields: [
1002
+ { fieldName: "opType" },
1003
+ { fieldName: "multiOpType" },
1004
+ ],
1005
+ }),
1006
+ );
1007
+ expect(OutputFormatter.success).toHaveBeenCalledWith(
1008
+ expect.objectContaining({
1009
+ Data: expect.objectContaining({
1010
+ RemovedFields: ["opType", "multiOpType"],
1011
+ }),
1012
+ }),
1013
+ );
1014
+ });
1015
+
730
1016
  it("should update entity metadata only (displayName and description)", async () => {
731
1017
  const sdk = mockSdk();
732
1018
  vi.mocked(readJsonInput).mockResolvedValue({
@@ -1390,13 +1676,12 @@ describe("entities update", () => {
1390
1676
  expect(process.exitCode).toBe(1);
1391
1677
  });
1392
1678
 
1393
- it("should error when SDK connection fails on update", async () => {
1679
+ it("should bail when SDK connection fails on update", async () => {
1680
+ const sdk = mockSdk();
1394
1681
  vi.mocked(readJsonInput).mockResolvedValue({
1395
1682
  displayName: "New Name",
1396
1683
  });
1397
- vi.mocked(createDataFabricClient).mockRejectedValue(
1398
- new Error("Not logged in"),
1399
- );
1684
+ vi.mocked(connectOrFail).mockResolvedValue(undefined);
1400
1685
 
1401
1686
  const program = buildProgram();
1402
1687
  await program.parseAsync([
@@ -1409,13 +1694,8 @@ describe("entities update", () => {
1409
1694
  '{"displayName":"New Name"}',
1410
1695
  ]);
1411
1696
 
1412
- expect(OutputFormatter.error).toHaveBeenCalledWith(
1413
- expect.objectContaining({
1414
- Result: "Failure",
1415
- Message: "Error connecting to Data Fabric",
1416
- }),
1417
- );
1418
- expect(process.exitCode).toBe(1);
1697
+ expect(sdk.entities.updateById).not.toHaveBeenCalled();
1698
+ expect(OutputFormatter.success).not.toHaveBeenCalled();
1419
1699
  });
1420
1700
 
1421
1701
  it("should error when updateById API fails", async () => {
@@ -1556,10 +1836,9 @@ describe("entities delete", () => {
1556
1836
  expect(process.exitCode).toBe(1);
1557
1837
  });
1558
1838
 
1559
- it("should error when SDK connection fails", async () => {
1560
- vi.mocked(createDataFabricClient).mockRejectedValue(
1561
- new Error("Not logged in"),
1562
- );
1839
+ it("should bail when SDK connection fails", async () => {
1840
+ const sdk = mockSdk();
1841
+ vi.mocked(connectOrFail).mockResolvedValue(undefined);
1563
1842
 
1564
1843
  const program = buildProgram();
1565
1844
  await program.parseAsync([
@@ -1573,13 +1852,8 @@ describe("entities delete", () => {
1573
1852
  "cleanup",
1574
1853
  ]);
1575
1854
 
1576
- expect(OutputFormatter.error).toHaveBeenCalledWith(
1577
- expect.objectContaining({
1578
- Result: "Failure",
1579
- Message: "Error connecting to Data Fabric",
1580
- }),
1581
- );
1582
- expect(process.exitCode).toBe(1);
1855
+ expect(sdk.entities.deleteById).not.toHaveBeenCalled();
1856
+ expect(OutputFormatter.success).not.toHaveBeenCalled();
1583
1857
  });
1584
1858
 
1585
1859
  it("should error when delete API fails", async () => {