@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.
@@ -143,7 +143,7 @@ describe("df entities — entities lifecycle", () => {
143
143
  "create",
144
144
  scratchName,
145
145
  "--body",
146
- '{"fields":[{"fieldName":"note","type":"STRING"}]}',
146
+ '{"fields":[{"name":"note","type":"STRING"}]}',
147
147
  ]);
148
148
  if (isAuthDenial(create)) {
149
149
  dfAccessDenied = true;
@@ -168,7 +168,7 @@ describe("df entities — entities lifecycle", () => {
168
168
  "--folder-key",
169
169
  scratchFolderKey,
170
170
  "--body",
171
- '{"fields":[{"fieldName":"note","type":"STRING"}]}',
171
+ '{"fields":[{"name":"note","type":"STRING"}]}',
172
172
  ]);
173
173
  if (createFolderEntity.exitCode === 0) {
174
174
  folderScopedEntityId = (
@@ -322,7 +322,7 @@ describe("df entities — entities lifecycle", () => {
322
322
  "create",
323
323
  name,
324
324
  "--body",
325
- '{"fields":[{"fieldName":"amount","type":"DECIMAL","decimalPrecision":2}]}',
325
+ '{"fields":[{"name":"amount","type":"DECIMAL","decimalPrecision":2}]}',
326
326
  ]);
327
327
  try {
328
328
  expect(created.Result).toBe("Success");
@@ -364,13 +364,13 @@ describe("df entities — entities lifecycle", () => {
364
364
  message: "Entity definition must include a 'fields' array",
365
365
  },
366
366
  {
367
- label: "field without fieldName",
367
+ label: "field without name",
368
368
  body: '{"fields":[{"type":"STRING"}]}',
369
- message: "Each field must include a 'fieldName' string",
369
+ message: "Each field must include a 'name' string",
370
370
  },
371
371
  {
372
372
  label: "unknown field type",
373
- body: '{"fields":[{"fieldName":"amount","type":"NOT_A_TYPE"}]}',
373
+ body: '{"fields":[{"name":"amount","type":"NOT_A_TYPE"}]}',
374
374
  message: "Invalid field type in fields",
375
375
  },
376
376
  ];
@@ -388,7 +388,7 @@ describe("df entities — entities lifecycle", () => {
388
388
 
389
389
  // ── S9 ── update composition on a transient scratch ─────────────────────
390
390
  it(
391
- "S9: update adds, edits, and removes fields in one call",
391
+ "S9: update adds, edits, removes fields, and normalizes read-shaped add fields",
392
392
  (ctx) => {
393
393
  if (dfAccessDenied) return ctx.skip();
394
394
  const name = `${scratchName}S9`;
@@ -397,7 +397,7 @@ describe("df entities — entities lifecycle", () => {
397
397
  "create",
398
398
  name,
399
399
  "--body",
400
- '{"fields":[{"fieldName":"oldColumn","type":"STRING"}]}',
400
+ '{"fields":[{"name":"oldColumn","type":"STRING"},{"name":"sourceNote","type":"STRING","lengthLimit":512}]}',
401
401
  ]);
402
402
  const id: string = created.Data.Id;
403
403
  try {
@@ -407,11 +407,11 @@ describe("df entities — entities lifecycle", () => {
407
407
  );
408
408
  if (!oldField) throw new Error("scratch missing 'oldColumn'");
409
409
  const body = JSON.stringify({
410
- addFields: [{ fieldName: "status", type: "STRING" }],
410
+ addFields: [{ name: "status", type: "STRING" }],
411
411
  updateFields: [
412
412
  { id: oldField.Id, displayName: "Old Column" },
413
413
  ],
414
- removeFields: [{ fieldName: "oldColumn" }],
414
+ removeFields: [{ name: "oldColumn" }],
415
415
  });
416
416
  const updated = cli([
417
417
  "entities",
@@ -428,6 +428,34 @@ describe("df entities — entities lifecycle", () => {
428
428
  expect(updated.Data.Id).toBe(id);
429
429
  expect(updated.Data.RemovedFields).toContain("oldColumn");
430
430
  expect(updated.Data.Reason).toBe("S9 composition test");
431
+
432
+ const sourceNoteField = (schema.Data.Fields as Json[]).find(
433
+ (field) => field.Name === "sourceNote",
434
+ );
435
+ if (!sourceNoteField)
436
+ throw new Error("scratch missing 'sourceNote'");
437
+ const readShapeAddField = {
438
+ ...sourceNoteField,
439
+ Name: "note",
440
+ DisplayName: "Note",
441
+ };
442
+
443
+ const readShapeUpdated = cli([
444
+ "entities",
445
+ "update",
446
+ id,
447
+ "--body",
448
+ JSON.stringify({ addFields: [readShapeAddField] }),
449
+ ]);
450
+ expect(readShapeUpdated.Result).toBe("Success");
451
+ expect(readShapeUpdated.Code).toBe("EntityUpdated");
452
+
453
+ const afterReadShape = cli(["entities", "get", id]);
454
+ const noteField = (afterReadShape.Data.Fields as Json[]).find(
455
+ (field) => field.Name === "note",
456
+ );
457
+ expect(noteField?.FieldDataType?.Name).toBe("STRING");
458
+ expect(noteField?.FieldDataType?.LengthLimit).toBe(512);
431
459
  } finally {
432
460
  runDf([
433
461
  "entities",
@@ -452,7 +480,7 @@ describe("df entities — entities lifecycle", () => {
452
480
  message: string;
453
481
  }> = [
454
482
  {
455
- label: "addFields missing fieldName",
483
+ label: "addFields missing name",
456
484
  argv: [
457
485
  "entities",
458
486
  "update",
@@ -461,7 +489,7 @@ describe("df entities — entities lifecycle", () => {
461
489
  '{"addFields":[{"type":"STRING"}]}',
462
490
  ],
463
491
  message:
464
- "Each field in addFields must include a non-empty 'fieldName' string",
492
+ "Each field in addFields must include a non-empty 'name' string",
465
493
  },
466
494
  {
467
495
  label: "updateFields missing id",
@@ -476,13 +504,13 @@ describe("df entities — entities lifecycle", () => {
476
504
  "Each field in updateFields must include a non-empty 'id' string",
477
505
  },
478
506
  {
479
- label: "duplicate fieldName in addFields",
507
+ label: "duplicate name in addFields",
480
508
  argv: [
481
509
  "entities",
482
510
  "update",
483
511
  "pre-network",
484
512
  "--body",
485
- '{"addFields":[{"fieldName":"duplicate","type":"STRING"},{"fieldName":"DUPLICATE","type":"STRING"}]}',
513
+ '{"addFields":[{"name":"duplicate","type":"STRING"},{"name":"DUPLICATE","type":"STRING"}]}',
486
514
  ],
487
515
  message:
488
516
  "Duplicate field name 'DUPLICATE' (case-insensitive)",
@@ -494,7 +522,7 @@ describe("df entities — entities lifecycle", () => {
494
522
  "update",
495
523
  "pre-network",
496
524
  "--body",
497
- '{"addFields":[{"fieldName":"col","type":"STRING"}],"removeFields":[{"fieldName":"col"}]}',
525
+ '{"addFields":[{"name":"col","type":"STRING"}],"removeFields":[{"name":"col"}]}',
498
526
  "--yes",
499
527
  "--reason",
500
528
  "x",
@@ -502,12 +530,57 @@ describe("df entities — entities lifecycle", () => {
502
530
  message:
503
531
  "Field 'col' appears in both addFields and removeFields",
504
532
  },
533
+ {
534
+ label: "name is immutable",
535
+ argv: [
536
+ "entities",
537
+ "update",
538
+ "pre-network",
539
+ "--body",
540
+ '{"name":"Renamed","displayName":"Renamed"}',
541
+ ],
542
+ message: "Entity name cannot be changed after creation",
543
+ },
544
+ {
545
+ label: "metadata update without displayName",
546
+ argv: [
547
+ "entities",
548
+ "update",
549
+ "pre-network",
550
+ "--body",
551
+ '{"description":"New description"}',
552
+ ],
553
+ message:
554
+ "'displayName' is required when updating entity metadata",
555
+ },
505
556
  ];
506
557
 
507
558
  for (const row of rows) {
508
559
  const parsed = expectFailure(runDf(row.argv), row.label);
509
560
  expect(parsed.Message, row.label).toBe(row.message);
561
+ expect(parsed.ErrorCode, row.label).toBe("invalid_argument");
510
562
  }
563
+
564
+ const aggregate = expectFailure(
565
+ runDf([
566
+ "entities",
567
+ "update",
568
+ "pre-network",
569
+ "--body",
570
+ '{"addFields":[{"type":"STRING"}],"removeFields":["code"]}',
571
+ "--yes",
572
+ "--reason",
573
+ "temporary validation",
574
+ ]),
575
+ "aggregate addFields and removeFields errors",
576
+ );
577
+ expect(aggregate.Message).toContain(
578
+ "Each field in addFields must include a non-empty 'name' string",
579
+ );
580
+ expect(aggregate.Message).toContain(
581
+ "Each field in removeFields must include a non-empty 'name' string",
582
+ );
583
+ expect(aggregate.ErrorCode).toBe("invalid_argument");
511
584
  },
512
585
  EXEC_TIMEOUT,
513
586
  );
@@ -516,7 +589,7 @@ describe("df entities — entities lifecycle", () => {
516
589
  it(
517
590
  "S11: update refuses removeFields without --yes and --reason",
518
591
  () => {
519
- const body = '{"removeFields":[{"fieldName":"oldColumn"}]}';
592
+ const body = '{"removeFields":[{"name":"oldColumn"}]}';
520
593
 
521
594
  const noFlags = expectFailure(
522
595
  runDf(["entities", "update", "pre-network", "--body", body]),
@@ -538,6 +611,7 @@ describe("df entities — entities lifecycle", () => {
538
611
  expect(yesNoReason.Message).toBe(
539
612
  "Reason required for destructive operation",
540
613
  );
614
+ expect(yesNoReason.ErrorCode).toBe("invalid_argument");
541
615
 
542
616
  const reasonNoYes = expectFailure(
543
617
  runDf([
@@ -573,6 +647,7 @@ describe("df entities — entities lifecycle", () => {
573
647
  expect(yesNoReason.Message).toBe(
574
648
  "Reason required for destructive operation",
575
649
  );
650
+ expect(yesNoReason.ErrorCode).toBe("invalid_argument");
576
651
 
577
652
  const reasonNoYes = expectFailure(
578
653
  runDf(["entities", "delete", "pre-network", "--reason", "x"]),
@@ -594,7 +669,7 @@ describe("df entities — entities lifecycle", () => {
594
669
  "create",
595
670
  name,
596
671
  "--body",
597
- '{"fields":[{"fieldName":"note","type":"STRING"}]}',
672
+ '{"fields":[{"name":"note","type":"STRING"}]}',
598
673
  ]);
599
674
  const id: string = created.Data.Id;
600
675
  const deleted = cli([
@@ -152,7 +152,7 @@ describe("df files — file attachments management", () => {
152
152
  "create",
153
153
  scratchEntityName,
154
154
  "--body",
155
- `{"fields":[{"fieldName":"note","type":"STRING"},{"fieldName":"${FILE_FIELD}","type":"FILE"}]}`,
155
+ `{"fields":[{"name":"note","type":"STRING"},{"name":"${FILE_FIELD}","type":"FILE"}]}`,
156
156
  ]);
157
157
  if (isAuthDenial(createEntity)) {
158
158
  dfAccessDenied = true;
@@ -191,7 +191,7 @@ describe("df files — file attachments management", () => {
191
191
  "--folder-key",
192
192
  scratchFolderKey,
193
193
  "--body",
194
- `{"fields":[{"fieldName":"note","type":"STRING"},{"fieldName":"${FILE_FIELD}","type":"FILE"}]}`,
194
+ `{"fields":[{"name":"note","type":"STRING"},{"name":"${FILE_FIELD}","type":"FILE"}]}`,
195
195
  ]);
196
196
  if (createFolderEntity.exitCode !== 0) return;
197
197
  folderScopedEntityId = (extractJson(createFolderEntity.stdout) as Json)
@@ -156,7 +156,7 @@ describe("df records — records management", () => {
156
156
  "create",
157
157
  scratchEntityName,
158
158
  "--body",
159
- '{"fields":[{"fieldName":"note","type":"STRING"},{"fieldName":"amount","type":"DECIMAL","decimalPrecision":2},{"fieldName":"status","type":"STRING"}]}',
159
+ '{"fields":[{"name":"note","type":"STRING"},{"name":"amount","type":"DECIMAL","decimalPrecision":2},{"name":"status","type":"STRING"}]}',
160
160
  ]);
161
161
  if (isAuthDenial(createEntity)) {
162
162
  dfAccessDenied = true;