zinkee 0.1.24 → 0.1.26

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.
@@ -200,6 +200,25 @@ describe("getCommandExamples", () => {
200
200
  }
201
201
  });
202
202
 
203
+ it("does not teach legacy system columns in display widget examples", () => {
204
+ const legacyColumns = ["id", "createdat", "updatedat", "createdby", "updatedby"];
205
+ const commands = ["displays widgets create", "displays widgets update", "displays list", "displays get"];
206
+
207
+ for (const command of commands) {
208
+ for (const example of getCommandExamples(command)) {
209
+ for (const column of legacyColumns) {
210
+ expect(example.command).not.toContain(`--field ${column}`);
211
+ }
212
+
213
+ const examplePayloads = [example.raw, example.response].filter(Boolean);
214
+ for (const payload of examplePayloads) {
215
+ expect(payload).not.toMatch(/"fields"\s*:\s*\[[^\]]*"(id|createdat|updatedat|createdby|updatedby)"/);
216
+ expect(payload).not.toMatch(/"fieldCalc"\s*:\s*"(id|createdat|updatedat|createdby|updatedby)"/);
217
+ }
218
+ }
219
+ }
220
+ });
221
+
203
222
  it("covers REFERENCE, MEMBER and DATE variants in displays variables create", () => {
204
223
  const examples = getCommandExamples("displays variables create");
205
224
  const rawPayloads = examples.map((example) => example.raw ?? "");
@@ -211,14 +230,23 @@ describe("getCommandExamples", () => {
211
230
  expect(rawPayloads.some((raw) => raw.includes('"dynamicOption": "thisMonth"'))).toBe(true);
212
231
  });
213
232
 
214
- it("covers SCHEMA, WORKFLOW and DISPLAY variants in navigation resources move", () => {
233
+ it("documents navigation resources move as schema-only with no resourceType", () => {
215
234
  const examples = getCommandExamples("navigation resources move");
216
235
  const rawPayloads = examples.map((example) => example.raw ?? "");
217
236
 
218
- expect(examples.length).toBeGreaterThanOrEqual(5);
219
- for (const resourceType of ["SCHEMA", "WORKFLOW", "DISPLAY", "SCHEDULE"]) {
220
- expect(rawPayloads.some((raw) => raw.includes(`"resourceType": "${resourceType}"`))).toBe(true);
237
+ expect(examples.length).toBeGreaterThanOrEqual(2);
238
+ // Navigation only moves schemas now, so the payload no longer carries a
239
+ // resourceType and the example commands must not pass --type.
240
+ for (const raw of rawPayloads) {
241
+ expect(raw).not.toContain("resourceType");
242
+ }
243
+ for (const example of examples) {
244
+ expect(example.command).not.toContain("--type");
221
245
  }
246
+ // Covers moving into a folder and back to the root folder.
247
+ expect(
248
+ rawPayloads.some((raw) => raw.includes('"targetFolderId": "00000000-0000-0000-0000-000000000000"')),
249
+ ).toBe(true);
222
250
  });
223
251
 
224
252
  it("covers slug and UUID variants in teamspace resources publish", () => {
@@ -818,12 +818,12 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
818
818
  ]),
819
819
  "navigation resources move": buildCommandExamples([
820
820
  {
821
- description: "Move a schema into a navigation folder.",
821
+ description:
822
+ "Move a schema into a navigation folder. Only schemas can be moved; the navigation menu holds databases.",
822
823
  command:
823
- 'zinkee --json navigation resources move 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --type SCHEMA --to Sales',
824
+ 'zinkee --json navigation resources move 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --to Sales',
824
825
  raw: `{
825
826
  "resourceId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
826
- "resourceType": "SCHEMA",
827
827
  "targetFolderId": "84a0fca4-37ef-4c83-a8ed-9ef67ad9324a"
828
828
  }`,
829
829
  response: `{
@@ -832,43 +832,12 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
832
832
  }`,
833
833
  },
834
834
  {
835
- description: "Move a workflow.",
836
- command:
837
- 'zinkee --json navigation resources move 3f8a2c1b-9d4e-4a5b-8c6d-7e8f90123456 --type WORKFLOW --to Operations',
838
- raw: `{
839
- "resourceId": "3f8a2c1b-9d4e-4a5b-8c6d-7e8f90123456",
840
- "resourceType": "WORKFLOW",
841
- "targetFolderId": "b8c9d0e1-f2a3-4b5c-6d7e-8f9012345678"
842
- }`,
843
- },
844
- {
845
- description: "Move a display.",
846
- command:
847
- 'zinkee --json navigation resources move 0f6f062f-1478-4df2-96a1-c495d037d260 --type DISPLAY --to Operations',
848
- raw: `{
849
- "resourceId": "0f6f062f-1478-4df2-96a1-c495d037d260",
850
- "resourceType": "DISPLAY",
851
- "targetFolderId": "b8c9d0e1-f2a3-4b5c-6d7e-8f9012345678"
852
- }`,
853
- },
854
- {
855
- description: "Move a resource back to the root folder (root is always UUID 00000000-0000-0000-0000-000000000000).",
835
+ description: "Move a schema back to the root folder (root is always UUID 00000000-0000-0000-0000-000000000000).",
856
836
  command:
857
- 'zinkee --json navigation resources move 5223cbc8-8c6c-4694-93bc-dd176364df9b --type SCHEMA --to 00000000-0000-0000-0000-000000000000',
837
+ 'zinkee --json navigation resources move 5223cbc8-8c6c-4694-93bc-dd176364df9b --to 00000000-0000-0000-0000-000000000000',
858
838
  raw: `{
859
839
  "resourceId": "5223cbc8-8c6c-4694-93bc-dd176364df9b",
860
- "resourceType": "SCHEMA",
861
840
  "targetFolderId": "00000000-0000-0000-0000-000000000000"
862
- }`,
863
- },
864
- {
865
- description: "Move a schedule resource.",
866
- command:
867
- 'zinkee --json navigation resources move a1b2c3d4-e5f6-7890-1234-567890abcdef --type SCHEDULE --to Operations',
868
- raw: `{
869
- "resourceId": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
870
- "resourceType": "SCHEDULE",
871
- "targetFolderId": "b8c9d0e1-f2a3-4b5c-6d7e-8f9012345678"
872
841
  }`,
873
842
  },
874
843
  ]),
@@ -1314,7 +1283,7 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
1314
1283
  description:
1315
1284
  "Create a TABLE widget (CLI normalises --type table to TABLE_OR_SUBTABLE).",
1316
1285
  command:
1317
- `zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --type table --name Customers --origin-resource 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --layout '{"x":0,"y":0,"w":12,"h":8}' --field id --field contact-name --field status --sort '{"fieldId":"id","direction":"DESC"}'`,
1286
+ `zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --type table --name Customers --origin-resource 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --layout '{"x":0,"y":0,"w":12,"h":8}' --field contact-name --field status --field amount --sort '{"fieldId":"contact-name","direction":"ASC"}'`,
1318
1287
  raw: `{
1319
1288
  "type": "TABLE_OR_SUBTABLE",
1320
1289
  "source": {
@@ -1329,11 +1298,11 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
1329
1298
  },
1330
1299
  "query": {
1331
1300
  "sorts": [
1332
- { "fieldId": "id", "direction": "DESC" }
1301
+ { "fieldId": "contact-name", "direction": "ASC" }
1333
1302
  ]
1334
1303
  },
1335
1304
  "view": {
1336
- "fields": ["id", "contact-name", "status"]
1305
+ "fields": ["contact-name", "status", "amount"]
1337
1306
  }
1338
1307
  }`,
1339
1308
  response: `{
@@ -1418,7 +1387,7 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
1418
1387
  {
1419
1388
  description: "Create a bars CHART widget with a monthly time-serie x-axis and two y-axis series.",
1420
1389
  command:
1421
- `zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --type CHART --name "Revenue by month" --origin-resource 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --layout '{"x":0,"y":0,"w":8,"h":6}' --chart-type bars --x-axis-field due-date --x-axis-date-format MONTH_YEAR --x-axis-time-series --y-axis-serie '{"typeCalc":"SUM","fieldCalc":"amount","color":"#4B9CD3","axisType":"PRIMARY"}' --y-axis-serie '{"typeCalc":"COUNT","fieldCalc":"id","color":"#E57373","axisType":"SECONDARY"}' --legend '{"position":"bottom"}'`,
1390
+ `zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --type CHART --name "Revenue by month" --origin-resource 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --layout '{"x":0,"y":0,"w":8,"h":6}' --chart-type bars --x-axis-field due-date --x-axis-date-format MONTH_YEAR --x-axis-time-series --y-axis-serie '{"typeCalc":"SUM","fieldCalc":"amount","color":"#4B9CD3","axisType":"PRIMARY"}' --y-axis-serie '{"typeCalc":"COUNT","fieldCalc":"contact-name","color":"#E57373","axisType":"SECONDARY"}' --legend '{"position":"bottom"}'`,
1422
1391
  raw: `{
1423
1392
  "type": "CHART",
1424
1393
  "source": {
@@ -1443,7 +1412,7 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
1443
1412
  },
1444
1413
  {
1445
1414
  "typeCalc": "COUNT",
1446
- "fieldCalc": "id",
1415
+ "fieldCalc": "contact-name",
1447
1416
  "color": "#E57373",
1448
1417
  "axisType": "SECONDARY"
1449
1418
  }
@@ -1515,9 +1484,10 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
1515
1484
  }`,
1516
1485
  },
1517
1486
  {
1518
- description: "Create a TIMELINE widget.",
1487
+ description:
1488
+ "Create a TIMELINE widget via flags. The typed view state lives in view.viewAdditionalProperties.viewState; field references there must be UUIDs (slugs are only resolved in --field). cardConfig uses category1/category2/category4 (no category3). Use --view-state for UI scalars (granularity, sidebarWidth, show* ...).",
1519
1489
  command:
1520
- `zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --type TIMELINE --name "Customer schedule" --origin-resource 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --layout '{"x":0,"y":0,"w":12,"h":6}' --field contact-name --field due-date`,
1490
+ `zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --type TIMELINE --name "Customer schedule" --origin-resource 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --layout '{"x":0,"y":0,"w":12,"h":6}' --field c60b8526-5835-4c9f-aecd-9a16c7704a34 --field a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890 --field c52efe3f-2825-4c60-a7e3-34dd4c1ce043 --field d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90 --start-date-field d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90 --end-date-field e5f6a7b8-c9d0-1e2f-3a4b-5c6d7e8f9012 --label-field c60b8526-5835-4c9f-aecd-9a16c7704a34 --group-field a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890 --subgroup-field c60b8526-5835-4c9f-aecd-9a16c7704a34 --progress-field c52efe3f-2825-4c60-a7e3-34dd4c1ce043 --card-title-field c60b8526-5835-4c9f-aecd-9a16c7704a34 --card-category1-field a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890 --card-category2-field d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90 --card-category4-field c52efe3f-2825-4c60-a7e3-34dd4c1ce043 --card-description-field c60b8526-5835-4c9f-aecd-9a16c7704a34 --view-state '{"granularity":"month","sidebarWidth":300,"showUngroupedEvents":true,"showUnsubgroupedEvents":true}'`,
1521
1491
  raw: `{
1522
1492
  "type": "TIMELINE",
1523
1493
  "source": {
@@ -1529,15 +1499,43 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
1529
1499
  },
1530
1500
  "presentation": { "name": "Customer schedule" },
1531
1501
  "view": {
1532
- "fields": ["contact-name", "due-date"]
1502
+ "fields": [
1503
+ "c60b8526-5835-4c9f-aecd-9a16c7704a34",
1504
+ "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
1505
+ "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
1506
+ "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90"
1507
+ ],
1508
+ "viewAdditionalProperties": {
1509
+ "viewState": {
1510
+ "granularity": "month",
1511
+ "sidebarWidth": 300,
1512
+ "showUngroupedEvents": true,
1513
+ "showUnsubgroupedEvents": true,
1514
+ "fieldMapping": {
1515
+ "startDateField": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
1516
+ "endDateField": "e5f6a7b8-c9d0-1e2f-3a4b-5c6d7e8f9012",
1517
+ "labelField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
1518
+ "groupField": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
1519
+ "subgroupField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
1520
+ "progressField": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
1521
+ "cardConfig": {
1522
+ "titleField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
1523
+ "category1Field": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
1524
+ "category2Field": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
1525
+ "category4Field": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
1526
+ "descriptionField": "c60b8526-5835-4c9f-aecd-9a16c7704a34"
1527
+ }
1528
+ }
1529
+ }
1530
+ }
1533
1531
  }
1534
1532
  }`,
1535
1533
  },
1536
1534
  {
1537
1535
  description:
1538
- "Create a KANBAN widget with a status filter and groupsExpanded config (rich query/view requires --raw).",
1536
+ "Create a KANBAN widget via flags. The typed view state lives in view.viewAdditionalProperties.viewState; field references there must be UUIDs (slugs are only resolved in --field). cardConfig uses category1/category2/category3 (no category4). --aggregation-method/--aggregation-field set the card aggregation; use --view-state for UI scalars.",
1539
1537
  command:
1540
- `zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --raw '{"type":"KANBAN","source":{"originResourceId":"2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e","isOriginSubSchema":false},"placement":{"layout":{"x":0,"y":0,"w":12,"h":8}},"presentation":{"name":"Status board"},"query":{"filters":[{"origin":{"schemaId":"contacts","fieldId":"status"},"comparisonOperator":"ANY_OF","values":["1","2","3"]}]},"view":{"fields":["contact-name","status","amount"],"groupsExpanded":{"1":true,"2":true,"3":false}}}'`,
1538
+ `zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --type KANBAN --name "Status board" --origin-resource 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --layout '{"x":0,"y":0,"w":12,"h":8}' --field c60b8526-5835-4c9f-aecd-9a16c7704a34 --field a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890 --field c52efe3f-2825-4c60-a7e3-34dd4c1ce043 --field d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90 --column-field a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890 --swimlane-field c60b8526-5835-4c9f-aecd-9a16c7704a34 --card-title-field c60b8526-5835-4c9f-aecd-9a16c7704a34 --card-category1-field a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890 --card-category2-field d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90 --card-category3-field c52efe3f-2825-4c60-a7e3-34dd4c1ce043 --card-description-field c60b8526-5835-4c9f-aecd-9a16c7704a34 --aggregation-method sum --aggregation-field c52efe3f-2825-4c60-a7e3-34dd4c1ce043 --view-state '{"hideEmptyColumns":false,"showNoValueColumn":true,"showNoValueSwimlane":true}'`,
1541
1539
  raw: `{
1542
1540
  "type": "KANBAN",
1543
1541
  "source": {
@@ -1548,28 +1546,43 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
1548
1546
  "layout": { "x": 0, "y": 0, "w": 12, "h": 8 }
1549
1547
  },
1550
1548
  "presentation": { "name": "Status board" },
1551
- "query": {
1552
- "filters": [
1553
- {
1554
- "origin": {
1555
- "schemaId": "contacts",
1556
- "fieldId": "status"
1557
- },
1558
- "comparisonOperator": "ANY_OF",
1559
- "values": ["1", "2", "3"]
1560
- }
1561
- ]
1562
- },
1563
1549
  "view": {
1564
- "fields": ["contact-name", "status", "amount"],
1565
- "groupsExpanded": { "1": true, "2": true, "3": false }
1550
+ "fields": [
1551
+ "c60b8526-5835-4c9f-aecd-9a16c7704a34",
1552
+ "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
1553
+ "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
1554
+ "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90"
1555
+ ],
1556
+ "viewAdditionalProperties": {
1557
+ "viewState": {
1558
+ "hideEmptyColumns": false,
1559
+ "showNoValueColumn": true,
1560
+ "showNoValueSwimlane": true,
1561
+ "fieldMapping": {
1562
+ "columnField": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
1563
+ "swimlaneField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
1564
+ "cardConfig": {
1565
+ "titleField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
1566
+ "category1Field": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
1567
+ "category2Field": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
1568
+ "category3Field": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
1569
+ "descriptionField": "c60b8526-5835-4c9f-aecd-9a16c7704a34"
1570
+ },
1571
+ "aggregationConfig": {
1572
+ "method": "sum",
1573
+ "fieldId": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043"
1574
+ }
1575
+ }
1576
+ }
1577
+ }
1566
1578
  }
1567
1579
  }`,
1568
1580
  },
1569
1581
  {
1570
- description: "Create a HIERARCHY widget rooted on a parent field.",
1582
+ description:
1583
+ "Create a HIERARCHY widget via flags. Declare columns once (--hierarchy-label, repeatable --hierarchy-info <id:name>, --hierarchy-number <id:name:aggregation>), map the root level (the view's own table) with --hierarchy-root-* and add each child level as a JSON object with --hierarchy-child. label is required per level; info/number mappings are optional. Column ids (e.g. col_1779975207355_zfndknslw) are unique opaque identifiers you choose — not the column name — and are reused as columnId in every mapping. All field references must be UUIDs.",
1571
1584
  command:
1572
- `zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --raw '{"type":"HIERARCHY","source":{"originResourceId":"2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e","isOriginSubSchema":false},"placement":{"layout":{"x":0,"y":0,"w":12,"h":6}},"presentation":{"name":"Org tree"},"view":{"fields":["contact-name","status"],"hierarchyConfig":{"parentFieldId":"contact-name"}}}'`,
1585
+ `zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --type HIERARCHY --name "Org tree" --origin-resource 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --layout '{"x":0,"y":0,"w":12,"h":6}' --field c60b8526-5835-4c9f-aecd-9a16c7704a34 --field a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890 --field c52efe3f-2825-4c60-a7e3-34dd4c1ce043 --hierarchy-label "Name" --hierarchy-info "col_1779975207355_zfndknslw:Status" --hierarchy-info "col_1779975243018_qm4t7xb2pa:Description" --hierarchy-number "col_1779975261490_h8kd3nv9ws:Total amount:SUM" --hierarchy-root-name "Customers" --hierarchy-root-label-field c60b8526-5835-4c9f-aecd-9a16c7704a34 --hierarchy-root-info "col_1779975207355_zfndknslw:a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890" --hierarchy-root-number "col_1779975261490_h8kd3nv9ws:c52efe3f-2825-4c60-a7e3-34dd4c1ce043" --hierarchy-child '{"name":"Projects","schemaId":"3ec9cdef-7e0a-4cdd-8019-8fb9281f5d6f","childFieldId":"80deefae-af3d-4000-b322-bfe1594f8073","labelFieldId":"50dbef0b-7e0a-4fdd-8019-8fb9281f5d70","infoMappings":[{"columnId":"col_1779975243018_qm4t7xb2pa","fieldId":"60dcef0c-8f1b-4eee-9120-9fc0392f6e71"}],"numberMappings":[{"columnId":"col_1779975261490_h8kd3nv9ws","fieldId":"70ddef0d-9f2c-4fff-a221-afd0493f7f72"}]}'`,
1573
1586
  raw: `{
1574
1587
  "type": "HIERARCHY",
1575
1588
  "source": {
@@ -1581,9 +1594,46 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
1581
1594
  },
1582
1595
  "presentation": { "name": "Org tree" },
1583
1596
  "view": {
1584
- "fields": ["contact-name", "status"],
1597
+ "fields": [
1598
+ "c60b8526-5835-4c9f-aecd-9a16c7704a34",
1599
+ "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
1600
+ "c52efe3f-2825-4c60-a7e3-34dd4c1ce043"
1601
+ ],
1585
1602
  "hierarchyConfig": {
1586
- "parentFieldId": "contact-name"
1603
+ "columns": {
1604
+ "label": "Name",
1605
+ "infos": [
1606
+ { "id": "col_1779975207355_zfndknslw", "name": "Status" },
1607
+ { "id": "col_1779975243018_qm4t7xb2pa", "name": "Description" }
1608
+ ],
1609
+ "numbers": [
1610
+ { "id": "col_1779975261490_h8kd3nv9ws", "name": "Total amount", "aggregation": "SUM" }
1611
+ ]
1612
+ },
1613
+ "rootLevel": {
1614
+ "name": "Customers",
1615
+ "labelFieldId": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
1616
+ "infoMappings": [
1617
+ { "columnId": "col_1779975207355_zfndknslw", "fieldId": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890" }
1618
+ ],
1619
+ "numberMappings": [
1620
+ { "columnId": "col_1779975261490_h8kd3nv9ws", "fieldId": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043" }
1621
+ ]
1622
+ },
1623
+ "childLevels": [
1624
+ {
1625
+ "name": "Projects",
1626
+ "schemaId": "3ec9cdef-7e0a-4cdd-8019-8fb9281f5d6f",
1627
+ "childFieldId": "80deefae-af3d-4000-b322-bfe1594f8073",
1628
+ "labelFieldId": "50dbef0b-7e0a-4fdd-8019-8fb9281f5d70",
1629
+ "infoMappings": [
1630
+ { "columnId": "col_1779975243018_qm4t7xb2pa", "fieldId": "60dcef0c-8f1b-4eee-9120-9fc0392f6e71" }
1631
+ ],
1632
+ "numberMappings": [
1633
+ { "columnId": "col_1779975261490_h8kd3nv9ws", "fieldId": "70ddef0d-9f2c-4fff-a221-afd0493f7f72" }
1634
+ ]
1635
+ }
1636
+ ]
1587
1637
  }
1588
1638
  }
1589
1639
  }`,
@@ -1593,13 +1643,13 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
1593
1643
  {
1594
1644
  description: "Move placement, update view columns, rename the widget and lock it.",
1595
1645
  command:
1596
- `zinkee --json displays widgets update 0f6f062f-1478-4df2-96a1-c495d037d260 11111111-1111-4111-a111-111111111111 --layout '{"x":1,"y":2,"w":8,"h":4}' --field id --field contact-name --field status --name "Revenue Updated" --widget-read-only`,
1646
+ `zinkee --json displays widgets update 0f6f062f-1478-4df2-96a1-c495d037d260 11111111-1111-4111-a111-111111111111 --layout '{"x":1,"y":2,"w":8,"h":4}' --field contact-name --field status --field amount --name "Revenue Updated" --widget-read-only`,
1597
1647
  raw: `{
1598
1648
  "placement": {
1599
1649
  "layout": { "x": 1, "y": 2, "w": 8, "h": 4 }
1600
1650
  },
1601
1651
  "view": {
1602
- "fields": ["id", "contact-name", "status"]
1652
+ "fields": ["contact-name", "status", "amount"]
1603
1653
  },
1604
1654
  "presentation": { "name": "Revenue Updated" },
1605
1655
  "behavior": { "readOnly": true }
@@ -2421,7 +2471,7 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
2421
2471
  "resources": [
2422
2472
  {
2423
2473
  "id": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
2424
- "name": "Contacts",
2474
+ "name": "Customer records",
2425
2475
  "type": "SCHEMA",
2426
2476
  "isInSpace": false,
2427
2477
  "additionalProperties": {}
@@ -2445,19 +2495,10 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
2445
2495
  "resources": [
2446
2496
  {
2447
2497
  "id": "3f8a2c1b-9d4e-4a5b-8c6d-7e8f90123456",
2448
- "name": "Quote approval",
2449
- "type": "WORKFLOW",
2498
+ "name": "Shipments",
2499
+ "type": "SCHEMA",
2450
2500
  "isInSpace": false,
2451
2501
  "additionalProperties": {}
2452
- },
2453
- {
2454
- "id": "0f6f062f-1478-4df2-96a1-c495d037d260",
2455
- "name": "Executive Revenue",
2456
- "type": "DISPLAY",
2457
- "isInSpace": true,
2458
- "additionalProperties": {
2459
- "pinned": true
2460
- }
2461
2502
  }
2462
2503
  ],
2463
2504
  "additionalProperties": {
@@ -2504,8 +2545,13 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
2504
2545
  "name": "Shared Dashboards",
2505
2546
  "order": 1,
2506
2547
  "isRoot": false,
2507
- "resourceCount": 1,
2548
+ "resourceCount": 2,
2508
2549
  "resources": [
2550
+ {
2551
+ "id": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
2552
+ "name": "Customer records",
2553
+ "type": "SCHEMA"
2554
+ },
2509
2555
  {
2510
2556
  "id": "0f6f062f-1478-4df2-96a1-c495d037d260",
2511
2557
  "name": "Executive Revenue",
@@ -2679,7 +2725,7 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
2679
2725
  "hideDeleteButton": false
2680
2726
  },
2681
2727
  "view": {
2682
- "fields": ["id", "contact-name", "status", "amount"],
2728
+ "fields": ["contact-name", "status", "amount"],
2683
2729
  "columnSize": { "contact-name": 240 }
2684
2730
  }
2685
2731
  }
@@ -2727,6 +2773,85 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
2727
2773
  command: "zinkee --json displays delete 0f6f062f-1478-4df2-96a1-c495d037d260",
2728
2774
  },
2729
2775
  ]),
2776
+ "displays folders list": buildCommandExamples([
2777
+ {
2778
+ description: "List flat display folders (non-root folders plus the root bucket).",
2779
+ command: "zinkee --json displays folders list",
2780
+ response: `[
2781
+ {
2782
+ "id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
2783
+ "name": "Executive Dashboards",
2784
+ "isRoot": false,
2785
+ "displayCount": 2
2786
+ },
2787
+ {
2788
+ "id": "8b22282b-3db3-4dd7-87f7-b29365dcf3f6",
2789
+ "name": null,
2790
+ "isRoot": true,
2791
+ "displayCount": 4
2792
+ }
2793
+ ]`,
2794
+ },
2795
+ ]),
2796
+ "displays folders create": buildCommandExamples([
2797
+ {
2798
+ description: "Create one flat display folder.",
2799
+ command: 'zinkee --json displays folders create --name "Executive Dashboards"',
2800
+ raw: `{
2801
+ "name": "Executive Dashboards"
2802
+ }`,
2803
+ response: `{
2804
+ "id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
2805
+ "name": "Executive Dashboards",
2806
+ "isRoot": false,
2807
+ "displayCount": 0
2808
+ }`,
2809
+ },
2810
+ ]),
2811
+ "displays folders update": buildCommandExamples([
2812
+ {
2813
+ description: "Rename a display folder. The folder argument accepts a UUID or an exact name.",
2814
+ command:
2815
+ 'zinkee --json displays folders update "Executive Dashboards" --name "Executive Dashboards (2026)"',
2816
+ raw: `{
2817
+ "name": "Executive Dashboards (2026)"
2818
+ }`,
2819
+ response: `{
2820
+ "id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
2821
+ "name": "Executive Dashboards (2026)",
2822
+ "isRoot": false,
2823
+ "displayCount": 2
2824
+ }`,
2825
+ },
2826
+ ]),
2827
+ "displays folders delete": buildCommandExamples([
2828
+ {
2829
+ description: "Delete a non-root display folder. Its displays move back to the root folder.",
2830
+ command: 'zinkee --json displays folders delete "Executive Dashboards"',
2831
+ response: `{
2832
+ "id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
2833
+ "name": "Executive Dashboards",
2834
+ "isRoot": false,
2835
+ "displayCount": 2
2836
+ }`,
2837
+ },
2838
+ ]),
2839
+ "displays folders move": buildCommandExamples([
2840
+ {
2841
+ description: "Move one display into a target folder by exact folder name.",
2842
+ command:
2843
+ 'zinkee --json displays folders move 0f6f062f-1478-4df2-96a1-c495d037d260 --to "Executive Dashboards"',
2844
+ raw: `{
2845
+ "displayId": "0f6f062f-1478-4df2-96a1-c495d037d260",
2846
+ "targetFolderId": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e"
2847
+ }`,
2848
+ response: `{
2849
+ "id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
2850
+ "name": "Executive Dashboards",
2851
+ "isRoot": false
2852
+ }`,
2853
+ },
2854
+ ]),
2730
2855
  "displays layout get": buildCommandExamples([
2731
2856
  {
2732
2857
  description: "Get the layout block of a display (template + tabs/freeformLayouts/slots).",
@@ -2824,7 +2949,7 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
2824
2949
  "hideDeleteButton": false
2825
2950
  },
2826
2951
  "view": {
2827
- "fields": ["id", "contact-name", "status", "amount"],
2952
+ "fields": ["contact-name", "status", "amount"],
2828
2953
  "columnSize": { "contact-name": 240 }
2829
2954
  }
2830
2955
  }`,
@@ -3797,7 +3922,8 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
3797
3922
  description: "Move one automation into a target folder by exact folder name.",
3798
3923
  command: 'zinkee --json automations folders move automation-1 --to "Codex Frontend Demo"',
3799
3924
  raw: `{
3800
- "automationId": "automation-1"
3925
+ "automationId": "automation-1",
3926
+ "targetFolderId": "cdfc14e3-3169-4ffb-8d9b-b11858a9240f"
3801
3927
  }`,
3802
3928
  response: `{
3803
3929
  "id": "cdfc14e3-3169-4ffb-8d9b-b11858a9240f",