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.
- package/.claude/settings.local.json +8 -1
- package/README.md +73 -5
- package/dist/index.js +551 -99
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/api/automations.ts +1 -1
- package/src/api/displays.ts +48 -0
- package/src/api/navigation.ts +0 -1
- package/src/command-registry.ts +35 -0
- package/src/commands/automations.test.ts +32 -0
- package/src/commands/automations.ts +9 -3
- package/src/commands/displays.test.ts +311 -0
- package/src/commands/displays.ts +431 -7
- package/src/commands/navigation.test.ts +2 -5
- package/src/commands/navigation.ts +11 -11
- package/src/commands/teamspace.ts +19 -13
- package/src/utils/examples.test.ts +32 -4
- package/src/utils/examples.ts +208 -82
package/dist/index.js
CHANGED
|
@@ -275,6 +275,41 @@ var commandRegistry = {
|
|
|
275
275
|
supportsRaw: false,
|
|
276
276
|
output: writeOutput
|
|
277
277
|
},
|
|
278
|
+
"displays folders list": {
|
|
279
|
+
command: "displays folders list",
|
|
280
|
+
accessLevel: "read",
|
|
281
|
+
supportsExample: true,
|
|
282
|
+
supportsRaw: false,
|
|
283
|
+
output: readOutput
|
|
284
|
+
},
|
|
285
|
+
"displays folders create": {
|
|
286
|
+
command: "displays folders create",
|
|
287
|
+
accessLevel: "write",
|
|
288
|
+
supportsExample: true,
|
|
289
|
+
supportsRaw: false,
|
|
290
|
+
output: writeOutput
|
|
291
|
+
},
|
|
292
|
+
"displays folders update": {
|
|
293
|
+
command: "displays folders update",
|
|
294
|
+
accessLevel: "write",
|
|
295
|
+
supportsExample: true,
|
|
296
|
+
supportsRaw: false,
|
|
297
|
+
output: writeOutput
|
|
298
|
+
},
|
|
299
|
+
"displays folders delete": {
|
|
300
|
+
command: "displays folders delete",
|
|
301
|
+
accessLevel: "destructive",
|
|
302
|
+
supportsExample: true,
|
|
303
|
+
supportsRaw: false,
|
|
304
|
+
output: writeOutput
|
|
305
|
+
},
|
|
306
|
+
"displays folders move": {
|
|
307
|
+
command: "displays folders move",
|
|
308
|
+
accessLevel: "write",
|
|
309
|
+
supportsExample: true,
|
|
310
|
+
supportsRaw: false,
|
|
311
|
+
output: writeOutput
|
|
312
|
+
},
|
|
278
313
|
"displays layout get": {
|
|
279
314
|
command: "displays layout get",
|
|
280
315
|
accessLevel: "read",
|
|
@@ -2919,11 +2954,10 @@ var specificExamples = {
|
|
|
2919
2954
|
]),
|
|
2920
2955
|
"navigation resources move": buildCommandExamples([
|
|
2921
2956
|
{
|
|
2922
|
-
description: "Move a schema into a navigation folder.",
|
|
2923
|
-
command: "zinkee --json navigation resources move 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --
|
|
2957
|
+
description: "Move a schema into a navigation folder. Only schemas can be moved; the navigation menu holds databases.",
|
|
2958
|
+
command: "zinkee --json navigation resources move 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --to Sales",
|
|
2924
2959
|
raw: `{
|
|
2925
2960
|
"resourceId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
|
|
2926
|
-
"resourceType": "SCHEMA",
|
|
2927
2961
|
"targetFolderId": "84a0fca4-37ef-4c83-a8ed-9ef67ad9324a"
|
|
2928
2962
|
}`,
|
|
2929
2963
|
response: `{
|
|
@@ -2932,39 +2966,11 @@ var specificExamples = {
|
|
|
2932
2966
|
}`
|
|
2933
2967
|
},
|
|
2934
2968
|
{
|
|
2935
|
-
description: "Move a
|
|
2936
|
-
command: "zinkee --json navigation resources move
|
|
2937
|
-
raw: `{
|
|
2938
|
-
"resourceId": "3f8a2c1b-9d4e-4a5b-8c6d-7e8f90123456",
|
|
2939
|
-
"resourceType": "WORKFLOW",
|
|
2940
|
-
"targetFolderId": "b8c9d0e1-f2a3-4b5c-6d7e-8f9012345678"
|
|
2941
|
-
}`
|
|
2942
|
-
},
|
|
2943
|
-
{
|
|
2944
|
-
description: "Move a display.",
|
|
2945
|
-
command: "zinkee --json navigation resources move 0f6f062f-1478-4df2-96a1-c495d037d260 --type DISPLAY --to Operations",
|
|
2946
|
-
raw: `{
|
|
2947
|
-
"resourceId": "0f6f062f-1478-4df2-96a1-c495d037d260",
|
|
2948
|
-
"resourceType": "DISPLAY",
|
|
2949
|
-
"targetFolderId": "b8c9d0e1-f2a3-4b5c-6d7e-8f9012345678"
|
|
2950
|
-
}`
|
|
2951
|
-
},
|
|
2952
|
-
{
|
|
2953
|
-
description: "Move a resource back to the root folder (root is always UUID 00000000-0000-0000-0000-000000000000).",
|
|
2954
|
-
command: "zinkee --json navigation resources move 5223cbc8-8c6c-4694-93bc-dd176364df9b --type SCHEMA --to 00000000-0000-0000-0000-000000000000",
|
|
2969
|
+
description: "Move a schema back to the root folder (root is always UUID 00000000-0000-0000-0000-000000000000).",
|
|
2970
|
+
command: "zinkee --json navigation resources move 5223cbc8-8c6c-4694-93bc-dd176364df9b --to 00000000-0000-0000-0000-000000000000",
|
|
2955
2971
|
raw: `{
|
|
2956
2972
|
"resourceId": "5223cbc8-8c6c-4694-93bc-dd176364df9b",
|
|
2957
|
-
"resourceType": "SCHEMA",
|
|
2958
2973
|
"targetFolderId": "00000000-0000-0000-0000-000000000000"
|
|
2959
|
-
}`
|
|
2960
|
-
},
|
|
2961
|
-
{
|
|
2962
|
-
description: "Move a schedule resource.",
|
|
2963
|
-
command: "zinkee --json navigation resources move a1b2c3d4-e5f6-7890-1234-567890abcdef --type SCHEDULE --to Operations",
|
|
2964
|
-
raw: `{
|
|
2965
|
-
"resourceId": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
|
|
2966
|
-
"resourceType": "SCHEDULE",
|
|
2967
|
-
"targetFolderId": "b8c9d0e1-f2a3-4b5c-6d7e-8f9012345678"
|
|
2968
2974
|
}`
|
|
2969
2975
|
}
|
|
2970
2976
|
]),
|
|
@@ -3375,7 +3381,7 @@ var specificExamples = {
|
|
|
3375
3381
|
"displays widgets create": buildCommandExamples([
|
|
3376
3382
|
{
|
|
3377
3383
|
description: "Create a TABLE widget (CLI normalises --type table to TABLE_OR_SUBTABLE).",
|
|
3378
|
-
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
|
|
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"}'`,
|
|
3379
3385
|
raw: `{
|
|
3380
3386
|
"type": "TABLE_OR_SUBTABLE",
|
|
3381
3387
|
"source": {
|
|
@@ -3390,11 +3396,11 @@ var specificExamples = {
|
|
|
3390
3396
|
},
|
|
3391
3397
|
"query": {
|
|
3392
3398
|
"sorts": [
|
|
3393
|
-
{ "fieldId": "
|
|
3399
|
+
{ "fieldId": "contact-name", "direction": "ASC" }
|
|
3394
3400
|
]
|
|
3395
3401
|
},
|
|
3396
3402
|
"view": {
|
|
3397
|
-
"fields": ["
|
|
3403
|
+
"fields": ["contact-name", "status", "amount"]
|
|
3398
3404
|
}
|
|
3399
3405
|
}`,
|
|
3400
3406
|
response: `{
|
|
@@ -3474,7 +3480,7 @@ var specificExamples = {
|
|
|
3474
3480
|
},
|
|
3475
3481
|
{
|
|
3476
3482
|
description: "Create a bars CHART widget with a monthly time-serie x-axis and two y-axis series.",
|
|
3477
|
-
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":"
|
|
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"}'`,
|
|
3478
3484
|
raw: `{
|
|
3479
3485
|
"type": "CHART",
|
|
3480
3486
|
"source": {
|
|
@@ -3499,7 +3505,7 @@ var specificExamples = {
|
|
|
3499
3505
|
},
|
|
3500
3506
|
{
|
|
3501
3507
|
"typeCalc": "COUNT",
|
|
3502
|
-
"fieldCalc": "
|
|
3508
|
+
"fieldCalc": "contact-name",
|
|
3503
3509
|
"color": "#E57373",
|
|
3504
3510
|
"axisType": "SECONDARY"
|
|
3505
3511
|
}
|
|
@@ -3569,8 +3575,8 @@ var specificExamples = {
|
|
|
3569
3575
|
}`
|
|
3570
3576
|
},
|
|
3571
3577
|
{
|
|
3572
|
-
description: "Create a TIMELINE widget.",
|
|
3573
|
-
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
|
|
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}'`,
|
|
3574
3580
|
raw: `{
|
|
3575
3581
|
"type": "TIMELINE",
|
|
3576
3582
|
"source": {
|
|
@@ -3582,13 +3588,41 @@ var specificExamples = {
|
|
|
3582
3588
|
},
|
|
3583
3589
|
"presentation": { "name": "Customer schedule" },
|
|
3584
3590
|
"view": {
|
|
3585
|
-
"fields": [
|
|
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
|
+
}
|
|
3586
3620
|
}
|
|
3587
3621
|
}`
|
|
3588
3622
|
},
|
|
3589
3623
|
{
|
|
3590
|
-
description: "Create a KANBAN widget
|
|
3591
|
-
command: `zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --
|
|
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}'`,
|
|
3592
3626
|
raw: `{
|
|
3593
3627
|
"type": "KANBAN",
|
|
3594
3628
|
"source": {
|
|
@@ -3599,27 +3633,41 @@ var specificExamples = {
|
|
|
3599
3633
|
"layout": { "x": 0, "y": 0, "w": 12, "h": 8 }
|
|
3600
3634
|
},
|
|
3601
3635
|
"presentation": { "name": "Status board" },
|
|
3602
|
-
"query": {
|
|
3603
|
-
"filters": [
|
|
3604
|
-
{
|
|
3605
|
-
"origin": {
|
|
3606
|
-
"schemaId": "contacts",
|
|
3607
|
-
"fieldId": "status"
|
|
3608
|
-
},
|
|
3609
|
-
"comparisonOperator": "ANY_OF",
|
|
3610
|
-
"values": ["1", "2", "3"]
|
|
3611
|
-
}
|
|
3612
|
-
]
|
|
3613
|
-
},
|
|
3614
3636
|
"view": {
|
|
3615
|
-
"fields": [
|
|
3616
|
-
|
|
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
|
+
}
|
|
3617
3665
|
}
|
|
3618
3666
|
}`
|
|
3619
3667
|
},
|
|
3620
3668
|
{
|
|
3621
|
-
description: "Create a HIERARCHY widget
|
|
3622
|
-
command: `zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --
|
|
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"}]}'`,
|
|
3623
3671
|
raw: `{
|
|
3624
3672
|
"type": "HIERARCHY",
|
|
3625
3673
|
"source": {
|
|
@@ -3631,9 +3679,46 @@ var specificExamples = {
|
|
|
3631
3679
|
},
|
|
3632
3680
|
"presentation": { "name": "Org tree" },
|
|
3633
3681
|
"view": {
|
|
3634
|
-
"fields": [
|
|
3682
|
+
"fields": [
|
|
3683
|
+
"c60b8526-5835-4c9f-aecd-9a16c7704a34",
|
|
3684
|
+
"a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
|
|
3685
|
+
"c52efe3f-2825-4c60-a7e3-34dd4c1ce043"
|
|
3686
|
+
],
|
|
3635
3687
|
"hierarchyConfig": {
|
|
3636
|
-
"
|
|
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
|
+
]
|
|
3637
3722
|
}
|
|
3638
3723
|
}
|
|
3639
3724
|
}`
|
|
@@ -3642,13 +3727,13 @@ var specificExamples = {
|
|
|
3642
3727
|
"displays widgets update": buildCommandExamples([
|
|
3643
3728
|
{
|
|
3644
3729
|
description: "Move placement, update view columns, rename the widget and lock it.",
|
|
3645
|
-
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
|
|
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`,
|
|
3646
3731
|
raw: `{
|
|
3647
3732
|
"placement": {
|
|
3648
3733
|
"layout": { "x": 1, "y": 2, "w": 8, "h": 4 }
|
|
3649
3734
|
},
|
|
3650
3735
|
"view": {
|
|
3651
|
-
"fields": ["
|
|
3736
|
+
"fields": ["contact-name", "status", "amount"]
|
|
3652
3737
|
},
|
|
3653
3738
|
"presentation": { "name": "Revenue Updated" },
|
|
3654
3739
|
"behavior": { "readOnly": true }
|
|
@@ -4453,7 +4538,7 @@ var specificExamples = {
|
|
|
4453
4538
|
"resources": [
|
|
4454
4539
|
{
|
|
4455
4540
|
"id": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
|
|
4456
|
-
"name": "
|
|
4541
|
+
"name": "Customer records",
|
|
4457
4542
|
"type": "SCHEMA",
|
|
4458
4543
|
"isInSpace": false,
|
|
4459
4544
|
"additionalProperties": {}
|
|
@@ -4477,19 +4562,10 @@ var specificExamples = {
|
|
|
4477
4562
|
"resources": [
|
|
4478
4563
|
{
|
|
4479
4564
|
"id": "3f8a2c1b-9d4e-4a5b-8c6d-7e8f90123456",
|
|
4480
|
-
"name": "
|
|
4481
|
-
"type": "
|
|
4565
|
+
"name": "Shipments",
|
|
4566
|
+
"type": "SCHEMA",
|
|
4482
4567
|
"isInSpace": false,
|
|
4483
4568
|
"additionalProperties": {}
|
|
4484
|
-
},
|
|
4485
|
-
{
|
|
4486
|
-
"id": "0f6f062f-1478-4df2-96a1-c495d037d260",
|
|
4487
|
-
"name": "Executive Revenue",
|
|
4488
|
-
"type": "DISPLAY",
|
|
4489
|
-
"isInSpace": true,
|
|
4490
|
-
"additionalProperties": {
|
|
4491
|
-
"pinned": true
|
|
4492
|
-
}
|
|
4493
4569
|
}
|
|
4494
4570
|
],
|
|
4495
4571
|
"additionalProperties": {
|
|
@@ -4536,8 +4612,13 @@ var specificExamples = {
|
|
|
4536
4612
|
"name": "Shared Dashboards",
|
|
4537
4613
|
"order": 1,
|
|
4538
4614
|
"isRoot": false,
|
|
4539
|
-
"resourceCount":
|
|
4615
|
+
"resourceCount": 2,
|
|
4540
4616
|
"resources": [
|
|
4617
|
+
{
|
|
4618
|
+
"id": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
|
|
4619
|
+
"name": "Customer records",
|
|
4620
|
+
"type": "SCHEMA"
|
|
4621
|
+
},
|
|
4541
4622
|
{
|
|
4542
4623
|
"id": "0f6f062f-1478-4df2-96a1-c495d037d260",
|
|
4543
4624
|
"name": "Executive Revenue",
|
|
@@ -4709,7 +4790,7 @@ var specificExamples = {
|
|
|
4709
4790
|
"hideDeleteButton": false
|
|
4710
4791
|
},
|
|
4711
4792
|
"view": {
|
|
4712
|
-
"fields": ["
|
|
4793
|
+
"fields": ["contact-name", "status", "amount"],
|
|
4713
4794
|
"columnSize": { "contact-name": 240 }
|
|
4714
4795
|
}
|
|
4715
4796
|
}
|
|
@@ -4756,6 +4837,83 @@ var specificExamples = {
|
|
|
4756
4837
|
command: "zinkee --json displays delete 0f6f062f-1478-4df2-96a1-c495d037d260"
|
|
4757
4838
|
}
|
|
4758
4839
|
]),
|
|
4840
|
+
"displays folders list": buildCommandExamples([
|
|
4841
|
+
{
|
|
4842
|
+
description: "List flat display folders (non-root folders plus the root bucket).",
|
|
4843
|
+
command: "zinkee --json displays folders list",
|
|
4844
|
+
response: `[
|
|
4845
|
+
{
|
|
4846
|
+
"id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
|
|
4847
|
+
"name": "Executive Dashboards",
|
|
4848
|
+
"isRoot": false,
|
|
4849
|
+
"displayCount": 2
|
|
4850
|
+
},
|
|
4851
|
+
{
|
|
4852
|
+
"id": "8b22282b-3db3-4dd7-87f7-b29365dcf3f6",
|
|
4853
|
+
"name": null,
|
|
4854
|
+
"isRoot": true,
|
|
4855
|
+
"displayCount": 4
|
|
4856
|
+
}
|
|
4857
|
+
]`
|
|
4858
|
+
}
|
|
4859
|
+
]),
|
|
4860
|
+
"displays folders create": buildCommandExamples([
|
|
4861
|
+
{
|
|
4862
|
+
description: "Create one flat display folder.",
|
|
4863
|
+
command: 'zinkee --json displays folders create --name "Executive Dashboards"',
|
|
4864
|
+
raw: `{
|
|
4865
|
+
"name": "Executive Dashboards"
|
|
4866
|
+
}`,
|
|
4867
|
+
response: `{
|
|
4868
|
+
"id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
|
|
4869
|
+
"name": "Executive Dashboards",
|
|
4870
|
+
"isRoot": false,
|
|
4871
|
+
"displayCount": 0
|
|
4872
|
+
}`
|
|
4873
|
+
}
|
|
4874
|
+
]),
|
|
4875
|
+
"displays folders update": buildCommandExamples([
|
|
4876
|
+
{
|
|
4877
|
+
description: "Rename a display folder. The folder argument accepts a UUID or an exact name.",
|
|
4878
|
+
command: 'zinkee --json displays folders update "Executive Dashboards" --name "Executive Dashboards (2026)"',
|
|
4879
|
+
raw: `{
|
|
4880
|
+
"name": "Executive Dashboards (2026)"
|
|
4881
|
+
}`,
|
|
4882
|
+
response: `{
|
|
4883
|
+
"id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
|
|
4884
|
+
"name": "Executive Dashboards (2026)",
|
|
4885
|
+
"isRoot": false,
|
|
4886
|
+
"displayCount": 2
|
|
4887
|
+
}`
|
|
4888
|
+
}
|
|
4889
|
+
]),
|
|
4890
|
+
"displays folders delete": buildCommandExamples([
|
|
4891
|
+
{
|
|
4892
|
+
description: "Delete a non-root display folder. Its displays move back to the root folder.",
|
|
4893
|
+
command: 'zinkee --json displays folders delete "Executive Dashboards"',
|
|
4894
|
+
response: `{
|
|
4895
|
+
"id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
|
|
4896
|
+
"name": "Executive Dashboards",
|
|
4897
|
+
"isRoot": false,
|
|
4898
|
+
"displayCount": 2
|
|
4899
|
+
}`
|
|
4900
|
+
}
|
|
4901
|
+
]),
|
|
4902
|
+
"displays folders move": buildCommandExamples([
|
|
4903
|
+
{
|
|
4904
|
+
description: "Move one display into a target folder by exact folder name.",
|
|
4905
|
+
command: 'zinkee --json displays folders move 0f6f062f-1478-4df2-96a1-c495d037d260 --to "Executive Dashboards"',
|
|
4906
|
+
raw: `{
|
|
4907
|
+
"displayId": "0f6f062f-1478-4df2-96a1-c495d037d260",
|
|
4908
|
+
"targetFolderId": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e"
|
|
4909
|
+
}`,
|
|
4910
|
+
response: `{
|
|
4911
|
+
"id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
|
|
4912
|
+
"name": "Executive Dashboards",
|
|
4913
|
+
"isRoot": false
|
|
4914
|
+
}`
|
|
4915
|
+
}
|
|
4916
|
+
]),
|
|
4759
4917
|
"displays layout get": buildCommandExamples([
|
|
4760
4918
|
{
|
|
4761
4919
|
description: "Get the layout block of a display (template + tabs/freeformLayouts/slots).",
|
|
@@ -4849,7 +5007,7 @@ var specificExamples = {
|
|
|
4849
5007
|
"hideDeleteButton": false
|
|
4850
5008
|
},
|
|
4851
5009
|
"view": {
|
|
4852
|
-
"fields": ["
|
|
5010
|
+
"fields": ["contact-name", "status", "amount"],
|
|
4853
5011
|
"columnSize": { "contact-name": 240 }
|
|
4854
5012
|
}
|
|
4855
5013
|
}`
|
|
@@ -5769,7 +5927,8 @@ var specificExamples = {
|
|
|
5769
5927
|
description: "Move one automation into a target folder by exact folder name.",
|
|
5770
5928
|
command: 'zinkee --json automations folders move automation-1 --to "Codex Frontend Demo"',
|
|
5771
5929
|
raw: `{
|
|
5772
|
-
"automationId": "automation-1"
|
|
5930
|
+
"automationId": "automation-1",
|
|
5931
|
+
"targetFolderId": "cdfc14e3-3169-4ffb-8d9b-b11858a9240f"
|
|
5773
5932
|
}`,
|
|
5774
5933
|
response: `{
|
|
5775
5934
|
"id": "cdfc14e3-3169-4ffb-8d9b-b11858a9240f",
|
|
@@ -6415,7 +6574,7 @@ var AutomationsApi = class {
|
|
|
6415
6574
|
}
|
|
6416
6575
|
moveAutomation(input) {
|
|
6417
6576
|
return this.client.requestJson(
|
|
6418
|
-
|
|
6577
|
+
"/api/v2/automation-folders/automations:move",
|
|
6419
6578
|
jsonOptions(input, "POST")
|
|
6420
6579
|
);
|
|
6421
6580
|
}
|
|
@@ -7560,8 +7719,8 @@ function registerAutomationsCommands(program, options = {}) {
|
|
|
7560
7719
|
const filePath = options.configPath ?? defaultConfigPath;
|
|
7561
7720
|
const stdout = getCommandIo2(options.stdout);
|
|
7562
7721
|
const automations = program.command("automations").description("Manage automations, triggers, actions, and connections");
|
|
7563
|
-
const folders = automations.command("folders").description("Manage automation folders");
|
|
7564
|
-
folders.command("list").description("List automation folders").action(async function action() {
|
|
7722
|
+
const folders = automations.command("folders").description("Manage automation folders (flat: a folder only has a name, no order or properties)");
|
|
7723
|
+
folders.command("list").description("List automation folders (non-root folders plus the root bucket, whose name is null)").action(async function action() {
|
|
7565
7724
|
const { api, json } = createAutomationsApi(this, filePath);
|
|
7566
7725
|
const data = await api.listFolders();
|
|
7567
7726
|
if (json) {
|
|
@@ -7611,7 +7770,11 @@ function registerAutomationsCommands(program, options = {}) {
|
|
|
7611
7770
|
}
|
|
7612
7771
|
writeLine2(stdout, `Deleted automation folder "${folder.value}".`);
|
|
7613
7772
|
});
|
|
7614
|
-
folders.command("move").description("Move an automation into a folder").argument("<automation>", "automation UUID", parseUuidOrSlugSelector).requiredOption(
|
|
7773
|
+
folders.command("move").description("Move an automation into a folder").argument("<automation>", "automation UUID", parseUuidOrSlugSelector).requiredOption(
|
|
7774
|
+
"--to <folder>",
|
|
7775
|
+
"target folder UUID or exact name (use the root folder to move it out of any folder)",
|
|
7776
|
+
parseUuidOrSlugSelector
|
|
7777
|
+
).action(async function action(automation, commandOptions) {
|
|
7615
7778
|
const { api, json, readOnly } = createAutomationsApi(this, filePath);
|
|
7616
7779
|
ensureWritable("automations folders move", readOnly, "write");
|
|
7617
7780
|
if (!commandOptions.to) {
|
|
@@ -8296,6 +8459,33 @@ var DisplaysApi = class {
|
|
|
8296
8459
|
{ method: "DELETE" }
|
|
8297
8460
|
);
|
|
8298
8461
|
}
|
|
8462
|
+
listFolders() {
|
|
8463
|
+
return this.client.getJson("/api/v2/display-folders");
|
|
8464
|
+
}
|
|
8465
|
+
createFolder(body) {
|
|
8466
|
+
return this.client.requestJson(
|
|
8467
|
+
"/api/v2/display-folders",
|
|
8468
|
+
jsonOptions3(body, "POST")
|
|
8469
|
+
);
|
|
8470
|
+
}
|
|
8471
|
+
updateFolder(folder, body) {
|
|
8472
|
+
return this.client.requestJson(
|
|
8473
|
+
`/api/v2/display-folders/${selectorValue3(folder)}`,
|
|
8474
|
+
jsonOptions3(body, "PATCH")
|
|
8475
|
+
);
|
|
8476
|
+
}
|
|
8477
|
+
deleteFolder(folder) {
|
|
8478
|
+
return this.client.requestJson(
|
|
8479
|
+
`/api/v2/display-folders/${selectorValue3(folder)}`,
|
|
8480
|
+
{ method: "DELETE" }
|
|
8481
|
+
);
|
|
8482
|
+
}
|
|
8483
|
+
moveDisplay(input) {
|
|
8484
|
+
return this.client.requestJson(
|
|
8485
|
+
"/api/v2/display-folders/displays:move",
|
|
8486
|
+
jsonOptions3(input, "POST")
|
|
8487
|
+
);
|
|
8488
|
+
}
|
|
8299
8489
|
};
|
|
8300
8490
|
|
|
8301
8491
|
// src/parsers/expressions.ts
|
|
@@ -8508,6 +8698,150 @@ function readNamedJsonOption(raw, rawFile, inlineFlag = "--option", fileFlag = "
|
|
|
8508
8698
|
function isEmptyObject3(value) {
|
|
8509
8699
|
return Object.keys(value).length === 0;
|
|
8510
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
|
+
}
|
|
8511
8845
|
function displayRows(displays) {
|
|
8512
8846
|
return displays.map((display) => ({
|
|
8513
8847
|
id: display.id,
|
|
@@ -8523,6 +8857,31 @@ function getDisplaySubresource(value) {
|
|
|
8523
8857
|
}
|
|
8524
8858
|
return value.filter((entry) => Boolean(entry) && typeof entry === "object");
|
|
8525
8859
|
}
|
|
8860
|
+
function displayFolderRows(folders) {
|
|
8861
|
+
return folders.map((folder) => ({
|
|
8862
|
+
id: folder.id ?? "",
|
|
8863
|
+
name: folder.name ?? "",
|
|
8864
|
+
isRoot: folder.isRoot ?? "",
|
|
8865
|
+
displayCount: folder.displayCount ?? ""
|
|
8866
|
+
}));
|
|
8867
|
+
}
|
|
8868
|
+
async function resolveDisplayFolderId(api, selector) {
|
|
8869
|
+
if (selector.kind === "uuid") {
|
|
8870
|
+
return selector.value;
|
|
8871
|
+
}
|
|
8872
|
+
const folders = await api.listFolders();
|
|
8873
|
+
const matches = folders.filter((folder) => folder.name === selector.value);
|
|
8874
|
+
if (matches.length === 1 && typeof matches[0]?.id === "string" && matches[0].id.length > 0) {
|
|
8875
|
+
return matches[0].id;
|
|
8876
|
+
}
|
|
8877
|
+
if (matches.length > 1) {
|
|
8878
|
+
throw new CliError(
|
|
8879
|
+
"invalid_cli_usage",
|
|
8880
|
+
`Folder "${selector.value}" is ambiguous. Found ${matches.length} matches.`
|
|
8881
|
+
);
|
|
8882
|
+
}
|
|
8883
|
+
throw new CliError("invalid_cli_usage", `Folder "${selector.value}" was not found.`);
|
|
8884
|
+
}
|
|
8526
8885
|
function buildVariableBody(options) {
|
|
8527
8886
|
const body = {
|
|
8528
8887
|
...readRawObject2(options.raw, options.rawFile)
|
|
@@ -8589,11 +8948,31 @@ function buildWidgetBody(options) {
|
|
|
8589
8948
|
layout
|
|
8590
8949
|
};
|
|
8591
8950
|
}
|
|
8951
|
+
const viewPatch = {};
|
|
8592
8952
|
if (options.field && options.field.length > 0) {
|
|
8593
|
-
|
|
8594
|
-
|
|
8595
|
-
|
|
8596
|
-
|
|
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);
|
|
8597
8976
|
}
|
|
8598
8977
|
const queryMerge = {};
|
|
8599
8978
|
if (options.sort && options.sort.length > 0) queryMerge.sorts = options.sort;
|
|
@@ -8728,6 +9107,72 @@ function registerDisplaysCommands(program, options = {}) {
|
|
|
8728
9107
|
}
|
|
8729
9108
|
writeLine4(stdout, `Deleted display "${display.value}".`);
|
|
8730
9109
|
});
|
|
9110
|
+
const folders = displays.command("folders").description("Manage display folders (flat: a folder only has a name, no order or properties)");
|
|
9111
|
+
folders.command("list").description("List display folders (non-root folders plus the root bucket, whose name is null)").action(async function action() {
|
|
9112
|
+
const { api, json } = createDisplaysApi(this, filePath);
|
|
9113
|
+
const data = await api.listFolders();
|
|
9114
|
+
if (json) {
|
|
9115
|
+
emitJson4(stdout, "displays folders list", data);
|
|
9116
|
+
return;
|
|
9117
|
+
}
|
|
9118
|
+
printTable(displayFolderRows(data), ["id", "name", "isRoot", "displayCount"], stdout);
|
|
9119
|
+
});
|
|
9120
|
+
folders.command("create").description("Create a display folder").requiredOption("--name <name>", "folder name").action(async function action(commandOptions) {
|
|
9121
|
+
const { api, json, readOnly } = createDisplaysApi(this, filePath);
|
|
9122
|
+
ensureWritable3("displays folders create", readOnly, "write");
|
|
9123
|
+
if (commandOptions.name === void 0) {
|
|
9124
|
+
throw new CliError("invalid_cli_usage", 'Provide folder name via "--name".');
|
|
9125
|
+
}
|
|
9126
|
+
const data = await api.createFolder({ name: commandOptions.name });
|
|
9127
|
+
if (json) {
|
|
9128
|
+
emitJson4(stdout, "displays folders create", data);
|
|
9129
|
+
return;
|
|
9130
|
+
}
|
|
9131
|
+
writeLine4(stdout, `Created display folder "${String(data.name ?? commandOptions.name)}".`);
|
|
9132
|
+
});
|
|
9133
|
+
folders.command("update").description("Rename a display folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector3).requiredOption("--name <name>", "folder name").action(async function action(folder, commandOptions) {
|
|
9134
|
+
const { api, json, readOnly } = createDisplaysApi(this, filePath);
|
|
9135
|
+
ensureWritable3("displays folders update", readOnly, "write");
|
|
9136
|
+
if (commandOptions.name === void 0) {
|
|
9137
|
+
throw new CliError("invalid_cli_usage", 'Provide folder name via "--name".');
|
|
9138
|
+
}
|
|
9139
|
+
const folderId = await resolveDisplayFolderId(api, folder);
|
|
9140
|
+
const data = await api.updateFolder({ kind: "uuid", value: folderId }, { name: commandOptions.name });
|
|
9141
|
+
if (json) {
|
|
9142
|
+
emitJson4(stdout, "displays folders update", data);
|
|
9143
|
+
return;
|
|
9144
|
+
}
|
|
9145
|
+
writeLine4(stdout, `Updated display folder "${String(data.name ?? folder.value)}".`);
|
|
9146
|
+
});
|
|
9147
|
+
folders.command("delete").description("Delete a display folder (its displays move back to the root folder)").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector3).action(async function action(folder) {
|
|
9148
|
+
const { api, json, readOnly } = createDisplaysApi(this, filePath);
|
|
9149
|
+
ensureWritable3("displays folders delete", readOnly, "destructive");
|
|
9150
|
+
const folderId = await resolveDisplayFolderId(api, folder);
|
|
9151
|
+
const data = await api.deleteFolder({ kind: "uuid", value: folderId });
|
|
9152
|
+
if (json) {
|
|
9153
|
+
emitJson4(stdout, "displays folders delete", data);
|
|
9154
|
+
return;
|
|
9155
|
+
}
|
|
9156
|
+
writeLine4(stdout, `Deleted display folder "${folder.value}".`);
|
|
9157
|
+
});
|
|
9158
|
+
folders.command("move").description("Move a display into a folder").argument("<display>", "display UUID", parseUuidOrSlugSelector3).requiredOption(
|
|
9159
|
+
"--to <folder>",
|
|
9160
|
+
"target folder UUID or exact name (use the root folder to move it out of any folder)",
|
|
9161
|
+
parseUuidOrSlugSelector3
|
|
9162
|
+
).action(async function action(display, commandOptions) {
|
|
9163
|
+
const { api, json, readOnly } = createDisplaysApi(this, filePath);
|
|
9164
|
+
ensureWritable3("displays folders move", readOnly, "write");
|
|
9165
|
+
if (!commandOptions.to) {
|
|
9166
|
+
throw new CliError("invalid_cli_usage", 'Provide target folder via "--to".');
|
|
9167
|
+
}
|
|
9168
|
+
const targetFolderId = await resolveDisplayFolderId(api, commandOptions.to);
|
|
9169
|
+
const data = await api.moveDisplay({ displayId: display.value, targetFolderId });
|
|
9170
|
+
if (json) {
|
|
9171
|
+
emitJson4(stdout, "displays folders move", data);
|
|
9172
|
+
return;
|
|
9173
|
+
}
|
|
9174
|
+
writeLine4(stdout, `Moved display "${display.value}" to folder "${targetFolderId}".`);
|
|
9175
|
+
});
|
|
8731
9176
|
const layout = displays.command("layout").description("Manage display layout");
|
|
8732
9177
|
layout.command("get").description("Get display layout").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).action(async function action(display) {
|
|
8733
9178
|
const { api, json } = createDisplaysApi(this, filePath);
|
|
@@ -8866,7 +9311,7 @@ function registerDisplaysCommands(program, options = {}) {
|
|
|
8866
9311
|
}
|
|
8867
9312
|
printTable([data], void 0, stdout);
|
|
8868
9313
|
});
|
|
8869
|
-
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) {
|
|
8870
9315
|
const { api, json, readOnly } = createDisplaysApi(this, filePath);
|
|
8871
9316
|
ensureWritable3("displays widgets create", readOnly, "write");
|
|
8872
9317
|
const data = await api.createWidget(display, buildWidgetBody(commandOptions));
|
|
@@ -8876,7 +9321,7 @@ function registerDisplaysCommands(program, options = {}) {
|
|
|
8876
9321
|
}
|
|
8877
9322
|
writeLine4(stdout, `Created widget on display "${display.value}".`);
|
|
8878
9323
|
});
|
|
8879
|
-
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) {
|
|
8880
9325
|
const { api, json, readOnly } = createDisplaysApi(this, filePath);
|
|
8881
9326
|
ensureWritable3("displays widgets update", readOnly, "write");
|
|
8882
9327
|
const data = await api.updateWidget(display, widgetId, buildWidgetBody(commandOptions));
|
|
@@ -9901,7 +10346,7 @@ function registerNavigationCommands(program, options = {}) {
|
|
|
9901
10346
|
}
|
|
9902
10347
|
printTable(folderRows2([resolved]), ["id", "order", "name", "resourceCount"], stdout);
|
|
9903
10348
|
});
|
|
9904
|
-
folders.command("create").description("Create a navigation folder").requiredOption("--name <name>", "folder name").option("--order <n>", "
|
|
10349
|
+
folders.command("create").description("Create a navigation folder").requiredOption("--name <name>", "folder name").option("--order <n>", "display order (lower values appear first)").option("--props <json>", 'additionalProperties JSON: free-form client metadata, e.g. {"color":"blue","icon":"chart-line"}').option("--props-file <path>", "path to a file with the additionalProperties JSON").action(async function action(commandOptions) {
|
|
9905
10350
|
const { api, json, readOnly } = createNavigationApi(this, filePath);
|
|
9906
10351
|
ensureWritable6("navigation folders create", readOnly, "write");
|
|
9907
10352
|
const data = await api.createFolder(buildFolderBody(commandOptions));
|
|
@@ -9911,7 +10356,7 @@ function registerNavigationCommands(program, options = {}) {
|
|
|
9911
10356
|
}
|
|
9912
10357
|
writeLine8(stdout, `Created navigation folder "${String(data.name ?? commandOptions.name)}".`);
|
|
9913
10358
|
});
|
|
9914
|
-
folders.command("update").description("Update a navigation folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector7).option("--name <name>", "folder name").option("--order <n>", "
|
|
10359
|
+
folders.command("update").description("Update a navigation folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector7).option("--name <name>", "folder name").option("--order <n>", "display order (lower values appear first)").option("--props <json>", 'additionalProperties JSON: free-form client metadata, e.g. {"color":"blue","icon":"chart-line"}').option("--props-file <path>", "path to a file with the additionalProperties JSON").action(async function action(folder, commandOptions) {
|
|
9915
10360
|
const { api, json, readOnly } = createNavigationApi(this, filePath);
|
|
9916
10361
|
ensureWritable6("navigation folders update", readOnly, "write");
|
|
9917
10362
|
const allFolders = await api.listFolders();
|
|
@@ -9939,14 +10384,15 @@ function registerNavigationCommands(program, options = {}) {
|
|
|
9939
10384
|
}
|
|
9940
10385
|
writeLine8(stdout, `Deleted navigation folder "${resolved.name ?? resolved.id}".`);
|
|
9941
10386
|
});
|
|
9942
|
-
navigation.command("resources").description("Manage navigation resources").command("move").description(
|
|
10387
|
+
navigation.command("resources").description("Manage navigation resources").command("move").description(
|
|
10388
|
+
"Move a schema into a navigation folder. Only schemas can be moved (the navigation menu holds databases); schedules and sub-schemas follow their parent schema. Use the root folder UUID 00000000-0000-0000-0000-000000000000 to move it back to the workspace root."
|
|
10389
|
+
).argument("<resource>", "schema UUID").requiredOption("--to <folder>", "target folder UUID or exact name").action(async function action(resourceId, commandOptions) {
|
|
9943
10390
|
const { api, json, readOnly } = createNavigationApi(this, filePath);
|
|
9944
10391
|
ensureWritable6("navigation resources move", readOnly, "write");
|
|
9945
10392
|
const allFolders = await api.listFolders();
|
|
9946
10393
|
const resolved = resolveFolder2(allFolders, parseUuidOrSlugSelector7(commandOptions.to));
|
|
9947
10394
|
const data = await api.moveResource({
|
|
9948
10395
|
resourceId,
|
|
9949
|
-
resourceType: commandOptions.type.toUpperCase(),
|
|
9950
10396
|
targetFolderId: resolved.id
|
|
9951
10397
|
});
|
|
9952
10398
|
if (json) {
|
|
@@ -11479,7 +11925,7 @@ function registerTeamspaceCommands(program, options = {}) {
|
|
|
11479
11925
|
const stdout = getCommandIo12(options.stdout);
|
|
11480
11926
|
const teamspace = program.command("teamspace").description("Manage teamspace folders and resources");
|
|
11481
11927
|
const folders = teamspace.command("folders").description("Manage teamspace folders");
|
|
11482
|
-
folders.command("list").description("List teamspace folders").option("--include-resources", "include
|
|
11928
|
+
folders.command("list").description("List teamspace folders").option("--include-resources", "include the published resources inside each folder").action(async function action(commandOptions) {
|
|
11483
11929
|
const { api, json } = createTeamspaceApi(this, filePath);
|
|
11484
11930
|
const data = await api.listFolders(Boolean(commandOptions.includeResources));
|
|
11485
11931
|
if (json) {
|
|
@@ -11488,7 +11934,7 @@ function registerTeamspaceCommands(program, options = {}) {
|
|
|
11488
11934
|
}
|
|
11489
11935
|
emitTable5(stdout, data);
|
|
11490
11936
|
});
|
|
11491
|
-
folders.command("get").description("Get a teamspace folder by exact name or UUID").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector10).option("--include-resources", "include
|
|
11937
|
+
folders.command("get").description("Get a teamspace folder by exact name or UUID").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector10).option("--include-resources", "include the published resources inside each folder").action(async function action(folder, commandOptions) {
|
|
11492
11938
|
const { api, json } = createTeamspaceApi(this, filePath);
|
|
11493
11939
|
const resolvedFolder = await resolveFolderSelector2(api, folder);
|
|
11494
11940
|
const allFolders = await api.listFolders(Boolean(commandOptions.includeResources));
|
|
@@ -11499,7 +11945,7 @@ function registerTeamspaceCommands(program, options = {}) {
|
|
|
11499
11945
|
}
|
|
11500
11946
|
emitTable5(stdout, data);
|
|
11501
11947
|
});
|
|
11502
|
-
folders.command("create").description("Create a teamspace folder").requiredOption("--name <name>", "folder name").option("--order <n>", "
|
|
11948
|
+
folders.command("create").description("Create a teamspace folder").requiredOption("--name <name>", "folder name").option("--order <n>", "display order (lower values appear first)", parseNonNegativeInteger3).option("--props <json>", 'additionalProperties JSON: free-form client metadata, e.g. {"icon":"folder-users","color":"gold"}').option("--props-file <path>", "path to a file with the additionalProperties JSON").action(async function action(commandOptions) {
|
|
11503
11949
|
const { api, json, readOnly } = createTeamspaceApi(this, filePath);
|
|
11504
11950
|
ensureWritable9("teamspace folders create", readOnly, "write");
|
|
11505
11951
|
const data = await api.createFolder(buildFolderCreateInput(commandOptions));
|
|
@@ -11509,7 +11955,7 @@ function registerTeamspaceCommands(program, options = {}) {
|
|
|
11509
11955
|
}
|
|
11510
11956
|
writeLine12(stdout, `Created folder "${getFolderIdentifier(data)}".`);
|
|
11511
11957
|
});
|
|
11512
|
-
folders.command("update").description("Update a teamspace folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector10).option("--name <name>", "folder name").option("--order <n>", "
|
|
11958
|
+
folders.command("update").description("Update a teamspace folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector10).option("--name <name>", "folder name").option("--order <n>", "display order (lower values appear first)", parseNonNegativeInteger3).option("--props <json>", 'additionalProperties JSON: free-form client metadata, e.g. {"icon":"folder-users","color":"gold"}').option("--props-file <path>", "path to a file with the additionalProperties JSON").action(async function action(folder, commandOptions) {
|
|
11513
11959
|
const { api, json, readOnly } = createTeamspaceApi(this, filePath);
|
|
11514
11960
|
ensureWritable9("teamspace folders update", readOnly, "write");
|
|
11515
11961
|
const resolvedFolder = await resolveFolderSelector2(api, folder);
|
|
@@ -11532,7 +11978,13 @@ function registerTeamspaceCommands(program, options = {}) {
|
|
|
11532
11978
|
writeLine12(stdout, `Deleted folder "${resolvedFolder.value}".`);
|
|
11533
11979
|
});
|
|
11534
11980
|
const resources = teamspace.command("resources").description("Manage teamspace resources");
|
|
11535
|
-
resources.command("publish").description(
|
|
11981
|
+
resources.command("publish").description(
|
|
11982
|
+
"Publish a resource to a teamspace folder. Publishing an already-published resource moves it to the new folder."
|
|
11983
|
+
).argument("<resource>", "schema UUID, schema slug, or display UUID", parseUuidOrSlugSelector10).requiredOption(
|
|
11984
|
+
"--to <folder>",
|
|
11985
|
+
"target folder UUID or exact name (root folder UUID is 00000000-0000-0000-0000-000000000000)",
|
|
11986
|
+
parseUuidOrSlugSelector10
|
|
11987
|
+
).action(async function action(resource, commandOptions) {
|
|
11536
11988
|
const { api, json, readOnly } = createTeamspaceApi(this, filePath);
|
|
11537
11989
|
ensureWritable9("teamspace resources publish", readOnly, "write");
|
|
11538
11990
|
const folder = await resolveFolderSelector2(api, commandOptions.to);
|
|
@@ -11546,7 +11998,7 @@ function registerTeamspaceCommands(program, options = {}) {
|
|
|
11546
11998
|
}
|
|
11547
11999
|
writeLine12(stdout, `Published resource "${resource.value}" to folder "${folder.value}".`);
|
|
11548
12000
|
});
|
|
11549
|
-
resources.command("unpublish").description("Unpublish a resource from teamspace").argument("<resource>", "
|
|
12001
|
+
resources.command("unpublish").description("Unpublish a resource from teamspace (removes it from its shared folder)").argument("<resource>", "schema UUID, schema slug, or display UUID", parseUuidOrSlugSelector10).action(async function action(resource) {
|
|
11550
12002
|
const { api, json, readOnly } = createTeamspaceApi(this, filePath);
|
|
11551
12003
|
ensureWritable9("teamspace resources unpublish", readOnly, "write");
|
|
11552
12004
|
const data = await api.unpublishResource(resource.value);
|