@uipath/data-fabric-tool 1.201.0-preview.115 → 1.201.0-preview.121

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.
@@ -301,7 +301,7 @@ describe("entities create", () => {
301
301
  const sdk = mockSdk();
302
302
  vi.mocked(sdk.entities.create).mockResolvedValue("new-entity-id");
303
303
  vi.mocked(readJsonInput).mockResolvedValue({
304
- fields: [{ fieldName: "title", type: "STRING" }],
304
+ fields: [{ name: "title", type: "STRING" }],
305
305
  });
306
306
 
307
307
  const program = buildProgram();
@@ -312,12 +312,12 @@ describe("entities create", () => {
312
312
  "create",
313
313
  "MyEntity",
314
314
  "--body",
315
- '{"fields":[{"fieldName":"title","type":"STRING"}]}',
315
+ '{"fields":[{"name":"title","type":"STRING"}]}',
316
316
  ]);
317
317
 
318
318
  expect(sdk.entities.create).toHaveBeenCalledWith(
319
319
  "MyEntity",
320
- [{ fieldName: "title", type: "STRING" }],
320
+ [{ name: "title", type: "STRING" }],
321
321
  undefined,
322
322
  );
323
323
  expect(OutputFormatter.success).toHaveBeenCalledWith(
@@ -329,13 +329,58 @@ describe("entities create", () => {
329
329
  );
330
330
  });
331
331
 
332
+ it("should normalize fields copied from entities get read shape on create", async () => {
333
+ const sdk = mockSdk();
334
+ vi.mocked(sdk.entities.create).mockResolvedValue("roundtrip-id");
335
+ vi.mocked(readJsonInput).mockResolvedValue({
336
+ fields: [
337
+ {
338
+ ID: "f1000000-0000-0000-0000-000000000001",
339
+ Name: "note",
340
+ DisplayName: "Note",
341
+ FieldDataType: { Name: "STRING", LengthLimit: 200 },
342
+ IsRequired: true,
343
+ System: false,
344
+ },
345
+ ],
346
+ });
347
+
348
+ const program = buildProgram();
349
+ await program.parseAsync([
350
+ "node",
351
+ "test",
352
+ "entities",
353
+ "create",
354
+ "MyEntity",
355
+ "--body",
356
+ '{"fields":[{"ID":"f1000000-0000-0000-0000-000000000001","Name":"note","DisplayName":"Note","FieldDataType":{"Name":"STRING","LengthLimit":200},"IsRequired":true,"System":false}]}',
357
+ ]);
358
+
359
+ expect(sdk.entities.create).toHaveBeenCalledWith(
360
+ "MyEntity",
361
+ [
362
+ {
363
+ name: "note",
364
+ displayName: "Note",
365
+ type: "STRING",
366
+ lengthLimit: 200,
367
+ isRequired: true,
368
+ },
369
+ ],
370
+ undefined,
371
+ );
372
+ expect(OutputFormatter.success).toHaveBeenCalledWith(
373
+ expect.objectContaining({ Code: "EntityCreated" }),
374
+ );
375
+ });
376
+
332
377
  it("should accept MULTILINE_MAX as a field type on create", async () => {
333
378
  const sdk = mockSdk();
334
379
  vi.mocked(sdk.entities.create).mockResolvedValue("doc-entity-id");
335
380
  vi.mocked(readJsonInput).mockResolvedValue({
336
381
  fields: [
337
- { fieldName: "title", type: "STRING" },
338
- { fieldName: "body", type: "MULTILINE_MAX" },
382
+ { name: "title", type: "STRING" },
383
+ { name: "body", type: "MULTILINE_MAX" },
339
384
  ],
340
385
  });
341
386
 
@@ -347,14 +392,14 @@ describe("entities create", () => {
347
392
  "create",
348
393
  "Document",
349
394
  "--body",
350
- '{"fields":[{"fieldName":"title","type":"STRING"},{"fieldName":"body","type":"MULTILINE_MAX"}]}',
395
+ '{"fields":[{"name":"title","type":"STRING"},{"name":"body","type":"MULTILINE_MAX"}]}',
351
396
  ]);
352
397
 
353
398
  expect(sdk.entities.create).toHaveBeenCalledWith(
354
399
  "Document",
355
400
  [
356
- { fieldName: "title", type: "STRING" },
357
- { fieldName: "body", type: "MULTILINE_MAX" },
401
+ { name: "title", type: "STRING" },
402
+ { name: "body", type: "MULTILINE_MAX" },
358
403
  ],
359
404
  undefined,
360
405
  );
@@ -371,7 +416,7 @@ describe("entities create", () => {
371
416
  const sdk = mockSdk();
372
417
  vi.mocked(sdk.entities.create).mockResolvedValue("entity-with-opts");
373
418
  vi.mocked(readJsonInput).mockResolvedValue({
374
- fields: [{ fieldName: "amount", type: "DECIMAL" }],
419
+ fields: [{ name: "amount", type: "DECIMAL" }],
375
420
  displayName: "My Entity",
376
421
  description: "A test entity",
377
422
  isRbacEnabled: true,
@@ -385,12 +430,12 @@ describe("entities create", () => {
385
430
  "create",
386
431
  "MyEntity",
387
432
  "--body",
388
- '{"fields":[{"fieldName":"amount","type":"DECIMAL"}],"displayName":"My Entity","description":"A test entity","isRbacEnabled":true}',
433
+ '{"fields":[{"name":"amount","type":"DECIMAL"}],"displayName":"My Entity","description":"A test entity","isRbacEnabled":true}',
389
434
  ]);
390
435
 
391
436
  expect(sdk.entities.create).toHaveBeenCalledWith(
392
437
  "MyEntity",
393
- [{ fieldName: "amount", type: "DECIMAL" }],
438
+ [{ name: "amount", type: "DECIMAL" }],
394
439
  expect.objectContaining({
395
440
  displayName: "My Entity",
396
441
  description: "A test entity",
@@ -405,11 +450,40 @@ describe("entities create", () => {
405
450
  );
406
451
  });
407
452
 
453
+ it("should forward isAnalyticsEnabled to create", async () => {
454
+ const sdk = mockSdk();
455
+ vi.mocked(sdk.entities.create).mockResolvedValue("analytics-entity");
456
+ vi.mocked(readJsonInput).mockResolvedValue({
457
+ fields: [{ name: "amount", type: "DECIMAL" }],
458
+ isAnalyticsEnabled: true,
459
+ });
460
+
461
+ const program = buildProgram();
462
+ await program.parseAsync([
463
+ "node",
464
+ "test",
465
+ "entities",
466
+ "create",
467
+ "MyEntity",
468
+ "--body",
469
+ '{"fields":[{"name":"amount","type":"DECIMAL"}],"isAnalyticsEnabled":true}',
470
+ ]);
471
+
472
+ expect(sdk.entities.create).toHaveBeenCalledWith(
473
+ "MyEntity",
474
+ [{ name: "amount", type: "DECIMAL" }],
475
+ expect.objectContaining({ isAnalyticsEnabled: true }),
476
+ );
477
+ expect(OutputFormatter.success).toHaveBeenCalledWith(
478
+ expect.objectContaining({ Code: "EntityCreated" }),
479
+ );
480
+ });
481
+
408
482
  it("should create entity with only displayName (partial options)", async () => {
409
483
  const sdk = mockSdk();
410
484
  vi.mocked(sdk.entities.create).mockResolvedValue("entity-partial");
411
485
  vi.mocked(readJsonInput).mockResolvedValue({
412
- fields: [{ fieldName: "name", type: "STRING" }],
486
+ fields: [{ name: "name", type: "STRING" }],
413
487
  displayName: "Partial Entity",
414
488
  });
415
489
 
@@ -421,7 +495,7 @@ describe("entities create", () => {
421
495
  "create",
422
496
  "PartialEntity",
423
497
  "--body",
424
- '{"fields":[{"fieldName":"name","type":"STRING"}],"displayName":"Partial Entity"}',
498
+ '{"fields":[{"name":"name","type":"STRING"}],"displayName":"Partial Entity"}',
425
499
  ]);
426
500
 
427
501
  expect(sdk.entities.create).toHaveBeenCalledWith(
@@ -441,7 +515,7 @@ describe("entities create", () => {
441
515
  );
442
516
  const fields = [
443
517
  {
444
- fieldName: "opType",
518
+ name: "opType",
445
519
  type: "CHOICE_SET_SINGLE",
446
520
  choiceSetId: "9db00b66-9952-f111-8ef3-6045bd07956d",
447
521
  isRequired: true,
@@ -464,7 +538,7 @@ describe("entities create", () => {
464
538
  "CliTestExpense",
465
539
  expect.arrayContaining([
466
540
  expect.objectContaining({
467
- fieldName: "opType",
541
+ name: "opType",
468
542
  type: "CHOICE_SET_SINGLE",
469
543
  choiceSetId: "9db00b66-9952-f111-8ef3-6045bd07956d",
470
544
  }),
@@ -481,7 +555,7 @@ describe("entities create", () => {
481
555
  vi.mocked(sdk.entities.create).mockResolvedValue("entity-choice-multi");
482
556
  const fields = [
483
557
  {
484
- fieldName: "multiOpType",
558
+ name: "multiOpType",
485
559
  type: "CHOICE_SET_MULTIPLE",
486
560
  choiceSetId: "9db00b66-9952-f111-8ef3-6045bd07956d",
487
561
  },
@@ -503,7 +577,7 @@ describe("entities create", () => {
503
577
  "CliTestExpense",
504
578
  expect.arrayContaining([
505
579
  expect.objectContaining({
506
- fieldName: "multiOpType",
580
+ name: "multiOpType",
507
581
  type: "CHOICE_SET_MULTIPLE",
508
582
  choiceSetId: "9db00b66-9952-f111-8ef3-6045bd07956d",
509
583
  }),
@@ -520,7 +594,7 @@ describe("entities create", () => {
520
594
  vi.mocked(sdk.entities.create).mockResolvedValue("entity-rel");
521
595
  const fields = [
522
596
  {
523
- fieldName: "rel1",
597
+ name: "rel1",
524
598
  type: "RELATIONSHIP",
525
599
  referenceEntityId: "a1b2c3d4-0000-0000-0000-000000000010",
526
600
  referenceFieldId: "f1000000-0000-0000-0000-000000000100",
@@ -543,7 +617,7 @@ describe("entities create", () => {
543
617
  "CliTestExpense",
544
618
  expect.arrayContaining([
545
619
  expect.objectContaining({
546
- fieldName: "rel1",
620
+ name: "rel1",
547
621
  type: "RELATIONSHIP",
548
622
  referenceEntityId: "a1b2c3d4-0000-0000-0000-000000000010",
549
623
  referenceFieldId: "f1000000-0000-0000-0000-000000000100",
@@ -561,7 +635,7 @@ describe("entities create", () => {
561
635
  vi.mocked(sdk.entities.create).mockResolvedValue("entity-xfolder-rel");
562
636
  const fields = [
563
637
  {
564
- fieldName: "purchaseOrder",
638
+ name: "purchaseOrder",
565
639
  type: "RELATIONSHIP",
566
640
  referenceEntityId: "a1b2c3d4-0000-0000-0000-000000000010",
567
641
  referenceFieldId: "f1000000-0000-0000-0000-000000000100",
@@ -587,7 +661,7 @@ describe("entities create", () => {
587
661
  "OrderLine",
588
662
  expect.arrayContaining([
589
663
  expect.objectContaining({
590
- fieldName: "purchaseOrder",
664
+ name: "purchaseOrder",
591
665
  type: "RELATIONSHIP",
592
666
  referenceFolderKey: "f1000000-0000-0000-0000-000000000060",
593
667
  }),
@@ -671,7 +745,7 @@ describe("entities create", () => {
671
745
  expect(process.exitCode).toBe(1);
672
746
  });
673
747
 
674
- it("should error when a field is missing fieldName", async () => {
748
+ it("should error when a field is missing name", async () => {
675
749
  vi.mocked(readJsonInput).mockResolvedValue({
676
750
  fields: [{ type: "STRING" }],
677
751
  });
@@ -690,7 +764,7 @@ describe("entities create", () => {
690
764
  expect(OutputFormatter.error).toHaveBeenCalledWith(
691
765
  expect.objectContaining({
692
766
  Result: "Failure",
693
- Message: "Each field must include a 'fieldName' string",
767
+ Message: "Each field must include a 'name' string",
694
768
  }),
695
769
  );
696
770
  expect(process.exitCode).toBe(1);
@@ -698,7 +772,7 @@ describe("entities create", () => {
698
772
 
699
773
  it("should error when a field has an invalid type", async () => {
700
774
  vi.mocked(readJsonInput).mockResolvedValue({
701
- fields: [{ fieldName: "title", type: "text" }],
775
+ fields: [{ name: "title", type: "text" }],
702
776
  });
703
777
 
704
778
  const program = buildProgram();
@@ -709,7 +783,7 @@ describe("entities create", () => {
709
783
  "create",
710
784
  "MyEntity",
711
785
  "--body",
712
- '{"fields":[{"fieldName":"title","type":"text"}]}',
786
+ '{"fields":[{"name":"title","type":"text"}]}',
713
787
  ]);
714
788
 
715
789
  expect(OutputFormatter.error).toHaveBeenCalledWith(
@@ -724,7 +798,7 @@ describe("entities create", () => {
724
798
  it("should bail when SDK connection fails on create", async () => {
725
799
  const sdk = mockSdk();
726
800
  vi.mocked(readJsonInput).mockResolvedValue({
727
- fields: [{ fieldName: "title", type: "STRING" }],
801
+ fields: [{ name: "title", type: "STRING" }],
728
802
  });
729
803
  vi.mocked(connectOrFail).mockResolvedValue(undefined);
730
804
 
@@ -736,7 +810,7 @@ describe("entities create", () => {
736
810
  "create",
737
811
  "MyEntity",
738
812
  "--body",
739
- '{"fields":[{"fieldName":"title","type":"STRING"}]}',
813
+ '{"fields":[{"name":"title","type":"STRING"}]}',
740
814
  ]);
741
815
 
742
816
  expect(sdk.entities.create).not.toHaveBeenCalled();
@@ -749,7 +823,7 @@ describe("entities create", () => {
749
823
  new Error("Entity already exists"),
750
824
  );
751
825
  vi.mocked(readJsonInput).mockResolvedValue({
752
- fields: [{ fieldName: "title", type: "STRING" }],
826
+ fields: [{ name: "title", type: "STRING" }],
753
827
  });
754
828
 
755
829
  const program = buildProgram();
@@ -760,7 +834,7 @@ describe("entities create", () => {
760
834
  "create",
761
835
  "MyEntity",
762
836
  "--body",
763
- '{"fields":[{"fieldName":"title","type":"STRING"}]}',
837
+ '{"fields":[{"name":"title","type":"STRING"}]}',
764
838
  ]);
765
839
 
766
840
  expect(OutputFormatter.error).toHaveBeenCalledWith(
@@ -775,7 +849,7 @@ describe("entities create", () => {
775
849
  it("should reject an entity name that starts with a digit", async () => {
776
850
  const sdk = mockSdk();
777
851
  vi.mocked(readJsonInput).mockResolvedValue({
778
- fields: [{ fieldName: "title", type: "STRING" }],
852
+ fields: [{ name: "title", type: "STRING" }],
779
853
  });
780
854
 
781
855
  const program = buildProgram();
@@ -786,7 +860,7 @@ describe("entities create", () => {
786
860
  "create",
787
861
  "1Bad",
788
862
  "--body",
789
- '{"fields":[{"fieldName":"title","type":"STRING"}]}',
863
+ '{"fields":[{"name":"title","type":"STRING"}]}',
790
864
  ]);
791
865
 
792
866
  expect(sdk.entities.create).not.toHaveBeenCalled();
@@ -802,7 +876,7 @@ describe("entities create", () => {
802
876
  it("should reject an entity name that is a reserved keyword", async () => {
803
877
  const sdk = mockSdk();
804
878
  vi.mocked(readJsonInput).mockResolvedValue({
805
- fields: [{ fieldName: "title", type: "STRING" }],
879
+ fields: [{ name: "title", type: "STRING" }],
806
880
  });
807
881
 
808
882
  const program = buildProgram();
@@ -813,7 +887,7 @@ describe("entities create", () => {
813
887
  "create",
814
888
  "Class",
815
889
  "--body",
816
- '{"fields":[{"fieldName":"title","type":"STRING"}]}',
890
+ '{"fields":[{"name":"title","type":"STRING"}]}',
817
891
  ]);
818
892
 
819
893
  expect(sdk.entities.create).not.toHaveBeenCalled();
@@ -829,7 +903,7 @@ describe("entities create", () => {
829
903
  it("should reject an entity name that is a confirmed SQL keyword", async () => {
830
904
  const sdk = mockSdk();
831
905
  vi.mocked(readJsonInput).mockResolvedValue({
832
- fields: [{ fieldName: "title", type: "STRING" }],
906
+ fields: [{ name: "title", type: "STRING" }],
833
907
  });
834
908
 
835
909
  const program = buildProgram();
@@ -840,7 +914,7 @@ describe("entities create", () => {
840
914
  "create",
841
915
  "Order",
842
916
  "--body",
843
- '{"fields":[{"fieldName":"title","type":"STRING"}]}',
917
+ '{"fields":[{"name":"title","type":"STRING"}]}',
844
918
  ]);
845
919
 
846
920
  expect(sdk.entities.create).not.toHaveBeenCalled();
@@ -853,10 +927,10 @@ describe("entities create", () => {
853
927
  expect(process.exitCode).toBe(1);
854
928
  });
855
929
 
856
- it("should reject a fieldName that is a reserved system field", async () => {
930
+ it("should reject a name that is a reserved system field", async () => {
857
931
  const sdk = mockSdk();
858
932
  vi.mocked(readJsonInput).mockResolvedValue({
859
- fields: [{ fieldName: "Id", type: "STRING" }],
933
+ fields: [{ name: "Id", type: "STRING" }],
860
934
  });
861
935
 
862
936
  const program = buildProgram();
@@ -867,7 +941,7 @@ describe("entities create", () => {
867
941
  "create",
868
942
  "MyEntity",
869
943
  "--body",
870
- '{"fields":[{"fieldName":"Id","type":"STRING"}]}',
944
+ '{"fields":[{"name":"Id","type":"STRING"}]}',
871
945
  ]);
872
946
 
873
947
  expect(sdk.entities.create).not.toHaveBeenCalled();
@@ -885,7 +959,7 @@ describe("entities create", () => {
885
959
  vi.mocked(readJsonInput).mockResolvedValue({
886
960
  fields: [
887
961
  {
888
- fieldName: "receipt",
962
+ name: "receipt",
889
963
  type: "FILE",
890
964
  referenceFolderKey: "folder-id",
891
965
  },
@@ -900,7 +974,7 @@ describe("entities create", () => {
900
974
  "create",
901
975
  "MyEntity",
902
976
  "--body",
903
- '{"fields":[{"fieldName":"receipt","type":"FILE","referenceFolderKey":"folder-id"}]}',
977
+ '{"fields":[{"name":"receipt","type":"FILE","referenceFolderKey":"folder-id"}]}',
904
978
  ]);
905
979
 
906
980
  expect(sdk.entities.create).not.toHaveBeenCalled();
@@ -918,7 +992,7 @@ describe("entities create", () => {
918
992
  it("should reject a UI-broken field type", async () => {
919
993
  const sdk = mockSdk();
920
994
  vi.mocked(readJsonInput).mockResolvedValue({
921
- fields: [{ fieldName: "count", type: "INTEGER" }],
995
+ fields: [{ name: "count", type: "INTEGER" }],
922
996
  });
923
997
 
924
998
  const program = buildProgram();
@@ -929,7 +1003,7 @@ describe("entities create", () => {
929
1003
  "create",
930
1004
  "MyEntity",
931
1005
  "--body",
932
- '{"fields":[{"fieldName":"count","type":"INTEGER"}]}',
1006
+ '{"fields":[{"name":"count","type":"INTEGER"}]}',
933
1007
  ]);
934
1008
 
935
1009
  expect(sdk.entities.create).not.toHaveBeenCalled();
@@ -952,10 +1026,25 @@ describe("entities update", () => {
952
1026
  process.exitCode = undefined;
953
1027
  });
954
1028
 
1029
+ it("should document update field shapes in --help", () => {
1030
+ const program = buildProgram();
1031
+ const cmd = program.commands.find((c) => c.name() === "entities");
1032
+ const updateCmd = cmd?.commands.find((c) => c.name() === "update");
1033
+ expect(updateCmd).toBeDefined();
1034
+
1035
+ const help = updateCmd?.helpInformation() ?? "";
1036
+ expect(help).toContain("addFields [{name,type,...}]");
1037
+ expect(help).toContain("updateFields [{id,...}]");
1038
+ expect(help).toContain("removeFields [{name}]");
1039
+ expect(help.replace(/\s+/g, " ")).toContain(
1040
+ "Do not paste a full copied field object into updateFields",
1041
+ );
1042
+ });
1043
+
955
1044
  it("should update entity by adding new fields (addFields)", async () => {
956
1045
  const sdk = mockSdk();
957
1046
  vi.mocked(readJsonInput).mockResolvedValue({
958
- addFields: [{ fieldName: "newField", type: "STRING" }],
1047
+ addFields: [{ name: "newField", type: "STRING" }],
959
1048
  });
960
1049
 
961
1050
  const program = buildProgram();
@@ -966,13 +1055,13 @@ describe("entities update", () => {
966
1055
  "update",
967
1056
  "entity-id",
968
1057
  "--body",
969
- '{"addFields":[{"fieldName":"newField","type":"STRING"}]}',
1058
+ '{"addFields":[{"name":"newField","type":"STRING"}]}',
970
1059
  ]);
971
1060
 
972
1061
  expect(sdk.entities.updateById).toHaveBeenCalledWith(
973
1062
  "entity-id",
974
1063
  expect.objectContaining({
975
- addFields: [{ fieldName: "newField", type: "STRING" }],
1064
+ addFields: [{ name: "newField", type: "STRING" }],
976
1065
  }),
977
1066
  );
978
1067
  expect(OutputFormatter.success).toHaveBeenCalledWith(
@@ -984,11 +1073,167 @@ describe("entities update", () => {
984
1073
  );
985
1074
  });
986
1075
 
1076
+ it("should normalize addFields copied from entities get read shape", async () => {
1077
+ const sdk = mockSdk();
1078
+ vi.mocked(readJsonInput).mockResolvedValue({
1079
+ addFields: [
1080
+ {
1081
+ Name: "note",
1082
+ DisplayName: "Note",
1083
+ FieldDataType: {
1084
+ Name: "STRING",
1085
+ LengthLimit: 200,
1086
+ },
1087
+ IsRequired: true,
1088
+ },
1089
+ ],
1090
+ });
1091
+
1092
+ const program = buildProgram();
1093
+ await program.parseAsync([
1094
+ "node",
1095
+ "test",
1096
+ "entities",
1097
+ "update",
1098
+ "entity-id",
1099
+ "--body",
1100
+ '{"addFields":[{"Name":"note","DisplayName":"Note","FieldDataType":{"Name":"STRING","LengthLimit":200},"IsRequired":true}]}',
1101
+ ]);
1102
+
1103
+ expect(sdk.entities.updateById).toHaveBeenCalledWith(
1104
+ "entity-id",
1105
+ expect.objectContaining({
1106
+ addFields: [
1107
+ {
1108
+ name: "note",
1109
+ displayName: "Note",
1110
+ type: "STRING",
1111
+ lengthLimit: 200,
1112
+ isRequired: true,
1113
+ },
1114
+ ],
1115
+ }),
1116
+ );
1117
+ expect(OutputFormatter.success).toHaveBeenCalledWith(
1118
+ expect.objectContaining({ Code: "EntityUpdated" }),
1119
+ );
1120
+ });
1121
+
1122
+ it("should normalize a copied RELATIONSHIP field into referenceEntityId and referenceFieldId", async () => {
1123
+ const sdk = mockSdk();
1124
+ // Shape a user copies out of `df entities get`: the SDK returns
1125
+ // referenceEntity/referenceField objects and the formatter PascalCases
1126
+ // every key on the way out.
1127
+ const copiedField = {
1128
+ Id: "f1000000-0000-0000-0000-000000000200",
1129
+ Name: "submitter",
1130
+ DisplayName: "Submitter",
1131
+ FieldDataType: { Name: "RELATIONSHIP" },
1132
+ IsRequired: true,
1133
+ ReferenceType: "ManyToOne",
1134
+ ReferenceEntity: {
1135
+ Id: "a1b2c3d4-0000-0000-0000-000000000010",
1136
+ Name: "Person",
1137
+ DisplayName: "Person",
1138
+ },
1139
+ ReferenceField: {
1140
+ Id: "f1000000-0000-0000-0000-000000000100",
1141
+ Definition: {
1142
+ Id: "f1000000-0000-0000-0000-000000000100",
1143
+ Name: "email",
1144
+ },
1145
+ },
1146
+ };
1147
+ vi.mocked(readJsonInput).mockResolvedValue({
1148
+ addFields: [copiedField],
1149
+ });
1150
+
1151
+ const program = buildProgram();
1152
+ await program.parseAsync([
1153
+ "node",
1154
+ "test",
1155
+ "entities",
1156
+ "update",
1157
+ "entity-id",
1158
+ "--body",
1159
+ JSON.stringify({ addFields: [copiedField] }),
1160
+ ]);
1161
+
1162
+ expect(sdk.entities.updateById).toHaveBeenCalledWith(
1163
+ "entity-id",
1164
+ expect.objectContaining({
1165
+ addFields: [
1166
+ {
1167
+ name: "submitter",
1168
+ type: "RELATIONSHIP",
1169
+ displayName: "Submitter",
1170
+ isRequired: true,
1171
+ referenceEntityId:
1172
+ "a1b2c3d4-0000-0000-0000-000000000010",
1173
+ referenceFieldId:
1174
+ "f1000000-0000-0000-0000-000000000100",
1175
+ },
1176
+ ],
1177
+ }),
1178
+ );
1179
+ expect(OutputFormatter.success).toHaveBeenCalledWith(
1180
+ expect.objectContaining({ Code: "EntityUpdated" }),
1181
+ );
1182
+ });
1183
+
1184
+ it("should normalize a copied CHOICE_SET_SINGLE field into choiceSetId", async () => {
1185
+ const sdk = mockSdk();
1186
+ const copiedField = {
1187
+ Id: "f1000000-0000-0000-0000-000000000201",
1188
+ Name: "category",
1189
+ DisplayName: "Category",
1190
+ FieldDataType: { Name: "CHOICE_SET_SINGLE" },
1191
+ IsRequired: true,
1192
+ ReferenceChoiceSet: {
1193
+ Id: "c1d2e3f4-0000-0000-0000-000000000001",
1194
+ Name: "ExpenseCategory",
1195
+ DisplayName: "Expense Category",
1196
+ },
1197
+ };
1198
+ vi.mocked(readJsonInput).mockResolvedValue({
1199
+ addFields: [copiedField],
1200
+ });
1201
+
1202
+ const program = buildProgram();
1203
+ await program.parseAsync([
1204
+ "node",
1205
+ "test",
1206
+ "entities",
1207
+ "update",
1208
+ "entity-id",
1209
+ "--body",
1210
+ JSON.stringify({ addFields: [copiedField] }),
1211
+ ]);
1212
+
1213
+ expect(sdk.entities.updateById).toHaveBeenCalledWith(
1214
+ "entity-id",
1215
+ expect.objectContaining({
1216
+ addFields: [
1217
+ {
1218
+ name: "category",
1219
+ type: "CHOICE_SET_SINGLE",
1220
+ displayName: "Category",
1221
+ isRequired: true,
1222
+ choiceSetId: "c1d2e3f4-0000-0000-0000-000000000001",
1223
+ },
1224
+ ],
1225
+ }),
1226
+ );
1227
+ expect(OutputFormatter.success).toHaveBeenCalledWith(
1228
+ expect.objectContaining({ Code: "EntityUpdated" }),
1229
+ );
1230
+ });
1231
+
987
1232
  it("should update entity by adding a RELATIONSHIP field with referenceEntityId and referenceFieldId", async () => {
988
1233
  const sdk = mockSdk();
989
1234
  const addFields = [
990
1235
  {
991
- fieldName: "rel1",
1236
+ name: "rel1",
992
1237
  type: "RELATIONSHIP",
993
1238
  referenceEntityId: "a1b2c3d4-0000-0000-0000-000000000010",
994
1239
  referenceFieldId: "f1000000-0000-0000-0000-000000000100",
@@ -1020,7 +1265,7 @@ describe("entities update", () => {
1020
1265
  const sdk = mockSdk();
1021
1266
  const addFields = [
1022
1267
  {
1023
- fieldName: "purchaseOrder",
1268
+ name: "purchaseOrder",
1024
1269
  type: "RELATIONSHIP",
1025
1270
  referenceEntityId: "a1b2c3d4-0000-0000-0000-000000000010",
1026
1271
  referenceFieldId: "f1000000-0000-0000-0000-000000000100",
@@ -1057,7 +1302,7 @@ describe("entities update", () => {
1057
1302
  const sdk = mockSdk();
1058
1303
  const addFields = [
1059
1304
  {
1060
- fieldName: "multiOpType",
1305
+ name: "multiOpType",
1061
1306
  type: "CHOICE_SET_MULTIPLE",
1062
1307
  choiceSetId: "9db00b66-9952-f111-8ef3-6045bd07956d",
1063
1308
  },
@@ -1191,7 +1436,7 @@ describe("entities update", () => {
1191
1436
  it("should remove a CHOICE_SET_SINGLE field via removeFields with --confirm and --reason", async () => {
1192
1437
  const sdk = mockSdk();
1193
1438
  vi.mocked(readJsonInput).mockResolvedValue({
1194
- removeFields: [{ fieldName: "opType" }],
1439
+ removeFields: [{ name: "opType" }],
1195
1440
  });
1196
1441
 
1197
1442
  const program = buildProgram();
@@ -1202,7 +1447,7 @@ describe("entities update", () => {
1202
1447
  "update",
1203
1448
  "entity-id",
1204
1449
  "--body",
1205
- '{"removeFields":[{"fieldName":"opType"}]}',
1450
+ '{"removeFields":[{"name":"opType"}]}',
1206
1451
  "--confirm",
1207
1452
  "--reason",
1208
1453
  "dropping single-select choice-set field",
@@ -1211,7 +1456,7 @@ describe("entities update", () => {
1211
1456
  expect(sdk.entities.updateById).toHaveBeenCalledWith(
1212
1457
  "entity-id",
1213
1458
  expect.objectContaining({
1214
- removeFields: [{ fieldName: "opType" }],
1459
+ removeFields: [{ name: "opType" }],
1215
1460
  }),
1216
1461
  );
1217
1462
  expect(OutputFormatter.success).toHaveBeenCalledWith(
@@ -1229,7 +1474,7 @@ describe("entities update", () => {
1229
1474
  it("should remove a CHOICE_SET_MULTIPLE field via removeFields with --confirm and --reason", async () => {
1230
1475
  const sdk = mockSdk();
1231
1476
  vi.mocked(readJsonInput).mockResolvedValue({
1232
- removeFields: [{ fieldName: "multiOpType" }],
1477
+ removeFields: [{ name: "multiOpType" }],
1233
1478
  });
1234
1479
 
1235
1480
  const program = buildProgram();
@@ -1240,7 +1485,7 @@ describe("entities update", () => {
1240
1485
  "update",
1241
1486
  "entity-id",
1242
1487
  "--body",
1243
- '{"removeFields":[{"fieldName":"multiOpType"}]}',
1488
+ '{"removeFields":[{"name":"multiOpType"}]}',
1244
1489
  "--confirm",
1245
1490
  "--reason",
1246
1491
  "dropping multi-select choice-set field",
@@ -1249,7 +1494,7 @@ describe("entities update", () => {
1249
1494
  expect(sdk.entities.updateById).toHaveBeenCalledWith(
1250
1495
  "entity-id",
1251
1496
  expect.objectContaining({
1252
- removeFields: [{ fieldName: "multiOpType" }],
1497
+ removeFields: [{ name: "multiOpType" }],
1253
1498
  }),
1254
1499
  );
1255
1500
  expect(OutputFormatter.success).toHaveBeenCalledWith(
@@ -1265,10 +1510,7 @@ describe("entities update", () => {
1265
1510
  it("should remove both choice-set fields in a single removeFields call", async () => {
1266
1511
  const sdk = mockSdk();
1267
1512
  vi.mocked(readJsonInput).mockResolvedValue({
1268
- removeFields: [
1269
- { fieldName: "opType" },
1270
- { fieldName: "multiOpType" },
1271
- ],
1513
+ removeFields: [{ name: "opType" }, { name: "multiOpType" }],
1272
1514
  });
1273
1515
 
1274
1516
  const program = buildProgram();
@@ -1279,7 +1521,7 @@ describe("entities update", () => {
1279
1521
  "update",
1280
1522
  "entity-id",
1281
1523
  "--body",
1282
- '{"removeFields":[{"fieldName":"opType"},{"fieldName":"multiOpType"}]}',
1524
+ '{"removeFields":[{"name":"opType"},{"name":"multiOpType"}]}',
1283
1525
  "--confirm",
1284
1526
  "--reason",
1285
1527
  "dropping all choice-set fields",
@@ -1288,10 +1530,7 @@ describe("entities update", () => {
1288
1530
  expect(sdk.entities.updateById).toHaveBeenCalledWith(
1289
1531
  "entity-id",
1290
1532
  expect.objectContaining({
1291
- removeFields: [
1292
- { fieldName: "opType" },
1293
- { fieldName: "multiOpType" },
1294
- ],
1533
+ removeFields: [{ name: "opType" }, { name: "multiOpType" }],
1295
1534
  }),
1296
1535
  );
1297
1536
  expect(OutputFormatter.success).toHaveBeenCalledWith(
@@ -1336,10 +1575,37 @@ describe("entities update", () => {
1336
1575
  );
1337
1576
  });
1338
1577
 
1578
+ it("should forward isAnalyticsEnabled to updateById", async () => {
1579
+ const sdk = mockSdk();
1580
+ vi.mocked(readJsonInput).mockResolvedValue({
1581
+ displayName: "My Entity",
1582
+ isAnalyticsEnabled: true,
1583
+ });
1584
+
1585
+ const program = buildProgram();
1586
+ await program.parseAsync([
1587
+ "node",
1588
+ "test",
1589
+ "entities",
1590
+ "update",
1591
+ "entity-id",
1592
+ "--body",
1593
+ '{"displayName":"My Entity","isAnalyticsEnabled":true}',
1594
+ ]);
1595
+
1596
+ expect(sdk.entities.updateById).toHaveBeenCalledWith(
1597
+ "entity-id",
1598
+ expect.objectContaining({ isAnalyticsEnabled: true }),
1599
+ );
1600
+ expect(OutputFormatter.success).toHaveBeenCalledWith(
1601
+ expect.objectContaining({ Code: "EntityUpdated" }),
1602
+ );
1603
+ });
1604
+
1339
1605
  it("should update entity with combined addFields, updateFields, and metadata", async () => {
1340
1606
  const sdk = mockSdk();
1341
1607
  vi.mocked(readJsonInput).mockResolvedValue({
1342
- addFields: [{ fieldName: "newField", type: "STRING" }],
1608
+ addFields: [{ name: "newField", type: "STRING" }],
1343
1609
  updateFields: [{ id: "field-uuid-1", isRequired: false }],
1344
1610
  displayName: "Combined Update",
1345
1611
  isRbacEnabled: true,
@@ -1353,7 +1619,7 @@ describe("entities update", () => {
1353
1619
  "update",
1354
1620
  "entity-id",
1355
1621
  "--body",
1356
- '{"addFields":[{"fieldName":"newField","type":"STRING"}],"updateFields":[{"id":"field-uuid-1","isRequired":false}],"displayName":"Combined Update","isRbacEnabled":true}',
1622
+ '{"addFields":[{"name":"newField","type":"STRING"}],"updateFields":[{"id":"field-uuid-1","isRequired":false}],"displayName":"Combined Update","isRbacEnabled":true}',
1357
1623
  ]);
1358
1624
 
1359
1625
  expect(sdk.entities.updateById).toHaveBeenCalledWith(
@@ -1373,7 +1639,8 @@ describe("entities update", () => {
1373
1639
  );
1374
1640
  });
1375
1641
 
1376
- it("should reject addFields items missing fieldName", async () => {
1642
+ it("should reject addFields items missing name", async () => {
1643
+ const sdk = mockSdk();
1377
1644
  vi.mocked(readJsonInput).mockResolvedValue({
1378
1645
  addFields: [{ type: "STRING" }],
1379
1646
  });
@@ -1393,15 +1660,152 @@ describe("entities update", () => {
1393
1660
  expect.objectContaining({
1394
1661
  Result: "Failure",
1395
1662
  Message:
1396
- "Each field in addFields must include a non-empty 'fieldName' string",
1663
+ "Each field in addFields must include a non-empty 'name' string",
1664
+ }),
1665
+ );
1666
+ expect(sdk.entities.updateById).not.toHaveBeenCalled();
1667
+ expect(process.exitCode).toBe(1);
1668
+ });
1669
+
1670
+ it("should reject a name in the update body since the entity name is immutable", async () => {
1671
+ const sdk = mockSdk();
1672
+ vi.mocked(readJsonInput).mockResolvedValue({
1673
+ name: "RenamedEntity",
1674
+ displayName: "Renamed Entity",
1675
+ });
1676
+
1677
+ const program = buildProgram();
1678
+ await program.parseAsync([
1679
+ "node",
1680
+ "test",
1681
+ "entities",
1682
+ "update",
1683
+ "entity-id",
1684
+ "--body",
1685
+ '{"name":"RenamedEntity","displayName":"Renamed Entity"}',
1686
+ ]);
1687
+
1688
+ expect(sdk.entities.updateById).not.toHaveBeenCalled();
1689
+ expect(OutputFormatter.error).toHaveBeenCalledWith(
1690
+ expect.objectContaining({
1691
+ Result: "Failure",
1692
+ Message: expect.stringContaining(
1693
+ "Entity name cannot be changed after creation",
1694
+ ),
1695
+ Instructions: expect.stringContaining(
1696
+ "Remove 'name' from the update body",
1697
+ ),
1698
+ }),
1699
+ );
1700
+ expect(process.exitCode).toBe(1);
1701
+ });
1702
+
1703
+ it("should require displayName when updating description without it", async () => {
1704
+ const sdk = mockSdk();
1705
+ vi.mocked(readJsonInput).mockResolvedValue({
1706
+ description: "New description",
1707
+ });
1708
+
1709
+ const program = buildProgram();
1710
+ await program.parseAsync([
1711
+ "node",
1712
+ "test",
1713
+ "entities",
1714
+ "update",
1715
+ "entity-id",
1716
+ "--body",
1717
+ '{"description":"New description"}',
1718
+ ]);
1719
+
1720
+ expect(sdk.entities.updateById).not.toHaveBeenCalled();
1721
+ expect(OutputFormatter.error).toHaveBeenCalledWith(
1722
+ expect.objectContaining({
1723
+ Result: "Failure",
1724
+ Message: expect.stringContaining(
1725
+ "'displayName' is required when updating entity metadata",
1726
+ ),
1397
1727
  }),
1398
1728
  );
1399
1729
  expect(process.exitCode).toBe(1);
1400
1730
  });
1401
1731
 
1732
+ it("should allow a metadata update that includes displayName", async () => {
1733
+ const sdk = mockSdk();
1734
+ vi.mocked(readJsonInput).mockResolvedValue({
1735
+ displayName: "Current Name",
1736
+ description: "New description",
1737
+ });
1738
+
1739
+ const program = buildProgram();
1740
+ await program.parseAsync([
1741
+ "node",
1742
+ "test",
1743
+ "entities",
1744
+ "update",
1745
+ "entity-id",
1746
+ "--body",
1747
+ '{"displayName":"Current Name","description":"New description"}',
1748
+ ]);
1749
+
1750
+ expect(sdk.entities.updateById).toHaveBeenCalledWith(
1751
+ "entity-id",
1752
+ expect.objectContaining({
1753
+ displayName: "Current Name",
1754
+ description: "New description",
1755
+ }),
1756
+ );
1757
+ expect(OutputFormatter.success).toHaveBeenCalledWith(
1758
+ expect.objectContaining({ Code: "EntityUpdated" }),
1759
+ );
1760
+ });
1761
+
1762
+ it("should report malformed addFields and removeFields together", async () => {
1763
+ const sdk = mockSdk();
1764
+ vi.mocked(readJsonInput).mockResolvedValue({
1765
+ addFields: [{ type: "STRING" }],
1766
+ removeFields: ["oldField"],
1767
+ });
1768
+
1769
+ const program = buildProgram();
1770
+ await program.parseAsync([
1771
+ "node",
1772
+ "test",
1773
+ "entities",
1774
+ "update",
1775
+ "entity-id",
1776
+ "--body",
1777
+ '{"addFields":[{"type":"STRING"}],"removeFields":["oldField"]}',
1778
+ "--yes",
1779
+ "--reason",
1780
+ "temporary validation",
1781
+ ]);
1782
+
1783
+ expect(sdk.entities.updateById).not.toHaveBeenCalled();
1784
+ expect(OutputFormatter.error).toHaveBeenCalledWith(
1785
+ expect.objectContaining({
1786
+ Result: "Failure",
1787
+ Message: expect.stringContaining(
1788
+ "Each field in addFields must include a non-empty 'name' string",
1789
+ ),
1790
+ Instructions: expect.stringContaining(
1791
+ 'Example: {"removeFields":[{"name":"oldField"}]}',
1792
+ ),
1793
+ ErrorCode: "invalid_argument",
1794
+ Retry: "RetryWillNotFix",
1795
+ }),
1796
+ );
1797
+ const error = vi.mocked(OutputFormatter.error).mock.calls[0][0] as {
1798
+ Message: string;
1799
+ };
1800
+ expect(error.Message).toContain(
1801
+ "Each field in removeFields must include a non-empty 'name' string",
1802
+ );
1803
+ expect(process.exitCode).toBe(1);
1804
+ });
1805
+
1402
1806
  it("should error when addFields has an invalid type", async () => {
1403
1807
  vi.mocked(readJsonInput).mockResolvedValue({
1404
- addFields: [{ fieldName: "price", type: "text" }],
1808
+ addFields: [{ name: "price", type: "text" }],
1405
1809
  });
1406
1810
 
1407
1811
  const program = buildProgram();
@@ -1412,7 +1816,7 @@ describe("entities update", () => {
1412
1816
  "update",
1413
1817
  "entity-id",
1414
1818
  "--body",
1415
- '{"addFields":[{"fieldName":"price","type":"text"}]}',
1819
+ '{"addFields":[{"name":"price","type":"text"}]}',
1416
1820
  ]);
1417
1821
 
1418
1822
  expect(OutputFormatter.error).toHaveBeenCalledWith(
@@ -1478,7 +1882,7 @@ describe("entities update", () => {
1478
1882
  expect(process.exitCode).toBe(1);
1479
1883
  });
1480
1884
 
1481
- it("should reject removeFields entries missing fieldName", async () => {
1885
+ it("should reject removeFields entries missing name", async () => {
1482
1886
  vi.mocked(readJsonInput).mockResolvedValue({
1483
1887
  removeFields: [{}],
1484
1888
  });
@@ -1501,7 +1905,7 @@ describe("entities update", () => {
1501
1905
  expect.objectContaining({
1502
1906
  Result: "Failure",
1503
1907
  Message:
1504
- "Each field in removeFields must include a non-empty 'fieldName' string",
1908
+ "Each field in removeFields must include a non-empty 'name' string",
1505
1909
  }),
1506
1910
  );
1507
1911
  expect(process.exitCode).toBe(1);
@@ -1510,7 +1914,7 @@ describe("entities update", () => {
1510
1914
  it("should reject removeFields without confirmation: exit 1, SDK not called", async () => {
1511
1915
  const sdk = mockSdk();
1512
1916
  vi.mocked(readJsonInput).mockResolvedValue({
1513
- removeFields: [{ fieldName: "oldField" }],
1917
+ removeFields: [{ name: "oldField" }],
1514
1918
  });
1515
1919
 
1516
1920
  const program = buildProgram();
@@ -1521,7 +1925,7 @@ describe("entities update", () => {
1521
1925
  "update",
1522
1926
  "entity-id",
1523
1927
  "--body",
1524
- '{"removeFields":[{"fieldName":"oldField"}]}',
1928
+ '{"removeFields":[{"name":"oldField"}]}',
1525
1929
  "--reason",
1526
1930
  "drop legacy",
1527
1931
  ]);
@@ -1534,7 +1938,7 @@ describe("entities update", () => {
1534
1938
  it("should accept removeFields with --yes (canonical flag)", async () => {
1535
1939
  const sdk = mockSdk();
1536
1940
  vi.mocked(readJsonInput).mockResolvedValue({
1537
- removeFields: [{ fieldName: "oldField" }],
1941
+ removeFields: [{ name: "oldField" }],
1538
1942
  });
1539
1943
 
1540
1944
  const program = buildProgram();
@@ -1545,7 +1949,7 @@ describe("entities update", () => {
1545
1949
  "update",
1546
1950
  "entity-id",
1547
1951
  "--body",
1548
- '{"removeFields":[{"fieldName":"oldField"}]}',
1952
+ '{"removeFields":[{"name":"oldField"}]}',
1549
1953
  "--yes",
1550
1954
  "--reason",
1551
1955
  "drop legacy",
@@ -1560,7 +1964,7 @@ describe("entities update", () => {
1560
1964
  it("should reject removeFields without --reason", async () => {
1561
1965
  const sdk = mockSdk();
1562
1966
  vi.mocked(readJsonInput).mockResolvedValue({
1563
- removeFields: [{ fieldName: "oldField" }],
1967
+ removeFields: [{ name: "oldField" }],
1564
1968
  });
1565
1969
 
1566
1970
  const program = buildProgram();
@@ -1571,7 +1975,7 @@ describe("entities update", () => {
1571
1975
  "update",
1572
1976
  "entity-id",
1573
1977
  "--body",
1574
- '{"removeFields":[{"fieldName":"oldField"}]}',
1978
+ '{"removeFields":[{"name":"oldField"}]}',
1575
1979
  "--confirm",
1576
1980
  ]);
1577
1981
 
@@ -1580,6 +1984,7 @@ describe("entities update", () => {
1580
1984
  expect.objectContaining({
1581
1985
  Result: "Failure",
1582
1986
  Message: "Reason required for destructive operation",
1987
+ ErrorCode: "invalid_argument",
1583
1988
  }),
1584
1989
  );
1585
1990
  expect(process.exitCode).toBe(1);
@@ -1588,10 +1993,7 @@ describe("entities update", () => {
1588
1993
  it("should remove fields when --confirm and --reason are present", async () => {
1589
1994
  const sdk = mockSdk();
1590
1995
  vi.mocked(readJsonInput).mockResolvedValue({
1591
- removeFields: [
1592
- { fieldName: "oldField" },
1593
- { fieldName: "anotherOld" },
1594
- ],
1996
+ removeFields: [{ name: "oldField" }, { name: "anotherOld" }],
1595
1997
  });
1596
1998
 
1597
1999
  const program = buildProgram();
@@ -1602,7 +2004,7 @@ describe("entities update", () => {
1602
2004
  "update",
1603
2005
  "entity-id",
1604
2006
  "--body",
1605
- '{"removeFields":[{"fieldName":"oldField"},{"fieldName":"anotherOld"}]}',
2007
+ '{"removeFields":[{"name":"oldField"},{"name":"anotherOld"}]}',
1606
2008
  "--confirm",
1607
2009
  "--reason",
1608
2010
  "drop legacy fields",
@@ -1611,10 +2013,7 @@ describe("entities update", () => {
1611
2013
  expect(sdk.entities.updateById).toHaveBeenCalledWith(
1612
2014
  "entity-id",
1613
2015
  expect.objectContaining({
1614
- removeFields: [
1615
- { fieldName: "oldField" },
1616
- { fieldName: "anotherOld" },
1617
- ],
2016
+ removeFields: [{ name: "oldField" }, { name: "anotherOld" }],
1618
2017
  }),
1619
2018
  );
1620
2019
  expect(OutputFormatter.success).toHaveBeenCalledWith(
@@ -1656,8 +2055,8 @@ describe("entities update", () => {
1656
2055
  it("should accept addFields + removeFields + updateFields + metadata in one call", async () => {
1657
2056
  const sdk = mockSdk();
1658
2057
  vi.mocked(readJsonInput).mockResolvedValue({
1659
- addFields: [{ fieldName: "newField", type: "STRING" }],
1660
- removeFields: [{ fieldName: "oldField" }],
2058
+ addFields: [{ name: "newField", type: "STRING" }],
2059
+ removeFields: [{ name: "oldField" }],
1661
2060
  updateFields: [
1662
2061
  {
1663
2062
  id: "field-uuid-1",
@@ -1678,7 +2077,7 @@ describe("entities update", () => {
1678
2077
  "update",
1679
2078
  "entity-id",
1680
2079
  "--body",
1681
- '{"addFields":[{"fieldName":"newField","type":"STRING"}],"removeFields":[{"fieldName":"oldField"}],"updateFields":[{"id":"field-uuid-1","displayName":"Renamed","isRequired":true}],"displayName":"Combined","description":"all-in-one update","isRbacEnabled":true}',
2080
+ '{"addFields":[{"name":"newField","type":"STRING"}],"removeFields":[{"name":"oldField"}],"updateFields":[{"id":"field-uuid-1","displayName":"Renamed","isRequired":true}],"displayName":"Combined","description":"all-in-one update","isRbacEnabled":true}',
1682
2081
  "--confirm",
1683
2082
  "--reason",
1684
2083
  "schema overhaul",
@@ -1687,8 +2086,8 @@ describe("entities update", () => {
1687
2086
  expect(sdk.entities.updateById).toHaveBeenCalledWith(
1688
2087
  "entity-id",
1689
2088
  expect.objectContaining({
1690
- addFields: [{ fieldName: "newField", type: "STRING" }],
1691
- removeFields: [{ fieldName: "oldField" }],
2089
+ addFields: [{ name: "newField", type: "STRING" }],
2090
+ removeFields: [{ name: "oldField" }],
1692
2091
  updateFields: [
1693
2092
  {
1694
2093
  id: "field-uuid-1",
@@ -1714,11 +2113,11 @@ describe("entities update", () => {
1714
2113
  );
1715
2114
  });
1716
2115
 
1717
- it("should reject when same fieldName appears in addFields and removeFields", async () => {
2116
+ it("should reject when same name appears in addFields and removeFields", async () => {
1718
2117
  const sdk = mockSdk();
1719
2118
  vi.mocked(readJsonInput).mockResolvedValue({
1720
- addFields: [{ fieldName: "overlap", type: "STRING" }],
1721
- removeFields: [{ fieldName: "overlap" }],
2119
+ addFields: [{ name: "overlap", type: "STRING" }],
2120
+ removeFields: [{ name: "overlap" }],
1722
2121
  });
1723
2122
 
1724
2123
  const program = buildProgram();
@@ -1729,7 +2128,7 @@ describe("entities update", () => {
1729
2128
  "update",
1730
2129
  "entity-id",
1731
2130
  "--body",
1732
- '{"addFields":[{"fieldName":"overlap","type":"STRING"}],"removeFields":[{"fieldName":"overlap"}]}',
2131
+ '{"addFields":[{"name":"overlap","type":"STRING"}],"removeFields":[{"name":"overlap"}]}',
1733
2132
  "--confirm",
1734
2133
  "--reason",
1735
2134
  "recreate",
@@ -1746,12 +2145,12 @@ describe("entities update", () => {
1746
2145
  expect(process.exitCode).toBe(1);
1747
2146
  });
1748
2147
 
1749
- it("should reject duplicate fieldNames within addFields", async () => {
2148
+ it("should reject duplicate names within addFields", async () => {
1750
2149
  const sdk = mockSdk();
1751
2150
  vi.mocked(readJsonInput).mockResolvedValue({
1752
2151
  addFields: [
1753
- { fieldName: "dup", type: "STRING" },
1754
- { fieldName: "dup", type: "DECIMAL" },
2152
+ { name: "dup", type: "STRING" },
2153
+ { name: "dup", type: "DECIMAL" },
1755
2154
  ],
1756
2155
  });
1757
2156
 
@@ -1763,7 +2162,7 @@ describe("entities update", () => {
1763
2162
  "update",
1764
2163
  "entity-id",
1765
2164
  "--body",
1766
- '{"addFields":[{"fieldName":"dup","type":"STRING"},{"fieldName":"dup","type":"DECIMAL"}]}',
2165
+ '{"addFields":[{"name":"dup","type":"STRING"},{"name":"dup","type":"DECIMAL"}]}',
1767
2166
  ]);
1768
2167
 
1769
2168
  expect(sdk.entities.updateById).not.toHaveBeenCalled();
@@ -1883,10 +2282,10 @@ describe("entities update", () => {
1883
2282
  expect(call.Data).toEqual({ ID: "entity-id" });
1884
2283
  });
1885
2284
 
1886
- it("should reject empty fieldName in addFields", async () => {
2285
+ it("should reject empty name in addFields", async () => {
1887
2286
  const sdk = mockSdk();
1888
2287
  vi.mocked(readJsonInput).mockResolvedValue({
1889
- addFields: [{ fieldName: " ", type: "STRING" }],
2288
+ addFields: [{ name: " ", type: "STRING" }],
1890
2289
  });
1891
2290
 
1892
2291
  const program = buildProgram();
@@ -1897,7 +2296,7 @@ describe("entities update", () => {
1897
2296
  "update",
1898
2297
  "entity-id",
1899
2298
  "--body",
1900
- '{"addFields":[{"fieldName":" ","type":"STRING"}]}',
2299
+ '{"addFields":[{"name":" ","type":"STRING"}]}',
1901
2300
  ]);
1902
2301
 
1903
2302
  expect(sdk.entities.updateById).not.toHaveBeenCalled();
@@ -1905,7 +2304,7 @@ describe("entities update", () => {
1905
2304
  expect.objectContaining({
1906
2305
  Result: "Failure",
1907
2306
  Message:
1908
- "Each field in addFields must include a non-empty 'fieldName' string",
2307
+ "Each field in addFields must include a non-empty 'name' string",
1909
2308
  }),
1910
2309
  );
1911
2310
  expect(process.exitCode).toBe(1);
@@ -2015,7 +2414,7 @@ describe("entities update", () => {
2015
2414
  new Error("Update failed"),
2016
2415
  );
2017
2416
  vi.mocked(readJsonInput).mockResolvedValue({
2018
- addFields: [{ fieldName: "newField", type: "STRING" }],
2417
+ addFields: [{ name: "newField", type: "STRING" }],
2019
2418
  });
2020
2419
 
2021
2420
  const program = buildProgram();
@@ -2026,7 +2425,7 @@ describe("entities update", () => {
2026
2425
  "update",
2027
2426
  "entity-id",
2028
2427
  "--body",
2029
- '{"addFields":[{"fieldName":"newField","type":"STRING"}]}',
2428
+ '{"addFields":[{"name":"newField","type":"STRING"}]}',
2030
2429
  ]);
2031
2430
 
2032
2431
  expect(OutputFormatter.error).toHaveBeenCalledWith(
@@ -2041,7 +2440,7 @@ describe("entities update", () => {
2041
2440
  it("should reject a UI-broken type in addFields", async () => {
2042
2441
  const sdk = mockSdk();
2043
2442
  vi.mocked(readJsonInput).mockResolvedValue({
2044
- addFields: [{ fieldName: "count", type: "FLOAT" }],
2443
+ addFields: [{ name: "count", type: "FLOAT" }],
2045
2444
  });
2046
2445
 
2047
2446
  const program = buildProgram();
@@ -2052,7 +2451,7 @@ describe("entities update", () => {
2052
2451
  "update",
2053
2452
  "entity-id",
2054
2453
  "--body",
2055
- '{"addFields":[{"fieldName":"count","type":"FLOAT"}]}',
2454
+ '{"addFields":[{"name":"count","type":"FLOAT"}]}',
2056
2455
  ]);
2057
2456
 
2058
2457
  expect(sdk.entities.updateById).not.toHaveBeenCalled();
@@ -2070,7 +2469,7 @@ describe("entities update", () => {
2070
2469
  it("should reject a reserved keyword in addFields", async () => {
2071
2470
  const sdk = mockSdk();
2072
2471
  vi.mocked(readJsonInput).mockResolvedValue({
2073
- addFields: [{ fieldName: "New", type: "STRING" }],
2472
+ addFields: [{ name: "New", type: "STRING" }],
2074
2473
  });
2075
2474
 
2076
2475
  const program = buildProgram();
@@ -2081,7 +2480,7 @@ describe("entities update", () => {
2081
2480
  "update",
2082
2481
  "entity-id",
2083
2482
  "--body",
2084
- '{"addFields":[{"fieldName":"New","type":"STRING"}]}',
2483
+ '{"addFields":[{"name":"New","type":"STRING"}]}',
2085
2484
  ]);
2086
2485
 
2087
2486
  expect(sdk.entities.updateById).not.toHaveBeenCalled();
@@ -2225,6 +2624,7 @@ describe("entities delete", () => {
2225
2624
  expect.objectContaining({
2226
2625
  Result: "Failure",
2227
2626
  Message: "Reason required for destructive operation",
2627
+ ErrorCode: "invalid_argument",
2228
2628
  }),
2229
2629
  );
2230
2630
  expect(process.exitCode).toBe(1);
@@ -2250,6 +2650,7 @@ describe("entities delete", () => {
2250
2650
  expect.objectContaining({
2251
2651
  Result: "Failure",
2252
2652
  Message: "Reason required for destructive operation",
2653
+ ErrorCode: "invalid_argument",
2253
2654
  }),
2254
2655
  );
2255
2656
  expect(process.exitCode).toBe(1);
@@ -2336,7 +2737,7 @@ describe("entities --folder-key forwarding", () => {
2336
2737
  const sdk = mockSdk();
2337
2738
  vi.mocked(sdk.entities.create).mockResolvedValue("new-entity-id");
2338
2739
  vi.mocked(readJsonInput).mockResolvedValue({
2339
- fields: [{ fieldName: "title", type: "STRING" }],
2740
+ fields: [{ name: "title", type: "STRING" }],
2340
2741
  });
2341
2742
 
2342
2743
  const program = buildProgram();
@@ -2347,14 +2748,14 @@ describe("entities --folder-key forwarding", () => {
2347
2748
  "create",
2348
2749
  "MyEntity",
2349
2750
  "--body",
2350
- '{"fields":[{"fieldName":"title","type":"STRING"}]}',
2751
+ '{"fields":[{"name":"title","type":"STRING"}]}',
2351
2752
  "--folder-key",
2352
2753
  "folder-guid-2",
2353
2754
  ]);
2354
2755
 
2355
2756
  expect(sdk.entities.create).toHaveBeenCalledWith(
2356
2757
  "MyEntity",
2357
- [{ fieldName: "title", type: "STRING" }],
2758
+ [{ name: "title", type: "STRING" }],
2358
2759
  expect.objectContaining({ folderKey: "folder-guid-2" }),
2359
2760
  );
2360
2761
  });