zinkee 0.1.25 → 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.
@@ -47,7 +47,10 @@
47
47
  "Bash(echo \"=== exit $? \\(grep\\) ===\")",
48
48
  "Bash(grep -rn \"resourceType\" src/)",
49
49
  "Bash(grep -rn \"automation-folders/\\\\${\\\\|/automations:move\\\\|{folderId}/automations\" src/)",
50
- "Bash(grep -rn \"navigation resources move.*--type\\\\|resourceType\" docs/ README.md)"
50
+ "Bash(grep -rn \"navigation resources move.*--type\\\\|resourceType\" docs/ README.md)",
51
+ "Bash(zinkee --version)",
52
+ "Bash(zinkee --json profiles list)",
53
+ "Bash(zinkee displays *)"
51
54
  ]
52
55
  }
53
56
  }
package/README.md CHANGED
@@ -486,9 +486,51 @@ zinkee --json displays widgets create <display-uuid> \
486
486
  "chart":{"yAxisSeries":[{"typeCalc":"SUM","fieldCalc":"hours-field-slug","axisType":"PRIMARY"}]}
487
487
  }'
488
488
 
489
- # KANBAN, TIMELINE, DETAIL also supported
489
+ # KANBAN widget (field mapping lives in view.viewAdditionalProperties.viewState)
490
+ zinkee --json displays widgets create <display-uuid> \
491
+ --type KANBAN \
492
+ --name "Status board" \
493
+ --origin-resource <schema-uuid> \
494
+ --field <name-field-uuid> --field <status-field-uuid> --field <amount-field-uuid> \
495
+ --column-field <status-field-uuid> \
496
+ --swimlane-field <owner-field-uuid> \
497
+ --card-title-field <name-field-uuid> \
498
+ --card-category1-field <status-field-uuid> \
499
+ --aggregation-method sum --aggregation-field <amount-field-uuid> \
500
+ --view-state '{"showNoValueColumn":true,"showNoValueSwimlane":true}'
501
+
502
+ # TIMELINE widget (cardConfig uses category1/category2/category4, no category3)
503
+ zinkee --json displays widgets create <display-uuid> \
504
+ --type TIMELINE \
505
+ --name "Customer schedule" \
506
+ --origin-resource <schema-uuid> \
507
+ --field <name-field-uuid> --field <start-field-uuid> --field <end-field-uuid> \
508
+ --start-date-field <start-field-uuid> \
509
+ --end-date-field <end-field-uuid> \
510
+ --label-field <name-field-uuid> \
511
+ --card-title-field <name-field-uuid> \
512
+ --view-state '{"granularity":"month","sidebarWidth":300}'
513
+
514
+ # HIERARCHY widget (columns + root level + repeatable child levels)
515
+ zinkee --json displays widgets create <display-uuid> \
516
+ --type HIERARCHY \
517
+ --name "Org tree" \
518
+ --origin-resource <schema-uuid> \
519
+ --field <name-field-uuid> --field <status-field-uuid> --field <amount-field-uuid> \
520
+ --hierarchy-label "Name" \
521
+ --hierarchy-info "col_1779975207355_zfndknslw:Status" \
522
+ --hierarchy-number "col_1779975261490_h8kd3nv9ws:Total amount:SUM" \
523
+ --hierarchy-root-name "Customers" \
524
+ --hierarchy-root-label-field <name-field-uuid> \
525
+ --hierarchy-root-info "col_1779975207355_zfndknslw:<status-field-uuid>" \
526
+ --hierarchy-root-number "col_1779975261490_h8kd3nv9ws:<amount-field-uuid>" \
527
+ --hierarchy-child '{"name":"Projects","schemaId":"<projects-schema-uuid>","childFieldId":"<project-customer-field-uuid>","labelFieldId":"<project-name-field-uuid>","infoMappings":[],"numberMappings":[{"columnId":"col_1779975261490_h8kd3nv9ws","fieldId":"<project-amount-field-uuid>"}]}'
490
528
  ```
491
529
 
530
+ For KANBAN/TIMELINE, `cardConfig` differs by type: KANBAN exposes `category1Field`/`category2Field`/`category3Field` (`--card-category1-field`…`--card-category3-field`), TIMELINE exposes `category1Field`/`category2Field`/`category4Field` (`--card-category4-field`). UI-state scalars (`columnOrder`, `hiddenColumns`, `collapsedColumns`, `hideEmptyColumns`, `showNoValueColumn`, `showNoValueSwimlane`, `granularity`, `sidebarWidth`, `visibleFields`, `collapsedGroups`, `collapsedSubgroups`, `showUngroupedEvents`, `showUnsubgroupedEvents`) go through `--view-state '<json>'` / `--view-state-file <path>`.
531
+
532
+ For HIERARCHY, `label` is required at every level but info/number mappings are optional; each child level relates to its parent through `childFieldId` (level 2 → root, level 3 → level 2, …). Numeric columns aggregate upward: a parent shows the aggregation of its children's values, falling back to the level's own mapped value when children have none. Column ids (the `id` in `--hierarchy-info`/`--hierarchy-number`, reused as `columnId` in every mapping) must be unique opaque identifiers you choose — not the column name; the frontend generates them as `col_<timestamp>_<random>` (e.g. `col_1779975207355_zfndknslw`). Pass the whole `hierarchyConfig` at once with `--hierarchy-config '<json>'` / `--hierarchy-config-file <path>` if you prefer.
533
+
492
534
  Widget types: `TABLE_OR_SUBTABLE`, `DETAIL`, `KPI`, `CHART`, `TIMELINE`, `KANBAN`, `HIERARCHY`.
493
535
 
494
536
  ### Set freeform layout
@@ -525,6 +567,8 @@ For comparators the parser does not cover yet (e.g. `NOT_CONTAINS`, `RANGE`) kee
525
567
 
526
568
  Slugs are resolved to UUIDs in: `--field`, `--source-schema`, `--source-field`, `--x-axis-field`, `--filter` field reference, `kpi.fieldCalc`, `chart.xAxisFieldId`, `chart.yAxisSeries[].fieldCalc`, `bindings.variableMap` values.
527
569
 
570
+ **Exception:** field references inside the KANBAN/TIMELINE `viewState` (`--column-field`, `--start-date-field`, `--card-*-field`, `--aggregation-field`, …) and inside the HIERARCHY `hierarchyConfig` (`--hierarchy-root-label-field`, `--hierarchy-root-info`/`--hierarchy-root-number` field ids, child level `*FieldId`/`schemaId`) are **not** slug-resolved — the backend only resolves slugs in `view.fields`, so these must be canonical UUIDs.
571
+
528
572
  Display UUIDs are required for `displays widgets create/update` and `displays variables create`.
529
573
 
530
574
  ---
package/dist/index.js CHANGED
@@ -3381,7 +3381,7 @@ var specificExamples = {
3381
3381
  "displays widgets create": buildCommandExamples([
3382
3382
  {
3383
3383
  description: "Create a TABLE widget (CLI normalises --type table to TABLE_OR_SUBTABLE).",
3384
- command: `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"}'`,
3384
+ command: `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"}'`,
3385
3385
  raw: `{
3386
3386
  "type": "TABLE_OR_SUBTABLE",
3387
3387
  "source": {
@@ -3396,11 +3396,11 @@ var specificExamples = {
3396
3396
  },
3397
3397
  "query": {
3398
3398
  "sorts": [
3399
- { "fieldId": "id", "direction": "DESC" }
3399
+ { "fieldId": "contact-name", "direction": "ASC" }
3400
3400
  ]
3401
3401
  },
3402
3402
  "view": {
3403
- "fields": ["id", "contact-name", "status"]
3403
+ "fields": ["contact-name", "status", "amount"]
3404
3404
  }
3405
3405
  }`,
3406
3406
  response: `{
@@ -3480,7 +3480,7 @@ var specificExamples = {
3480
3480
  },
3481
3481
  {
3482
3482
  description: "Create a bars CHART widget with a monthly time-serie x-axis and two y-axis series.",
3483
- command: `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"}'`,
3483
+ command: `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"}'`,
3484
3484
  raw: `{
3485
3485
  "type": "CHART",
3486
3486
  "source": {
@@ -3505,7 +3505,7 @@ var specificExamples = {
3505
3505
  },
3506
3506
  {
3507
3507
  "typeCalc": "COUNT",
3508
- "fieldCalc": "id",
3508
+ "fieldCalc": "contact-name",
3509
3509
  "color": "#E57373",
3510
3510
  "axisType": "SECONDARY"
3511
3511
  }
@@ -3575,8 +3575,8 @@ var specificExamples = {
3575
3575
  }`
3576
3576
  },
3577
3577
  {
3578
- description: "Create a TIMELINE widget.",
3579
- command: `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`,
3578
+ description: "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* ...).",
3579
+ command: `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}'`,
3580
3580
  raw: `{
3581
3581
  "type": "TIMELINE",
3582
3582
  "source": {
@@ -3588,13 +3588,41 @@ var specificExamples = {
3588
3588
  },
3589
3589
  "presentation": { "name": "Customer schedule" },
3590
3590
  "view": {
3591
- "fields": ["contact-name", "due-date"]
3591
+ "fields": [
3592
+ "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3593
+ "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3594
+ "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
3595
+ "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90"
3596
+ ],
3597
+ "viewAdditionalProperties": {
3598
+ "viewState": {
3599
+ "granularity": "month",
3600
+ "sidebarWidth": 300,
3601
+ "showUngroupedEvents": true,
3602
+ "showUnsubgroupedEvents": true,
3603
+ "fieldMapping": {
3604
+ "startDateField": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
3605
+ "endDateField": "e5f6a7b8-c9d0-1e2f-3a4b-5c6d7e8f9012",
3606
+ "labelField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3607
+ "groupField": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3608
+ "subgroupField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3609
+ "progressField": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
3610
+ "cardConfig": {
3611
+ "titleField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3612
+ "category1Field": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3613
+ "category2Field": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
3614
+ "category4Field": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
3615
+ "descriptionField": "c60b8526-5835-4c9f-aecd-9a16c7704a34"
3616
+ }
3617
+ }
3618
+ }
3619
+ }
3592
3620
  }
3593
3621
  }`
3594
3622
  },
3595
3623
  {
3596
- description: "Create a KANBAN widget with a status filter and groupsExpanded config (rich query/view requires --raw).",
3597
- command: `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}}}'`,
3624
+ description: "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.",
3625
+ command: `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}'`,
3598
3626
  raw: `{
3599
3627
  "type": "KANBAN",
3600
3628
  "source": {
@@ -3605,27 +3633,41 @@ var specificExamples = {
3605
3633
  "layout": { "x": 0, "y": 0, "w": 12, "h": 8 }
3606
3634
  },
3607
3635
  "presentation": { "name": "Status board" },
3608
- "query": {
3609
- "filters": [
3610
- {
3611
- "origin": {
3612
- "schemaId": "contacts",
3613
- "fieldId": "status"
3614
- },
3615
- "comparisonOperator": "ANY_OF",
3616
- "values": ["1", "2", "3"]
3617
- }
3618
- ]
3619
- },
3620
3636
  "view": {
3621
- "fields": ["contact-name", "status", "amount"],
3622
- "groupsExpanded": { "1": true, "2": true, "3": false }
3637
+ "fields": [
3638
+ "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3639
+ "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3640
+ "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
3641
+ "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90"
3642
+ ],
3643
+ "viewAdditionalProperties": {
3644
+ "viewState": {
3645
+ "hideEmptyColumns": false,
3646
+ "showNoValueColumn": true,
3647
+ "showNoValueSwimlane": true,
3648
+ "fieldMapping": {
3649
+ "columnField": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3650
+ "swimlaneField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3651
+ "cardConfig": {
3652
+ "titleField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3653
+ "category1Field": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3654
+ "category2Field": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
3655
+ "category3Field": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
3656
+ "descriptionField": "c60b8526-5835-4c9f-aecd-9a16c7704a34"
3657
+ },
3658
+ "aggregationConfig": {
3659
+ "method": "sum",
3660
+ "fieldId": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043"
3661
+ }
3662
+ }
3663
+ }
3664
+ }
3623
3665
  }
3624
3666
  }`
3625
3667
  },
3626
3668
  {
3627
- description: "Create a HIERARCHY widget rooted on a parent field.",
3628
- command: `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"}}}'`,
3669
+ description: "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 \u2014 not the column name \u2014 and are reused as columnId in every mapping. All field references must be UUIDs.",
3670
+ command: `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"}]}'`,
3629
3671
  raw: `{
3630
3672
  "type": "HIERARCHY",
3631
3673
  "source": {
@@ -3637,9 +3679,46 @@ var specificExamples = {
3637
3679
  },
3638
3680
  "presentation": { "name": "Org tree" },
3639
3681
  "view": {
3640
- "fields": ["contact-name", "status"],
3682
+ "fields": [
3683
+ "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3684
+ "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3685
+ "c52efe3f-2825-4c60-a7e3-34dd4c1ce043"
3686
+ ],
3641
3687
  "hierarchyConfig": {
3642
- "parentFieldId": "contact-name"
3688
+ "columns": {
3689
+ "label": "Name",
3690
+ "infos": [
3691
+ { "id": "col_1779975207355_zfndknslw", "name": "Status" },
3692
+ { "id": "col_1779975243018_qm4t7xb2pa", "name": "Description" }
3693
+ ],
3694
+ "numbers": [
3695
+ { "id": "col_1779975261490_h8kd3nv9ws", "name": "Total amount", "aggregation": "SUM" }
3696
+ ]
3697
+ },
3698
+ "rootLevel": {
3699
+ "name": "Customers",
3700
+ "labelFieldId": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3701
+ "infoMappings": [
3702
+ { "columnId": "col_1779975207355_zfndknslw", "fieldId": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890" }
3703
+ ],
3704
+ "numberMappings": [
3705
+ { "columnId": "col_1779975261490_h8kd3nv9ws", "fieldId": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043" }
3706
+ ]
3707
+ },
3708
+ "childLevels": [
3709
+ {
3710
+ "name": "Projects",
3711
+ "schemaId": "3ec9cdef-7e0a-4cdd-8019-8fb9281f5d6f",
3712
+ "childFieldId": "80deefae-af3d-4000-b322-bfe1594f8073",
3713
+ "labelFieldId": "50dbef0b-7e0a-4fdd-8019-8fb9281f5d70",
3714
+ "infoMappings": [
3715
+ { "columnId": "col_1779975243018_qm4t7xb2pa", "fieldId": "60dcef0c-8f1b-4eee-9120-9fc0392f6e71" }
3716
+ ],
3717
+ "numberMappings": [
3718
+ { "columnId": "col_1779975261490_h8kd3nv9ws", "fieldId": "70ddef0d-9f2c-4fff-a221-afd0493f7f72" }
3719
+ ]
3720
+ }
3721
+ ]
3643
3722
  }
3644
3723
  }
3645
3724
  }`
@@ -3648,13 +3727,13 @@ var specificExamples = {
3648
3727
  "displays widgets update": buildCommandExamples([
3649
3728
  {
3650
3729
  description: "Move placement, update view columns, rename the widget and lock it.",
3651
- command: `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`,
3730
+ command: `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`,
3652
3731
  raw: `{
3653
3732
  "placement": {
3654
3733
  "layout": { "x": 1, "y": 2, "w": 8, "h": 4 }
3655
3734
  },
3656
3735
  "view": {
3657
- "fields": ["id", "contact-name", "status"]
3736
+ "fields": ["contact-name", "status", "amount"]
3658
3737
  },
3659
3738
  "presentation": { "name": "Revenue Updated" },
3660
3739
  "behavior": { "readOnly": true }
@@ -4711,7 +4790,7 @@ var specificExamples = {
4711
4790
  "hideDeleteButton": false
4712
4791
  },
4713
4792
  "view": {
4714
- "fields": ["id", "contact-name", "status", "amount"],
4793
+ "fields": ["contact-name", "status", "amount"],
4715
4794
  "columnSize": { "contact-name": 240 }
4716
4795
  }
4717
4796
  }
@@ -4928,7 +5007,7 @@ var specificExamples = {
4928
5007
  "hideDeleteButton": false
4929
5008
  },
4930
5009
  "view": {
4931
- "fields": ["id", "contact-name", "status", "amount"],
5010
+ "fields": ["contact-name", "status", "amount"],
4932
5011
  "columnSize": { "contact-name": 240 }
4933
5012
  }
4934
5013
  }`
@@ -8619,6 +8698,150 @@ function readNamedJsonOption(raw, rawFile, inlineFlag = "--option", fileFlag = "
8619
8698
  function isEmptyObject3(value) {
8620
8699
  return Object.keys(value).length === 0;
8621
8700
  }
8701
+ function isPlainObject(value) {
8702
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8703
+ }
8704
+ function deepMerge(target, source) {
8705
+ const out = { ...target };
8706
+ for (const [key, value] of Object.entries(source)) {
8707
+ const existing = out[key];
8708
+ out[key] = isPlainObject(existing) && isPlainObject(value) ? deepMerge(existing, value) : value;
8709
+ }
8710
+ return out;
8711
+ }
8712
+ function assignDefined(target, key, value) {
8713
+ if (value !== void 0) target[key] = value;
8714
+ }
8715
+ function readNamedJsonObject(raw, rawFile, inlineFlag, fileFlag) {
8716
+ const parsed = readNamedJsonOption(raw, rawFile, inlineFlag, fileFlag);
8717
+ if (parsed === void 0) return void 0;
8718
+ if (!isPlainObject(parsed)) {
8719
+ throw new CliError("invalid_cli_usage", `${inlineFlag} payload must be a JSON object.`);
8720
+ }
8721
+ return parsed;
8722
+ }
8723
+ var HIERARCHY_AGGREGATIONS = /* @__PURE__ */ new Set([
8724
+ "SUM",
8725
+ "AVERAGE",
8726
+ "MINIMUM",
8727
+ "MAXIMUM",
8728
+ "COUNT",
8729
+ "COUNT_DISTINCT"
8730
+ ]);
8731
+ function parseHierarchyInfo(value) {
8732
+ const idx = value.indexOf(":");
8733
+ if (idx <= 0 || idx === value.length - 1) {
8734
+ throw new CliError("invalid_cli_usage", `--hierarchy-info "${value}" must use the format <id:name>.`);
8735
+ }
8736
+ return { id: value.slice(0, idx).trim(), name: value.slice(idx + 1).trim() };
8737
+ }
8738
+ function parseHierarchyNumber(value) {
8739
+ const parts = value.split(":");
8740
+ if (parts.length < 3) {
8741
+ throw new CliError(
8742
+ "invalid_cli_usage",
8743
+ `--hierarchy-number "${value}" must use the format <id:name:aggregation>.`
8744
+ );
8745
+ }
8746
+ const id = parts[0]?.trim() ?? "";
8747
+ const aggregation = (parts[parts.length - 1]?.trim() ?? "").toUpperCase();
8748
+ const name = parts.slice(1, -1).join(":").trim();
8749
+ if (!id || !name) {
8750
+ throw new CliError(
8751
+ "invalid_cli_usage",
8752
+ `--hierarchy-number "${value}" must use the format <id:name:aggregation>.`
8753
+ );
8754
+ }
8755
+ if (!HIERARCHY_AGGREGATIONS.has(aggregation)) {
8756
+ throw new CliError(
8757
+ "invalid_cli_usage",
8758
+ `--hierarchy-number aggregation "${aggregation}" must be one of SUM, AVERAGE, MINIMUM, MAXIMUM, COUNT, COUNT_DISTINCT.`
8759
+ );
8760
+ }
8761
+ return { id, name, aggregation };
8762
+ }
8763
+ function parseHierarchyMapping(value, flag) {
8764
+ const idx = value.indexOf(":");
8765
+ if (idx <= 0 || idx === value.length - 1) {
8766
+ throw new CliError("invalid_cli_usage", `${flag} "${value}" must use the format <columnId:fieldId>.`);
8767
+ }
8768
+ return { columnId: value.slice(0, idx).trim(), fieldId: value.slice(idx + 1).trim() };
8769
+ }
8770
+ function buildWidgetFieldMapping(options) {
8771
+ const mapping = {};
8772
+ assignDefined(mapping, "columnField", options.columnField);
8773
+ assignDefined(mapping, "swimlaneField", options.swimlaneField);
8774
+ assignDefined(mapping, "startDateField", options.startDateField);
8775
+ assignDefined(mapping, "endDateField", options.endDateField);
8776
+ assignDefined(mapping, "labelField", options.labelField);
8777
+ assignDefined(mapping, "groupField", options.groupField);
8778
+ assignDefined(mapping, "subgroupField", options.subgroupField);
8779
+ assignDefined(mapping, "progressField", options.progressField);
8780
+ const cardConfig = {};
8781
+ assignDefined(cardConfig, "titleField", options.cardTitleField);
8782
+ assignDefined(cardConfig, "category1Field", options.cardCategory1Field);
8783
+ assignDefined(cardConfig, "category2Field", options.cardCategory2Field);
8784
+ assignDefined(cardConfig, "category3Field", options.cardCategory3Field);
8785
+ assignDefined(cardConfig, "category4Field", options.cardCategory4Field);
8786
+ assignDefined(cardConfig, "descriptionField", options.cardDescriptionField);
8787
+ if (Object.keys(cardConfig).length > 0) mapping.cardConfig = cardConfig;
8788
+ const aggregationConfig = {};
8789
+ assignDefined(aggregationConfig, "method", options.aggregationMethod);
8790
+ assignDefined(aggregationConfig, "fieldId", options.aggregationField);
8791
+ if (Object.keys(aggregationConfig).length > 0) mapping.aggregationConfig = aggregationConfig;
8792
+ return Object.keys(mapping).length > 0 ? mapping : void 0;
8793
+ }
8794
+ function buildHierarchyConfig(options) {
8795
+ const base = readNamedJsonObject(
8796
+ options.hierarchyConfig,
8797
+ options.hierarchyConfigFile,
8798
+ "--hierarchy-config",
8799
+ "--hierarchy-config-file"
8800
+ );
8801
+ const patch = {};
8802
+ const columns = {};
8803
+ assignDefined(columns, "label", options.hierarchyLabel);
8804
+ if (options.hierarchyInfo && options.hierarchyInfo.length > 0) {
8805
+ columns.infos = options.hierarchyInfo.map(parseHierarchyInfo);
8806
+ }
8807
+ if (options.hierarchyNumber && options.hierarchyNumber.length > 0) {
8808
+ columns.numbers = options.hierarchyNumber.map(parseHierarchyNumber);
8809
+ }
8810
+ if (Object.keys(columns).length > 0) patch.columns = columns;
8811
+ const rootLevel = {};
8812
+ assignDefined(rootLevel, "name", options.hierarchyRootName);
8813
+ assignDefined(rootLevel, "labelFieldId", options.hierarchyRootLabelField);
8814
+ if (options.hierarchyRootInfo && options.hierarchyRootInfo.length > 0) {
8815
+ rootLevel.infoMappings = options.hierarchyRootInfo.map(
8816
+ (entry) => parseHierarchyMapping(entry, "--hierarchy-root-info")
8817
+ );
8818
+ }
8819
+ if (options.hierarchyRootNumber && options.hierarchyRootNumber.length > 0) {
8820
+ rootLevel.numberMappings = options.hierarchyRootNumber.map(
8821
+ (entry) => parseHierarchyMapping(entry, "--hierarchy-root-number")
8822
+ );
8823
+ }
8824
+ if (Object.keys(rootLevel).length > 0) patch.rootLevel = rootLevel;
8825
+ if (options.hierarchyChild && options.hierarchyChild.length > 0) {
8826
+ patch.childLevels = options.hierarchyChild.map((entry, index) => {
8827
+ let parsed;
8828
+ try {
8829
+ parsed = JSON.parse(entry);
8830
+ } catch {
8831
+ throw new CliError("invalid_cli_usage", `--hierarchy-child payload #${index + 1} is invalid JSON.`);
8832
+ }
8833
+ if (!isPlainObject(parsed)) {
8834
+ throw new CliError(
8835
+ "invalid_cli_usage",
8836
+ `--hierarchy-child payload #${index + 1} must be a JSON object.`
8837
+ );
8838
+ }
8839
+ return parsed;
8840
+ });
8841
+ }
8842
+ if (base === void 0 && Object.keys(patch).length === 0) return void 0;
8843
+ return deepMerge(base ?? {}, patch);
8844
+ }
8622
8845
  function displayRows(displays) {
8623
8846
  return displays.map((display) => ({
8624
8847
  id: display.id,
@@ -8725,11 +8948,31 @@ function buildWidgetBody(options) {
8725
8948
  layout
8726
8949
  };
8727
8950
  }
8951
+ const viewPatch = {};
8728
8952
  if (options.field && options.field.length > 0) {
8729
- body.view = {
8730
- ...typeof body.view === "object" && body.view ? body.view : {},
8731
- fields: options.field
8732
- };
8953
+ viewPatch.fields = options.field;
8954
+ }
8955
+ const fieldMapping = buildWidgetFieldMapping(options);
8956
+ const viewStateBase = readNamedJsonObject(
8957
+ options.viewState,
8958
+ options.viewStateFile,
8959
+ "--view-state",
8960
+ "--view-state-file"
8961
+ );
8962
+ let viewState = viewStateBase ? { ...viewStateBase } : void 0;
8963
+ if (fieldMapping) {
8964
+ viewState = deepMerge(viewState ?? {}, { fieldMapping });
8965
+ }
8966
+ if (viewState !== void 0) {
8967
+ viewPatch.viewAdditionalProperties = { viewState };
8968
+ }
8969
+ const hierarchyConfig = buildHierarchyConfig(options);
8970
+ if (hierarchyConfig !== void 0) {
8971
+ viewPatch.hierarchyConfig = hierarchyConfig;
8972
+ }
8973
+ if (Object.keys(viewPatch).length > 0) {
8974
+ const existingView = typeof body.view === "object" && body.view ? body.view : {};
8975
+ body.view = deepMerge(existingView, viewPatch);
8733
8976
  }
8734
8977
  const queryMerge = {};
8735
8978
  if (options.sort && options.sort.length > 0) queryMerge.sorts = options.sort;
@@ -9068,7 +9311,7 @@ function registerDisplaysCommands(program, options = {}) {
9068
9311
  }
9069
9312
  printTable([data], void 0, stdout);
9070
9313
  });
9071
- widgets.command("create").description("Create widget").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).requiredOption("--type <type>", "widget type").option("--name <name>").option("--description <text>").option("--icon <icon>").option("--color <color>").option("--origin-resource <uuid>").option("--origin-subschema").option("--tab <tabId>").option("--slot <slotId>").option("--layout <json>").option("--layout-file <path>").option("--field <field>", "repeatable field", (v, p = []) => [...p, v], []).option("--sort <sort>", "repeatable sort", (v, p = []) => [...p, v], []).option("--filter <expr>", "repeatable filter", collectFilters, []).option("--widget-read-only").option("--hide-add-button").option("--hide-delete-button").option("--hide-sort-button").option("--hide-filter-button").option("--hide-see-button").option("--calc <type>").option("--calc-field <uuid>").option("--kpi-config <json>").option("--chart-type <type>", "chart type (lines, bars, stackedBars, combined)").option("--x-axis-field <uuid>").option("--x-axis-date-format <granularity>", "time granularity (DATE, MONTH_YEAR, QUARTER_YEAR, YEAR)").option("--x-axis-time-series").option("--y-axis-serie <json>", "repeatable y axis serie", (v, p = []) => [...p, v], []).option("--legend <json>").option("--raw <json>").option("--raw-file <path>").action(async function action(display, commandOptions) {
9314
+ widgets.command("create").description("Create widget").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).requiredOption("--type <type>", "widget type").option("--name <name>").option("--description <text>").option("--icon <icon>").option("--color <color>").option("--origin-resource <uuid>").option("--origin-subschema").option("--tab <tabId>").option("--slot <slotId>").option("--layout <json>").option("--layout-file <path>").option("--field <field>", "repeatable field", (v, p = []) => [...p, v], []).option("--sort <sort>", "repeatable sort", (v, p = []) => [...p, v], []).option("--filter <expr>", "repeatable filter", collectFilters, []).option("--widget-read-only").option("--hide-add-button").option("--hide-delete-button").option("--hide-sort-button").option("--hide-filter-button").option("--hide-see-button").option("--calc <type>").option("--calc-field <uuid>").option("--kpi-config <json>").option("--chart-type <type>", "chart type (lines, bars, stackedBars, combined)").option("--x-axis-field <uuid>").option("--x-axis-date-format <granularity>", "time granularity (DATE, MONTH_YEAR, QUARTER_YEAR, YEAR)").option("--x-axis-time-series").option("--y-axis-serie <json>", "repeatable y axis serie", (v, p = []) => [...p, v], []).option("--legend <json>").option("--column-field <uuid>", "KANBAN column field (UUID, not slug)").option("--swimlane-field <uuid>", "KANBAN swimlane field (UUID, not slug)").option("--start-date-field <uuid>", "TIMELINE start date field (UUID, not slug)").option("--end-date-field <uuid>", "TIMELINE end date field (UUID, not slug)").option("--label-field <uuid>", "TIMELINE label field (UUID, not slug)").option("--group-field <uuid>", "TIMELINE group field (UUID, not slug)").option("--subgroup-field <uuid>", "TIMELINE subgroup field (UUID, not slug)").option("--progress-field <uuid>", "TIMELINE progress field (UUID, not slug)").option("--card-title-field <uuid>", "KANBAN/TIMELINE card title field (UUID, not slug)").option("--card-category1-field <uuid>", "KANBAN/TIMELINE card category 1 field (UUID, not slug)").option("--card-category2-field <uuid>", "KANBAN/TIMELINE card category 2 field (UUID, not slug)").option("--card-category3-field <uuid>", "KANBAN card category 3 field (UUID, not slug)").option("--card-category4-field <uuid>", "TIMELINE card category 4 field (UUID, not slug)").option("--card-description-field <uuid>", "KANBAN/TIMELINE card description field (UUID, not slug)").option("--aggregation-method <method>", "KANBAN card aggregation method (e.g. sum)").option("--aggregation-field <uuid>", "KANBAN card aggregation field (UUID, not slug)").option("--view-state <json>", "KANBAN/TIMELINE viewState UI scalars (columnOrder, granularity, sidebarWidth, show* ...)").option("--view-state-file <path>", "read --view-state JSON from a file").option("--hierarchy-label <name>", "HIERARCHY label column name").option("--hierarchy-info <id:name>", "HIERARCHY info column; id is a unique opaque column id you choose (e.g. col_1779975207355_zfndknslw), not the name, and is reused as columnId in mappings (repeatable)", (v, p = []) => [...p, v], []).option("--hierarchy-number <id:name:aggregation>", "HIERARCHY number column; id is a unique opaque column id (e.g. col_1779975207355_zfndknslw), not the name; aggregation SUM|AVERAGE|MINIMUM|MAXIMUM|COUNT|COUNT_DISTINCT (repeatable)", (v, p = []) => [...p, v], []).option("--hierarchy-root-name <name>", "HIERARCHY root level name").option("--hierarchy-root-label-field <uuid>", "HIERARCHY root level label field (UUID, not slug)").option("--hierarchy-root-info <columnId:fieldId>", "HIERARCHY root info mapping; columnId must match a --hierarchy-info id (repeatable)", (v, p = []) => [...p, v], []).option("--hierarchy-root-number <columnId:fieldId>", "HIERARCHY root number mapping; columnId must match a --hierarchy-number id (repeatable)", (v, p = []) => [...p, v], []).option("--hierarchy-child <json>", "HIERARCHY child level JSON {name,schemaId,childFieldId,labelFieldId,infoMappings,numberMappings} (repeatable)", (v, p = []) => [...p, v], []).option("--hierarchy-config <json>", "HIERARCHY full hierarchyConfig JSON (escape hatch)").option("--hierarchy-config-file <path>", "read --hierarchy-config JSON from a file").option("--raw <json>").option("--raw-file <path>").action(async function action(display, commandOptions) {
9072
9315
  const { api, json, readOnly } = createDisplaysApi(this, filePath);
9073
9316
  ensureWritable3("displays widgets create", readOnly, "write");
9074
9317
  const data = await api.createWidget(display, buildWidgetBody(commandOptions));
@@ -9078,7 +9321,7 @@ function registerDisplaysCommands(program, options = {}) {
9078
9321
  }
9079
9322
  writeLine4(stdout, `Created widget on display "${display.value}".`);
9080
9323
  });
9081
- widgets.command("update").description("Update widget").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).argument("<widget>", "widget id").option("--type <type>").option("--name <name>").option("--description <text>").option("--icon <icon>").option("--color <color>").option("--origin-resource <uuid>").option("--origin-subschema").option("--tab <tabId>").option("--slot <slotId>").option("--layout <json>").option("--layout-file <path>").option("--field <field>", "repeatable field", (v, p = []) => [...p, v], []).option("--sort <sort>", "repeatable sort", (v, p = []) => [...p, v], []).option("--filter <expr>", "repeatable filter", collectFilters, []).option("--widget-read-only").option("--hide-add-button").option("--hide-delete-button").option("--hide-sort-button").option("--hide-filter-button").option("--hide-see-button").option("--calc <type>").option("--calc-field <uuid>").option("--kpi-config <json>").option("--chart-type <type>", "chart type (lines, bars, stackedBars, combined)").option("--x-axis-field <uuid>").option("--x-axis-date-format <granularity>", "time granularity (DATE, MONTH_YEAR, QUARTER_YEAR, YEAR)").option("--x-axis-time-series").option("--y-axis-serie <json>", "repeatable y axis serie", (v, p = []) => [...p, v], []).option("--legend <json>").option("--raw <json>").option("--raw-file <path>").action(async function action(display, widgetId, commandOptions) {
9324
+ widgets.command("update").description("Update widget").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).argument("<widget>", "widget id").option("--type <type>").option("--name <name>").option("--description <text>").option("--icon <icon>").option("--color <color>").option("--origin-resource <uuid>").option("--origin-subschema").option("--tab <tabId>").option("--slot <slotId>").option("--layout <json>").option("--layout-file <path>").option("--field <field>", "repeatable field", (v, p = []) => [...p, v], []).option("--sort <sort>", "repeatable sort", (v, p = []) => [...p, v], []).option("--filter <expr>", "repeatable filter", collectFilters, []).option("--widget-read-only").option("--hide-add-button").option("--hide-delete-button").option("--hide-sort-button").option("--hide-filter-button").option("--hide-see-button").option("--calc <type>").option("--calc-field <uuid>").option("--kpi-config <json>").option("--chart-type <type>", "chart type (lines, bars, stackedBars, combined)").option("--x-axis-field <uuid>").option("--x-axis-date-format <granularity>", "time granularity (DATE, MONTH_YEAR, QUARTER_YEAR, YEAR)").option("--x-axis-time-series").option("--y-axis-serie <json>", "repeatable y axis serie", (v, p = []) => [...p, v], []).option("--legend <json>").option("--column-field <uuid>", "KANBAN column field (UUID, not slug)").option("--swimlane-field <uuid>", "KANBAN swimlane field (UUID, not slug)").option("--start-date-field <uuid>", "TIMELINE start date field (UUID, not slug)").option("--end-date-field <uuid>", "TIMELINE end date field (UUID, not slug)").option("--label-field <uuid>", "TIMELINE label field (UUID, not slug)").option("--group-field <uuid>", "TIMELINE group field (UUID, not slug)").option("--subgroup-field <uuid>", "TIMELINE subgroup field (UUID, not slug)").option("--progress-field <uuid>", "TIMELINE progress field (UUID, not slug)").option("--card-title-field <uuid>", "KANBAN/TIMELINE card title field (UUID, not slug)").option("--card-category1-field <uuid>", "KANBAN/TIMELINE card category 1 field (UUID, not slug)").option("--card-category2-field <uuid>", "KANBAN/TIMELINE card category 2 field (UUID, not slug)").option("--card-category3-field <uuid>", "KANBAN card category 3 field (UUID, not slug)").option("--card-category4-field <uuid>", "TIMELINE card category 4 field (UUID, not slug)").option("--card-description-field <uuid>", "KANBAN/TIMELINE card description field (UUID, not slug)").option("--aggregation-method <method>", "KANBAN card aggregation method (e.g. sum)").option("--aggregation-field <uuid>", "KANBAN card aggregation field (UUID, not slug)").option("--view-state <json>", "KANBAN/TIMELINE viewState UI scalars (columnOrder, granularity, sidebarWidth, show* ...)").option("--view-state-file <path>", "read --view-state JSON from a file").option("--hierarchy-label <name>", "HIERARCHY label column name").option("--hierarchy-info <id:name>", "HIERARCHY info column; id is a unique opaque column id you choose (e.g. col_1779975207355_zfndknslw), not the name, and is reused as columnId in mappings (repeatable)", (v, p = []) => [...p, v], []).option("--hierarchy-number <id:name:aggregation>", "HIERARCHY number column; id is a unique opaque column id (e.g. col_1779975207355_zfndknslw), not the name; aggregation SUM|AVERAGE|MINIMUM|MAXIMUM|COUNT|COUNT_DISTINCT (repeatable)", (v, p = []) => [...p, v], []).option("--hierarchy-root-name <name>", "HIERARCHY root level name").option("--hierarchy-root-label-field <uuid>", "HIERARCHY root level label field (UUID, not slug)").option("--hierarchy-root-info <columnId:fieldId>", "HIERARCHY root info mapping; columnId must match a --hierarchy-info id (repeatable)", (v, p = []) => [...p, v], []).option("--hierarchy-root-number <columnId:fieldId>", "HIERARCHY root number mapping; columnId must match a --hierarchy-number id (repeatable)", (v, p = []) => [...p, v], []).option("--hierarchy-child <json>", "HIERARCHY child level JSON {name,schemaId,childFieldId,labelFieldId,infoMappings,numberMappings} (repeatable)", (v, p = []) => [...p, v], []).option("--hierarchy-config <json>", "HIERARCHY full hierarchyConfig JSON (escape hatch)").option("--hierarchy-config-file <path>", "read --hierarchy-config JSON from a file").option("--raw <json>").option("--raw-file <path>").action(async function action(display, widgetId, commandOptions) {
9082
9325
  const { api, json, readOnly } = createDisplaysApi(this, filePath);
9083
9326
  ensureWritable3("displays widgets update", readOnly, "write");
9084
9327
  const data = await api.updateWidget(display, widgetId, buildWidgetBody(commandOptions));