@uipath/data-fabric-tool 1.196.0 → 1.197.0-preview.59

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.
@@ -518,6 +518,48 @@ describe("entities create", () => {
518
518
  );
519
519
  });
520
520
 
521
+ it("should preserve per-field referenceFolderKey on a cross-folder RELATIONSHIP", async () => {
522
+ const sdk = mockSdk();
523
+ vi.mocked(sdk.entities.create).mockResolvedValue("entity-xfolder-rel");
524
+ const fields = [
525
+ {
526
+ fieldName: "order",
527
+ type: "RELATIONSHIP",
528
+ referenceEntityId: "a1b2c3d4-0000-0000-0000-000000000010",
529
+ referenceFieldId: "f1000000-0000-0000-0000-000000000100",
530
+ referenceFolderKey: "f1000000-0000-0000-0000-000000000060",
531
+ },
532
+ ];
533
+ vi.mocked(readJsonInput).mockResolvedValue({ fields });
534
+
535
+ const program = buildProgram();
536
+ await program.parseAsync([
537
+ "node",
538
+ "test",
539
+ "entities",
540
+ "create",
541
+ "OrderLine",
542
+ "--body",
543
+ JSON.stringify({ fields }),
544
+ "--folder-key",
545
+ "f1000000-0000-0000-0000-000000000050",
546
+ ]);
547
+
548
+ expect(sdk.entities.create).toHaveBeenCalledWith(
549
+ "OrderLine",
550
+ expect.arrayContaining([
551
+ expect.objectContaining({
552
+ fieldName: "order",
553
+ type: "RELATIONSHIP",
554
+ referenceFolderKey: "f1000000-0000-0000-0000-000000000060",
555
+ }),
556
+ ]),
557
+ expect.objectContaining({
558
+ folderKey: "f1000000-0000-0000-0000-000000000050",
559
+ }),
560
+ );
561
+ });
562
+
521
563
  it("should error when no --body or --file provided", async () => {
522
564
  vi.mocked(readJsonInput).mockRejectedValue(
523
565
  new Error("Provide entity definition via --file or --body."),
@@ -763,6 +805,43 @@ describe("entities update", () => {
763
805
  );
764
806
  });
765
807
 
808
+ it("should preserve per-field referenceFolderKey when addFields includes a cross-folder RELATIONSHIP", async () => {
809
+ const sdk = mockSdk();
810
+ const addFields = [
811
+ {
812
+ fieldName: "order",
813
+ type: "RELATIONSHIP",
814
+ referenceEntityId: "a1b2c3d4-0000-0000-0000-000000000010",
815
+ referenceFieldId: "f1000000-0000-0000-0000-000000000100",
816
+ referenceFolderKey: "f1000000-0000-0000-0000-000000000060",
817
+ },
818
+ ];
819
+ vi.mocked(readJsonInput).mockResolvedValue({ addFields });
820
+
821
+ const program = buildProgram();
822
+ await program.parseAsync([
823
+ "node",
824
+ "test",
825
+ "entities",
826
+ "update",
827
+ "entity-id",
828
+ "--body",
829
+ JSON.stringify({ addFields }),
830
+ ]);
831
+
832
+ expect(sdk.entities.updateById).toHaveBeenCalledWith(
833
+ "entity-id",
834
+ expect.objectContaining({
835
+ addFields: expect.arrayContaining([
836
+ expect.objectContaining({
837
+ referenceFolderKey:
838
+ "f1000000-0000-0000-0000-000000000060",
839
+ }),
840
+ ]),
841
+ }),
842
+ );
843
+ });
844
+
766
845
  it("should update entity by adding a CHOICE_SET_MULTIPLE field with choiceSetId", async () => {
767
846
  const sdk = mockSdk();
768
847
  const addFields = [
@@ -1772,6 +1851,7 @@ describe("entities delete", () => {
1772
1851
 
1773
1852
  expect(sdk.entities.deleteById).toHaveBeenCalledWith(
1774
1853
  "entity-to-delete",
1854
+ undefined,
1775
1855
  );
1776
1856
  expect(OutputFormatter.success).toHaveBeenCalledWith(
1777
1857
  expect.objectContaining({
@@ -1819,7 +1899,10 @@ describe("entities delete", () => {
1819
1899
  "cleanup",
1820
1900
  ]);
1821
1901
 
1822
- expect(sdk.entities.deleteById).toHaveBeenCalledWith("entity-id");
1902
+ expect(sdk.entities.deleteById).toHaveBeenCalledWith(
1903
+ "entity-id",
1904
+ undefined,
1905
+ );
1823
1906
  expect(OutputFormatter.success).toHaveBeenCalledWith(
1824
1907
  expect.objectContaining({ Result: "Success" }),
1825
1908
  );
@@ -1920,3 +2003,171 @@ describe("entities delete", () => {
1920
2003
  expect(process.exitCode).toBe(1);
1921
2004
  });
1922
2005
  });
2006
+
2007
+ describe("entities --folder-key forwarding", () => {
2008
+ beforeEach(() => {
2009
+ vi.resetAllMocks();
2010
+ process.exitCode = undefined;
2011
+ });
2012
+
2013
+ it("should forward --folder-key to getById", async () => {
2014
+ const sdk = mockSdk();
2015
+ vi.mocked(sdk.entities.getById).mockResolvedValue({
2016
+ id: "ent-1",
2017
+ fields: [],
2018
+ } as never);
2019
+
2020
+ const program = buildProgram();
2021
+ await program.parseAsync([
2022
+ "node",
2023
+ "test",
2024
+ "entities",
2025
+ "get",
2026
+ "ent-1",
2027
+ "--folder-key",
2028
+ "folder-guid-1",
2029
+ ]);
2030
+
2031
+ expect(sdk.entities.getById).toHaveBeenCalledWith("ent-1", {
2032
+ folderKey: "folder-guid-1",
2033
+ });
2034
+ });
2035
+
2036
+ it("should forward --folder-key into create options", async () => {
2037
+ const sdk = mockSdk();
2038
+ vi.mocked(sdk.entities.create).mockResolvedValue("new-entity-id");
2039
+ vi.mocked(readJsonInput).mockResolvedValue({
2040
+ fields: [{ fieldName: "title", type: "STRING" }],
2041
+ });
2042
+
2043
+ const program = buildProgram();
2044
+ await program.parseAsync([
2045
+ "node",
2046
+ "test",
2047
+ "entities",
2048
+ "create",
2049
+ "MyEntity",
2050
+ "--body",
2051
+ '{"fields":[{"fieldName":"title","type":"STRING"}]}',
2052
+ "--folder-key",
2053
+ "folder-guid-2",
2054
+ ]);
2055
+
2056
+ expect(sdk.entities.create).toHaveBeenCalledWith(
2057
+ "MyEntity",
2058
+ [{ fieldName: "title", type: "STRING" }],
2059
+ expect.objectContaining({ folderKey: "folder-guid-2" }),
2060
+ );
2061
+ });
2062
+
2063
+ it("should forward --folder-key into updateById options", async () => {
2064
+ const sdk = mockSdk();
2065
+ vi.mocked(readJsonInput).mockResolvedValue({
2066
+ displayName: "Renamed",
2067
+ });
2068
+
2069
+ const program = buildProgram();
2070
+ await program.parseAsync([
2071
+ "node",
2072
+ "test",
2073
+ "entities",
2074
+ "update",
2075
+ "ent-1",
2076
+ "--body",
2077
+ '{"displayName":"Renamed"}',
2078
+ "--folder-key",
2079
+ "folder-guid-3",
2080
+ ]);
2081
+
2082
+ expect(sdk.entities.updateById).toHaveBeenCalledWith(
2083
+ "ent-1",
2084
+ expect.objectContaining({
2085
+ displayName: "Renamed",
2086
+ folderKey: "folder-guid-3",
2087
+ }),
2088
+ );
2089
+ });
2090
+
2091
+ it("should forward --folder-key to deleteById", async () => {
2092
+ const sdk = mockSdk();
2093
+
2094
+ const program = buildProgram();
2095
+ await program.parseAsync([
2096
+ "node",
2097
+ "test",
2098
+ "entities",
2099
+ "delete",
2100
+ "ent-1",
2101
+ "--confirm",
2102
+ "--reason",
2103
+ "cleanup",
2104
+ "--folder-key",
2105
+ "folder-guid-4",
2106
+ ]);
2107
+
2108
+ expect(sdk.entities.deleteById).toHaveBeenCalledWith("ent-1", {
2109
+ folderKey: "folder-guid-4",
2110
+ });
2111
+ });
2112
+ });
2113
+
2114
+ describe("entities list --include-folders", () => {
2115
+ beforeEach(() => {
2116
+ vi.resetAllMocks();
2117
+ process.exitCode = undefined;
2118
+ });
2119
+
2120
+ it("should call getAll with no options when neither --folder-key nor --include-folders is passed", async () => {
2121
+ const sdk = mockSdk();
2122
+ const program = buildProgram();
2123
+ await program.parseAsync(["node", "test", "entities", "list"]);
2124
+ expect(sdk.entities.getAll).toHaveBeenCalledWith(undefined);
2125
+ });
2126
+
2127
+ it("should forward --include-folders as includeFolderEntities: true", async () => {
2128
+ const sdk = mockSdk();
2129
+ const program = buildProgram();
2130
+ await program.parseAsync([
2131
+ "node",
2132
+ "test",
2133
+ "entities",
2134
+ "list",
2135
+ "--include-folders",
2136
+ ]);
2137
+ expect(sdk.entities.getAll).toHaveBeenCalledWith({
2138
+ includeFolderEntities: true,
2139
+ });
2140
+ });
2141
+
2142
+ it("should forward --folder-key as folderKey to getAll", async () => {
2143
+ const sdk = mockSdk();
2144
+ const program = buildProgram();
2145
+ await program.parseAsync([
2146
+ "node",
2147
+ "test",
2148
+ "entities",
2149
+ "list",
2150
+ "--folder-key",
2151
+ "folder-guid-1",
2152
+ ]);
2153
+ expect(sdk.entities.getAll).toHaveBeenCalledWith({
2154
+ folderKey: "folder-guid-1",
2155
+ });
2156
+ });
2157
+
2158
+ it("should reject --folder-key combined with --include-folders", async () => {
2159
+ const sdk = mockSdk();
2160
+ const program = buildProgram();
2161
+ await program.parseAsync([
2162
+ "node",
2163
+ "test",
2164
+ "entities",
2165
+ "list",
2166
+ "--folder-key",
2167
+ "folder-guid-1",
2168
+ "--include-folders",
2169
+ ]);
2170
+ expect(sdk.entities.getAll).not.toHaveBeenCalled();
2171
+ expect(process.exitCode).toBe(1);
2172
+ });
2173
+ });
@@ -9,6 +9,7 @@ import {
9
9
  } from "@uipath/common";
10
10
  import type {
11
11
  EntityCreateFieldOptions,
12
+ EntityGetAllOptions,
12
13
  EntityServiceModel,
13
14
  EntityUpdateByIdOptions,
14
15
  ExternalSourceFields,
@@ -23,16 +24,20 @@ import { connectOrFail } from "../utils/sdk-client";
23
24
  interface ListOptions {
24
25
  tenant?: string;
25
26
  nativeOnly?: boolean;
27
+ folderKey?: string;
28
+ includeFolders?: boolean;
26
29
  }
27
30
 
28
31
  interface GetOptions {
29
32
  tenant?: string;
33
+ folderKey?: string;
30
34
  }
31
35
 
32
36
  interface CreateOptions {
33
37
  tenant?: string;
34
38
  file?: string;
35
39
  body?: string;
40
+ folderKey?: string;
36
41
  }
37
42
 
38
43
  interface UpdateEntityOptions {
@@ -42,6 +47,7 @@ interface UpdateEntityOptions {
42
47
  yes?: boolean;
43
48
  confirm?: boolean;
44
49
  reason?: string;
50
+ folderKey?: string;
45
51
  }
46
52
 
47
53
  interface DeleteOptions {
@@ -49,11 +55,14 @@ interface DeleteOptions {
49
55
  yes?: boolean;
50
56
  confirm?: boolean;
51
57
  reason?: string;
58
+ folderKey?: string;
52
59
  }
53
60
 
54
61
  const ENTITIES_LIST_EXAMPLES: CommandExample[] = [
55
62
  {
56
- Description: "List Data Fabric entities.",
63
+ Description:
64
+ "List Data Fabric entities. Each entity includes the 'folderId' it lives in — pass that as '--folder-key' on follow-up commands targeting folder-scoped entities. " +
65
+ "Scope modes: omit both flags to see only tenant-level entities (the default); pass '--folder-key <uuid>' to see only that folder's entities; pass '--include-folders' to see tenant + folder entities together. '--folder-key' and '--include-folders' are mutually exclusive.",
57
66
  Command: "uip df entities list --native-only",
58
67
  Output: {
59
68
  Code: "EntityList",
@@ -64,6 +73,7 @@ const ENTITIES_LIST_EXAMPLES: CommandExample[] = [
64
73
  displayName: "Invoice",
65
74
  entityType: "Standard",
66
75
  description: "Invoice records",
76
+ folderId: "f1000000-0000-0000-0000-000000000001",
67
77
  isRbacEnabled: false,
68
78
  fields: [
69
79
  {
@@ -146,6 +156,19 @@ const ENTITIES_CREATE_EXAMPLES: CommandExample[] = [
146
156
  Data: { ID: "a1b2c3d4-0000-0000-0000-000000000004" },
147
157
  },
148
158
  },
159
+ {
160
+ Description:
161
+ "Create a folder-scoped entity with cross-folder references. " +
162
+ "Pass '--folder-key' to place the new entity in a folder. " +
163
+ "Per-field 'referenceFolderKey' points a RELATIONSHIP, FILE, or CHOICE_SET_* field at a target that lives in a different folder (or at the tenant level when omitted). " +
164
+ "Get target entity/field IDs from 'df entities list --folder-key <key>' and 'df entities get <id> --folder-key <key>'; get choice-set IDs from 'df choice-sets list --folder-key <key>' (omit '--folder-key' for tenant-level choice sets).",
165
+ Command:
166
+ 'uip df entities create OrderLine --folder-key f1000000-0000-0000-0000-000000000050 --body \'{"displayName":"Order Line","fields":[{"fieldName":"order","type":"RELATIONSHIP","referenceEntityId":"a1b2c3d4-0000-0000-0000-000000000010","referenceFieldId":"f1000000-0000-0000-0000-000000000100","referenceFolderKey":"f1000000-0000-0000-0000-000000000060","isRequired":true},{"fieldName":"userType","type":"CHOICE_SET_SINGLE","choiceSetId":"c1d2e3f4-0000-0000-0000-000000000077"}]}\'',
167
+ Output: {
168
+ Code: "EntityCreated",
169
+ Data: { ID: "a1b2c3d4-0000-0000-0000-000000000005" },
170
+ },
171
+ },
149
172
  ];
150
173
 
151
174
  const VALID_FIELD_TYPES = new Set(Object.values(EntityFieldDataType));
@@ -195,12 +218,43 @@ export const registerEntitiesCommand = (program: Command) => {
195
218
  "--native-only",
196
219
  "Show only native entities (exclude federated entities with external connections)",
197
220
  )
221
+ .option(
222
+ "--folder-key <key>",
223
+ "Folder key (GUID) to scope the listing to a specific folder",
224
+ )
225
+ .option(
226
+ "--include-folders",
227
+ "List tenant-level entities together with entities from every folder you can see. Mutually exclusive with --folder-key.",
228
+ )
198
229
  .examples(ENTITIES_LIST_EXAMPLES)
199
230
  .trackedAction(processContext, async (options: ListOptions) => {
231
+ if (
232
+ options.folderKey !== undefined &&
233
+ options.includeFolders === true
234
+ ) {
235
+ return fail(
236
+ "--folder-key and --include-folders are mutually exclusive",
237
+ "Use --folder-key to list a single folder, or --include-folders to list tenant + folder entities together.",
238
+ );
239
+ }
240
+
200
241
  const sdk = await connectOrFail(options.tenant);
201
242
  if (!sdk) return;
202
243
 
203
- const [listError, result] = await catchError(sdk.entities.getAll());
244
+ const listOpts: EntityGetAllOptions = {
245
+ ...(options.folderKey !== undefined && {
246
+ folderKey: options.folderKey,
247
+ }),
248
+ ...(options.includeFolders === true && {
249
+ includeFolderEntities: true,
250
+ }),
251
+ };
252
+
253
+ const [listError, result] = await catchError(
254
+ sdk.entities.getAll(
255
+ Object.keys(listOpts).length > 0 ? listOpts : undefined,
256
+ ),
257
+ );
204
258
 
205
259
  if (listError) {
206
260
  return fail(
@@ -231,6 +285,10 @@ export const registerEntitiesCommand = (program: Command) => {
231
285
  .addOption(
232
286
  createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>"),
233
287
  )
288
+ .option(
289
+ "--folder-key <key>",
290
+ "Folder key (GUID) of the folder containing the entity (for folder-scoped entities)",
291
+ )
234
292
  .examples(ENTITIES_GET_EXAMPLES)
235
293
  .trackedAction(
236
294
  processContext,
@@ -239,7 +297,12 @@ export const registerEntitiesCommand = (program: Command) => {
239
297
  if (!sdk) return;
240
298
 
241
299
  const [getError, entity] = await catchError(
242
- sdk.entities.getById(id),
300
+ sdk.entities.getById(
301
+ id,
302
+ options.folderKey !== undefined
303
+ ? { folderKey: options.folderKey }
304
+ : undefined,
305
+ ),
243
306
  );
244
307
 
245
308
  if (getError) {
@@ -280,9 +343,10 @@ export const registerEntitiesCommand = (program: Command) => {
280
343
  "-f, --file <path>",
281
344
  "Path to JSON file with entity definition (fields array required; displayName, description, isRbacEnabled optional)",
282
345
  )
346
+ .option("--body <json>", "Inline JSON entity definition")
283
347
  .option(
284
- "--body <json>",
285
- "Inline JSON entity definition (use `-` to read from stdin)",
348
+ "--folder-key <key>",
349
+ "Folder key (GUID) of the target folder (for folder-scoped entities)",
286
350
  )
287
351
  .examples(ENTITIES_CREATE_EXAMPLES)
288
352
  .trackedAction(
@@ -356,6 +420,9 @@ export const registerEntitiesCommand = (program: Command) => {
356
420
  ...(definition.isRbacEnabled !== undefined && {
357
421
  isRbacEnabled: definition.isRbacEnabled as boolean,
358
422
  }),
423
+ ...(options.folderKey !== undefined && {
424
+ folderKey: options.folderKey,
425
+ }),
359
426
  };
360
427
 
361
428
  const entityService: EntityServiceModel = sdk.entities;
@@ -410,6 +477,10 @@ export const registerEntitiesCommand = (program: Command) => {
410
477
  "--reason <reason>",
411
478
  "Required when 'removeFields' is non-empty — echoed back in the response so the caller can log it",
412
479
  )
480
+ .option(
481
+ "--folder-key <key>",
482
+ "Folder key (GUID) of the folder containing the entity (for folder-scoped entities)",
483
+ )
413
484
  .trackedAction(
414
485
  processContext,
415
486
  async (id: string, options: UpdateEntityOptions) => {
@@ -573,8 +644,14 @@ export const registerEntitiesCommand = (program: Command) => {
573
644
  if (!sdk) return;
574
645
 
575
646
  const entityService: EntityServiceModel = sdk.entities;
647
+ const updatePayload: EntityUpdateByIdOptions = {
648
+ ...pickKnownUpdateKeys(input),
649
+ ...(options.folderKey !== undefined && {
650
+ folderKey: options.folderKey,
651
+ }),
652
+ };
576
653
  const [updateError] = await catchError(
577
- entityService.updateById(id, pickKnownUpdateKeys(input)),
654
+ entityService.updateById(id, updatePayload),
578
655
  );
579
656
 
580
657
  if (updateError) {
@@ -613,6 +690,10 @@ export const registerEntitiesCommand = (program: Command) => {
613
690
  "--reason <reason>",
614
691
  "Reason for the deletion — echoed back in the response so the caller can log it",
615
692
  )
693
+ .option(
694
+ "--folder-key <key>",
695
+ "Folder key (GUID) of the folder containing the entity (for folder-scoped entities)",
696
+ )
616
697
  .examples(ENTITIES_DELETE_EXAMPLES)
617
698
  .trackedAction(
618
699
  processContext,
@@ -629,7 +710,12 @@ export const registerEntitiesCommand = (program: Command) => {
629
710
 
630
711
  const entityService: EntityServiceModel = sdk.entities;
631
712
  const [deleteError] = await catchError(
632
- entityService.deleteById(id),
713
+ entityService.deleteById(
714
+ id,
715
+ options.folderKey !== undefined
716
+ ? { folderKey: options.folderKey }
717
+ : undefined,
718
+ ),
633
719
  );
634
720
 
635
721
  if (deleteError) {
@@ -109,6 +109,7 @@ describe("files upload", () => {
109
109
  "record-1",
110
110
  "attachment",
111
111
  expect.any(File),
112
+ undefined,
112
113
  );
113
114
  expect(OutputFormatter.success).toHaveBeenCalledWith(
114
115
  expect.objectContaining({
@@ -132,6 +133,7 @@ describe("files upload", () => {
132
133
  "record-1",
133
134
  "attachment",
134
135
  expect.objectContaining({ name: "upload" }),
136
+ undefined,
135
137
  );
136
138
  });
137
139
 
@@ -245,6 +247,7 @@ describe("files delete", () => {
245
247
  "entity-1",
246
248
  "record-1",
247
249
  "attachment",
250
+ undefined,
248
251
  );
249
252
  expect(OutputFormatter.success).toHaveBeenCalledWith(
250
253
  expect.objectContaining({
@@ -266,6 +269,7 @@ describe("files delete", () => {
266
269
  "entity-1",
267
270
  "record-1",
268
271
  "attachment",
272
+ undefined,
269
273
  );
270
274
  expect(OutputFormatter.success).toHaveBeenCalledWith(
271
275
  expect.objectContaining({ Result: "Success", Code: "FileDeleted" }),
@@ -370,3 +374,62 @@ describe("files download edge cases", () => {
370
374
  );
371
375
  });
372
376
  });
377
+
378
+ describe("files --folder-key forwarding", () => {
379
+ beforeEach(() => {
380
+ vi.clearAllMocks();
381
+ vi.mocked(OutputFormatter.success).mockReset();
382
+ vi.mocked(OutputFormatter.error).mockReset();
383
+ });
384
+
385
+ it("should forward --folder-key to uploadAttachment", async () => {
386
+ const sdk = mockSdk();
387
+ mockFs.readFile.mockResolvedValue(new Uint8Array([1, 2, 3]));
388
+ const program = buildProgram();
389
+ await runCommand(
390
+ program,
391
+ "files upload entity-1 record-1 attachment --file /tmp/report.pdf --folder-key folder-guid-1",
392
+ );
393
+ expect(sdk.entities.uploadAttachment).toHaveBeenCalledWith(
394
+ "entity-1",
395
+ "record-1",
396
+ "attachment",
397
+ expect.any(File),
398
+ { folderKey: "folder-guid-1" },
399
+ );
400
+ });
401
+
402
+ it("should forward --folder-key to downloadAttachment", async () => {
403
+ const blob = new Blob(["data"]);
404
+ const sdk = mockSdk({
405
+ downloadAttachment: vi.fn().mockResolvedValue(blob),
406
+ });
407
+ mockFs.writeFile.mockResolvedValue(undefined);
408
+ const program = buildProgram();
409
+ await runCommand(
410
+ program,
411
+ "files download entity-1 record-1 attachment --folder-key folder-guid-2",
412
+ );
413
+ expect(sdk.entities.downloadAttachment).toHaveBeenCalledWith(
414
+ "entity-1",
415
+ "record-1",
416
+ "attachment",
417
+ { folderKey: "folder-guid-2" },
418
+ );
419
+ });
420
+
421
+ it("should forward --folder-key to deleteAttachment", async () => {
422
+ const sdk = mockSdk();
423
+ const program = buildProgram();
424
+ await runCommand(
425
+ program,
426
+ "files delete entity-1 record-1 attachment --yes --reason cleanup --folder-key folder-guid-3",
427
+ );
428
+ expect(sdk.entities.deleteAttachment).toHaveBeenCalledWith(
429
+ "entity-1",
430
+ "record-1",
431
+ "attachment",
432
+ { folderKey: "folder-guid-3" },
433
+ );
434
+ });
435
+ });
@@ -16,11 +16,13 @@ import { connectOrFail } from "../utils/sdk-client";
16
16
  interface UploadOptions {
17
17
  tenant?: string;
18
18
  file?: string;
19
+ folderKey?: string;
19
20
  }
20
21
 
21
22
  interface DownloadOptions {
22
23
  tenant?: string;
23
24
  destination?: string;
25
+ folderKey?: string;
24
26
  }
25
27
 
26
28
  interface DeleteOptions {
@@ -28,6 +30,7 @@ interface DeleteOptions {
28
30
  yes?: boolean;
29
31
  confirm?: boolean;
30
32
  reason?: string;
33
+ folderKey?: string;
31
34
  }
32
35
 
33
36
  const FILES_UPLOAD_EXAMPLES: CommandExample[] = [
@@ -95,6 +98,10 @@ export const registerFilesCommand = (program: Command) => {
95
98
  createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>"),
96
99
  )
97
100
  .option("-f, --file <path>", "Path to the file to upload")
101
+ .option(
102
+ "--folder-key <key>",
103
+ "Folder key (GUID) of the folder containing the entity (for folder-scoped entities)",
104
+ )
98
105
  .examples(FILES_UPLOAD_EXAMPLES)
99
106
  .trackedAction(
100
107
  processContext,
@@ -134,6 +141,9 @@ export const registerFilesCommand = (program: Command) => {
134
141
  [fileContent as Uint8Array<ArrayBuffer>],
135
142
  fileName,
136
143
  ),
144
+ options.folderKey !== undefined
145
+ ? { folderKey: options.folderKey }
146
+ : undefined,
137
147
  ),
138
148
  );
139
149
 
@@ -170,6 +180,10 @@ export const registerFilesCommand = (program: Command) => {
170
180
  "--destination <path>",
171
181
  "Output file path (defaults to <record-id>_<field-name>.bin)",
172
182
  )
183
+ .option(
184
+ "--folder-key <key>",
185
+ "Folder key (GUID) of the folder containing the entity (for folder-scoped entities)",
186
+ )
173
187
  .examples(FILES_DOWNLOAD_EXAMPLES)
174
188
  .trackedAction(
175
189
  processContext,
@@ -187,6 +201,9 @@ export const registerFilesCommand = (program: Command) => {
187
201
  entityId,
188
202
  recordId,
189
203
  fieldName,
204
+ options.folderKey !== undefined
205
+ ? { folderKey: options.folderKey }
206
+ : undefined,
190
207
  ),
191
208
  );
192
209
 
@@ -252,6 +269,10 @@ export const registerFilesCommand = (program: Command) => {
252
269
  "--reason <reason>",
253
270
  "Reason for the deletion — echoed back in the response so the caller can log it",
254
271
  )
272
+ .option(
273
+ "--folder-key <key>",
274
+ "Folder key (GUID) of the folder containing the entity (for folder-scoped entities)",
275
+ )
255
276
  .examples(FILES_DELETE_EXAMPLES)
256
277
  .trackedAction(
257
278
  processContext,
@@ -276,6 +297,9 @@ export const registerFilesCommand = (program: Command) => {
276
297
  entityId,
277
298
  recordId,
278
299
  fieldName,
300
+ options.folderKey !== undefined
301
+ ? { folderKey: options.folderKey }
302
+ : undefined,
279
303
  ),
280
304
  );
281
305