zinkee 0.1.35 → 0.1.36

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/dist/index.js CHANGED
@@ -275,41 +275,6 @@ 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
- },
313
278
  "displays layout get": {
314
279
  command: "displays layout get",
315
280
  accessLevel: "read",
@@ -471,62 +436,6 @@ var commandRegistry = {
471
436
  supportsRaw: false,
472
437
  output: writeOutput
473
438
  },
474
- "document-templates list": {
475
- command: "document-templates list",
476
- accessLevel: "read",
477
- supportsExample: true,
478
- supportsRaw: false,
479
- output: readOutput
480
- },
481
- "document-templates get": {
482
- command: "document-templates get",
483
- accessLevel: "read",
484
- supportsExample: true,
485
- supportsRaw: false,
486
- output: readOutput
487
- },
488
- "document-templates create": {
489
- command: "document-templates create",
490
- accessLevel: "write",
491
- supportsExample: true,
492
- supportsRaw: true,
493
- output: writeOutput
494
- },
495
- "document-templates update": {
496
- command: "document-templates update",
497
- accessLevel: "write",
498
- supportsExample: true,
499
- supportsRaw: false,
500
- output: writeOutput
501
- },
502
- "document-templates delete": {
503
- command: "document-templates delete",
504
- accessLevel: "destructive",
505
- supportsExample: true,
506
- supportsRaw: false,
507
- output: writeOutput
508
- },
509
- "document-templates assets add": {
510
- command: "document-templates assets add",
511
- accessLevel: "write",
512
- supportsExample: true,
513
- supportsRaw: false,
514
- output: writeOutput
515
- },
516
- "document-templates assets delete": {
517
- command: "document-templates assets delete",
518
- accessLevel: "destructive",
519
- supportsExample: true,
520
- supportsRaw: false,
521
- output: writeOutput
522
- },
523
- "document-templates assets download": {
524
- command: "document-templates assets download",
525
- accessLevel: "read",
526
- supportsExample: true,
527
- supportsRaw: false,
528
- output: "binary"
529
- },
530
439
  "files upload": {
531
440
  command: "files upload",
532
441
  accessLevel: "write",
@@ -667,13 +576,6 @@ var commandRegistry = {
667
576
  supportsRaw: false,
668
577
  output: writeOutput
669
578
  },
670
- "schemas set-unique-fields": {
671
- command: "schemas set-unique-fields",
672
- accessLevel: "write",
673
- supportsExample: true,
674
- supportsRaw: false,
675
- output: writeOutput
676
- },
677
579
  "schemas delete": {
678
580
  command: "schemas delete",
679
581
  accessLevel: "destructive",
@@ -2409,7 +2311,6 @@ var specificExamples = {
2409
2311
  },
2410
2312
  "auditable": true,
2411
2313
  "commentable": true,
2412
- "highlightedField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
2413
2314
  "fields": [
2414
2315
  {
2415
2316
  "id": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
@@ -2424,8 +2325,7 @@ var specificExamples = {
2424
2325
  "conditionalFormatting": []
2425
2326
  }
2426
2327
  }
2427
- ],
2428
- "uniqueFields": []
2328
+ ]
2429
2329
  }`
2430
2330
  },
2431
2331
  {
@@ -2441,86 +2341,6 @@ var specificExamples = {
2441
2341
  command: "zinkee --json schemas update contacts --auditable true",
2442
2342
  raw: `{
2443
2343
  "auditable": true
2444
- }`
2445
- },
2446
- {
2447
- description: "Set the schema's highlighted (main) field \u2014 the field whose value names each record in the UI (activity-panel title and detail-view record list).",
2448
- command: "zinkee --json schemas update contacts --highlighted-field contact-name",
2449
- raw: `{
2450
- "highlightedField": "c60b8526-5835-4c9f-aecd-9a16c7704a34"
2451
- }`
2452
- }
2453
- ]),
2454
- "schemas set-unique-fields": buildCommandExamples([
2455
- {
2456
- description: "Set a composite unique constraint: the listed fields must be unique together across records.",
2457
- command: "zinkee --json schemas set-unique-fields contacts --field contact-name --field notes",
2458
- raw: `{
2459
- "fieldIds": [
2460
- "c60b8526-5835-4c9f-aecd-9a16c7704a34",
2461
- "1d2e3f4a-5b6c-7d8e-9f01-23456789abcd"
2462
- ]
2463
- }`,
2464
- response: `{
2465
- "id": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
2466
- "name": "Contacts",
2467
- "slug": "contacts",
2468
- "folder": {
2469
- "id": "7f4e7c25-d8b2-4c1a-9f3e-6a7b5c8d9e1f",
2470
- "name": "Customers",
2471
- "isRoot": false
2472
- },
2473
- "auditable": true,
2474
- "commentable": true,
2475
- "highlightedField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
2476
- "fields": [
2477
- {
2478
- "id": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
2479
- "type": "TextField",
2480
- "slug": "contact-name",
2481
- "label": "Customer Name",
2482
- "required": true,
2483
- "system": false,
2484
- "config": {
2485
- "textType": "NORMAL",
2486
- "defaultValue": "Unknown",
2487
- "conditionalFormatting": []
2488
- }
2489
- },
2490
- {
2491
- "id": "1d2e3f4a-5b6c-7d8e-9f01-23456789abcd",
2492
- "type": "TextField",
2493
- "slug": "notes",
2494
- "label": "Notes",
2495
- "required": false,
2496
- "system": false,
2497
- "config": {
2498
- "textType": "LONG",
2499
- "defaultValue": null,
2500
- "conditionalFormatting": []
2501
- }
2502
- }
2503
- ],
2504
- "uniqueFields": [
2505
- "c60b8526-5835-4c9f-aecd-9a16c7704a34",
2506
- "1d2e3f4a-5b6c-7d8e-9f01-23456789abcd"
2507
- ]
2508
- }`
2509
- },
2510
- {
2511
- description: "Set a single-field unique constraint.",
2512
- command: "zinkee --json schemas set-unique-fields contacts --field contact-name",
2513
- raw: `{
2514
- "fieldIds": [
2515
- "c60b8526-5835-4c9f-aecd-9a16c7704a34"
2516
- ]
2517
- }`
2518
- },
2519
- {
2520
- description: "Clear the unique constraint (no field must be unique anymore).",
2521
- command: "zinkee --json schemas set-unique-fields contacts --clear",
2522
- raw: `{
2523
- "fieldIds": []
2524
2344
  }`
2525
2345
  }
2526
2346
  ]),
@@ -2750,7 +2570,7 @@ var specificExamples = {
2750
2570
  },
2751
2571
  {
2752
2572
  description: "Filter by status with a free-text search term.",
2753
- command: `zinkee --json records query contacts --select id,contact-name,status --where "status in OPEN" --search garcia --limit 25`,
2573
+ command: `zinkee --json records query contacts --select id,contact-name,status --where "status in OPEN" --limit 25 --raw '{"search":{"term":"garcia"}}'`,
2754
2574
  raw: `{
2755
2575
  "select": ["id", "contact-name", "status"],
2756
2576
  "where": [
@@ -2832,78 +2652,35 @@ var specificExamples = {
2832
2652
  ]),
2833
2653
  "records create": buildCommandExamples([
2834
2654
  {
2835
- description: "Create a single record with --set/--set-json (the single-record flags build one record, sent as a one-element 'records' array).",
2655
+ description: "Minimal create using just two plain string fields.",
2836
2656
  command: `zinkee --json records create contacts --set contact-name="Ada Lovelace" --set contact-email=ada@example.com`,
2837
2657
  raw: `{
2838
- "records": [
2839
- {
2840
- "contact-name": "Ada Lovelace",
2841
- "contact-email": "ada@example.com"
2842
- }
2843
- ]
2844
- }`,
2845
- response: `{
2846
- "created": [
2847
- "550e8400-e29b-41d4-a716-446655440000"
2848
- ],
2849
- "errors": []
2850
- }`
2851
- },
2852
- {
2853
- description: "Create many records from a JSON array file (one object per record, slug -> value). Best-effort: valid records are created and invalid ones are reported per index in 'errors'. ReferenceField values accept the target record id (a bare UUID, or the compound 'recordId::anything' whose label is ignored) or an exact display value; the server stores the canonical 'recordId::displayValue'.",
2854
- command: `zinkee --json records create contacts --records-file ./records.json`,
2855
- raw: `{
2856
- "records": [
2857
- {
2858
- "contact-name": "Ada Lovelace",
2859
- "contact-email": "ada@example.com"
2860
- },
2861
- {
2862
- "contact-name": "Grace Hopper",
2863
- "contact-email": "grace@example.com",
2864
- "status": 2,
2865
- "amount": 1999.99,
2866
- "due-date": "2026-06-01T09:00:00Z",
2867
- "customer-ref": "8ad602a1-f6e3-43f6-9ab2-f1c5afc99621",
2868
- "owner": "6c8a3e0d-4e5f-4a1b-9c2d-3e4f5a6b7c8d"
2869
- }
2870
- ]
2658
+ "values": {
2659
+ "contact-name": "Ada Lovelace",
2660
+ "contact-email": "ada@example.com"
2661
+ }
2871
2662
  }`,
2872
2663
  response: `{
2873
- "created": [
2874
- "550e8400-e29b-41d4-a716-446655440000"
2875
- ],
2876
- "errors": [
2877
- {
2878
- "index": 1,
2879
- "reason": "record_field_not_found",
2880
- "message": "Field 'contact-emial' was not found in schema '2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e'.",
2881
- "action": "Use a valid field slug from the schema and retry."
2882
- }
2883
- ]
2664
+ "recordId": "550e8400-e29b-41d4-a716-446655440000",
2665
+ "values": {
2666
+ "contact-name": "Ada Lovelace",
2667
+ "contact-email": "ada@example.com"
2668
+ }
2884
2669
  }`
2885
2670
  },
2886
2671
  {
2887
- description: "Set a ReferenceField by the target record id (a bare UUID, or the compound 'recordId::anything' whose label is ignored) or by an exact display value. The server resolves and stores the canonical 'recordId::displayValue'. Unknown references are rejected per index with reason 'data_field_reference_not_found'.",
2888
- command: `zinkee --json records create deals --set deal-name="Acme renewal" --set customer-ref=00000000-0000-0000-0000-000000000000`,
2672
+ description: "Create a record mixing text, option, number, date, reference and member fields. ReferenceField values must match the target's current targetDisplayField (read it from the target record before writing).",
2673
+ command: `zinkee --json records create contacts --set contact-name="Grace Hopper" --set contact-email=grace@example.com --set status=2 --set amount=1999.99 --set due-date=2026-06-01T09:00:00Z --set customer-ref="CUST-12" --set owner=6c8a3e0d-4e5f-4a1b-9c2d-3e4f5a6b7c8d`,
2889
2674
  raw: `{
2890
- "records": [
2891
- {
2892
- "deal-name": "Acme renewal",
2893
- "customer-ref": "00000000-0000-0000-0000-000000000000"
2894
- }
2895
- ]
2896
- }`,
2897
- response: `{
2898
- "created": [],
2899
- "errors": [
2900
- {
2901
- "index": 0,
2902
- "reason": "data_field_reference_not_found",
2903
- "message": "Referenced record was not found in the target schema.",
2904
- "action": "Use an existing record id or an existing display value for this reference field."
2905
- }
2906
- ]
2675
+ "values": {
2676
+ "contact-name": "Grace Hopper",
2677
+ "contact-email": "grace@example.com",
2678
+ "status": 2,
2679
+ "amount": 1999.99,
2680
+ "due-date": "2026-06-01T09:00:00Z",
2681
+ "customer-ref": "CUST-12",
2682
+ "owner": "6c8a3e0d-4e5f-4a1b-9c2d-3e4f5a6b7c8d"
2683
+ }
2907
2684
  }`
2908
2685
  }
2909
2686
  ]),
@@ -2945,22 +2722,6 @@ var specificExamples = {
2945
2722
  command: "zinkee --json records update contacts 550e8400-e29b-41d4-a716-446655440000 --unset contact-email --unset due-date",
2946
2723
  raw: `{
2947
2724
  "unset": ["contact-email", "due-date"]
2948
- }`
2949
- },
2950
- {
2951
- description: "Set a ReferenceField on an existing record. Pass the target record id (a bare UUID, or the compound 'recordId::anything' whose label is ignored) or an exact display value; the response shows the canonical 'recordId::displayValue' the server stored. If the reference doesn't exist the whole update is rejected with reason 'data_field_reference_not_found'.",
2952
- command: "zinkee --json records update deals 550e8400-e29b-41d4-a716-446655440000 --set customer-ref=8ad602a1-f6e3-43f6-9ab2-f1c5afc99621",
2953
- raw: `{
2954
- "set": {
2955
- "customer-ref": "8ad602a1-f6e3-43f6-9ab2-f1c5afc99621"
2956
- }
2957
- }`,
2958
- response: `{
2959
- "recordId": "550e8400-e29b-41d4-a716-446655440000",
2960
- "values": {
2961
- "deal-name": "Acme renewal",
2962
- "customer-ref": "8ad602a1-f6e3-43f6-9ab2-f1c5afc99621::Acme Corp"
2963
- }
2964
2725
  }`
2965
2726
  }
2966
2727
  ]),
@@ -3102,10 +2863,11 @@ var specificExamples = {
3102
2863
  ]),
3103
2864
  "navigation resources move": buildCommandExamples([
3104
2865
  {
3105
- description: "Move a schema into a navigation folder. Only schemas can be moved; the navigation menu holds databases.",
3106
- command: "zinkee --json navigation resources move 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --to Sales",
2866
+ description: "Move a schema into a navigation folder.",
2867
+ command: "zinkee --json navigation resources move 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --type SCHEMA --to Sales",
3107
2868
  raw: `{
3108
2869
  "resourceId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
2870
+ "resourceType": "SCHEMA",
3109
2871
  "targetFolderId": "84a0fca4-37ef-4c83-a8ed-9ef67ad9324a"
3110
2872
  }`,
3111
2873
  response: `{
@@ -3114,11 +2876,39 @@ var specificExamples = {
3114
2876
  }`
3115
2877
  },
3116
2878
  {
3117
- description: "Move a schema back to the root folder (root is always UUID 00000000-0000-0000-0000-000000000000).",
3118
- command: "zinkee --json navigation resources move 5223cbc8-8c6c-4694-93bc-dd176364df9b --to 00000000-0000-0000-0000-000000000000",
2879
+ description: "Move a workflow.",
2880
+ command: "zinkee --json navigation resources move 3f8a2c1b-9d4e-4a5b-8c6d-7e8f90123456 --type WORKFLOW --to Operations",
2881
+ raw: `{
2882
+ "resourceId": "3f8a2c1b-9d4e-4a5b-8c6d-7e8f90123456",
2883
+ "resourceType": "WORKFLOW",
2884
+ "targetFolderId": "b8c9d0e1-f2a3-4b5c-6d7e-8f9012345678"
2885
+ }`
2886
+ },
2887
+ {
2888
+ description: "Move a display.",
2889
+ command: "zinkee --json navigation resources move 0f6f062f-1478-4df2-96a1-c495d037d260 --type DISPLAY --to Operations",
2890
+ raw: `{
2891
+ "resourceId": "0f6f062f-1478-4df2-96a1-c495d037d260",
2892
+ "resourceType": "DISPLAY",
2893
+ "targetFolderId": "b8c9d0e1-f2a3-4b5c-6d7e-8f9012345678"
2894
+ }`
2895
+ },
2896
+ {
2897
+ description: "Move a resource back to the root folder (root is always UUID 00000000-0000-0000-0000-000000000000).",
2898
+ command: "zinkee --json navigation resources move 5223cbc8-8c6c-4694-93bc-dd176364df9b --type SCHEMA --to 00000000-0000-0000-0000-000000000000",
3119
2899
  raw: `{
3120
2900
  "resourceId": "5223cbc8-8c6c-4694-93bc-dd176364df9b",
2901
+ "resourceType": "SCHEMA",
3121
2902
  "targetFolderId": "00000000-0000-0000-0000-000000000000"
2903
+ }`
2904
+ },
2905
+ {
2906
+ description: "Move a schedule resource.",
2907
+ command: "zinkee --json navigation resources move a1b2c3d4-e5f6-7890-1234-567890abcdef --type SCHEDULE --to Operations",
2908
+ raw: `{
2909
+ "resourceId": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
2910
+ "resourceType": "SCHEDULE",
2911
+ "targetFolderId": "b8c9d0e1-f2a3-4b5c-6d7e-8f9012345678"
3122
2912
  }`
3123
2913
  }
3124
2914
  ]),
@@ -3516,12 +3306,12 @@ var specificExamples = {
3516
3306
  }`
3517
3307
  },
3518
3308
  {
3519
- description: "Change a DATE variable to use last12Months.",
3520
- command: "zinkee --json displays variables update 0f6f062f-1478-4df2-96a1-c495d037d260 bbbbbbbb-2222-4222-a222-222222222222 --date-mode dynamic --date-dynamic-option last12Months",
3309
+ description: "Change a DATE variable to use lastWeek.",
3310
+ command: "zinkee --json displays variables update 0f6f062f-1478-4df2-96a1-c495d037d260 bbbbbbbb-2222-4222-a222-222222222222 --date-mode dynamic --date-dynamic-option lastWeek",
3521
3311
  raw: `{
3522
3312
  "date": {
3523
3313
  "mode": "dynamic",
3524
- "dynamicOption": "last12Months"
3314
+ "dynamicOption": "lastWeek"
3525
3315
  }
3526
3316
  }`
3527
3317
  }
@@ -3529,7 +3319,7 @@ var specificExamples = {
3529
3319
  "displays widgets create": buildCommandExamples([
3530
3320
  {
3531
3321
  description: "Create a TABLE widget (CLI normalises --type table to TABLE_OR_SUBTABLE).",
3532
- 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"}'`,
3322
+ 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"}'`,
3533
3323
  raw: `{
3534
3324
  "type": "TABLE_OR_SUBTABLE",
3535
3325
  "source": {
@@ -3544,11 +3334,11 @@ var specificExamples = {
3544
3334
  },
3545
3335
  "query": {
3546
3336
  "sorts": [
3547
- { "fieldId": "contact-name", "direction": "ASC" }
3337
+ { "fieldId": "id", "direction": "DESC" }
3548
3338
  ]
3549
3339
  },
3550
3340
  "view": {
3551
- "fields": ["contact-name", "status", "amount"]
3341
+ "fields": ["id", "contact-name", "status"]
3552
3342
  }
3553
3343
  }`,
3554
3344
  response: `{
@@ -3597,8 +3387,8 @@ var specificExamples = {
3597
3387
  }`
3598
3388
  },
3599
3389
  {
3600
- description: "Create a CHART widget with a daily time-serie x-axis.",
3601
- command: `zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --type CHART --name "Revenue by day" --origin-resource 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --layout '{"x":0,"y":0,"w":8,"h":6}' --chart-type lines --x-axis-field due-date --x-axis-date-format DATE --x-axis-time-series --y-axis-serie '{"typeCalc":"SUM","fieldCalc":"amount","color":"#4B9CD3","axisType":"PRIMARY"}' --legend '{"position":"bottom"}'`,
3390
+ description: "Create a bars CHART widget with a time-serie x-axis and two y-axis series.",
3391
+ 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 --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"}'`,
3602
3392
  raw: `{
3603
3393
  "type": "CHART",
3604
3394
  "source": {
@@ -3608,11 +3398,11 @@ var specificExamples = {
3608
3398
  "placement": {
3609
3399
  "layout": { "x": 0, "y": 0, "w": 8, "h": 6 }
3610
3400
  },
3611
- "presentation": { "name": "Revenue by day" },
3401
+ "presentation": { "name": "Revenue by month" },
3612
3402
  "chart": {
3613
- "chartType": "lines",
3403
+ "chartType": "bars",
3614
3404
  "xAxisFieldId": "due-date",
3615
- "xAxisDateFormat": "DATE",
3405
+ "xAxisDateFormat": "MONTH",
3616
3406
  "xAxisAsTimeSerie": true,
3617
3407
  "yAxisSeries": [
3618
3408
  {
@@ -3620,6 +3410,12 @@ var specificExamples = {
3620
3410
  "fieldCalc": "amount",
3621
3411
  "color": "#4B9CD3",
3622
3412
  "axisType": "PRIMARY"
3413
+ },
3414
+ {
3415
+ "typeCalc": "COUNT",
3416
+ "fieldCalc": "id",
3417
+ "color": "#E57373",
3418
+ "axisType": "SECONDARY"
3623
3419
  }
3624
3420
  ],
3625
3421
  "legend": { "position": "bottom" }
@@ -3627,197 +3423,59 @@ var specificExamples = {
3627
3423
  }`
3628
3424
  },
3629
3425
  {
3630
- description: "Create a bars CHART widget with a monthly time-serie x-axis and two y-axis series.",
3631
- 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"}'`,
3426
+ description: "Create a TIMELINE widget.",
3427
+ 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`,
3632
3428
  raw: `{
3633
- "type": "CHART",
3429
+ "type": "TIMELINE",
3634
3430
  "source": {
3635
3431
  "originResourceId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
3636
3432
  "isOriginSubSchema": false
3637
3433
  },
3638
3434
  "placement": {
3639
- "layout": { "x": 0, "y": 0, "w": 8, "h": 6 }
3435
+ "layout": { "x": 0, "y": 0, "w": 12, "h": 6 }
3640
3436
  },
3641
- "presentation": { "name": "Revenue by month" },
3642
- "chart": {
3643
- "chartType": "bars",
3644
- "xAxisFieldId": "due-date",
3645
- "xAxisDateFormat": "MONTH_YEAR",
3646
- "xAxisAsTimeSerie": true,
3647
- "yAxisSeries": [
3648
- {
3649
- "typeCalc": "SUM",
3650
- "fieldCalc": "amount",
3651
- "color": "#4B9CD3",
3652
- "axisType": "PRIMARY"
3653
- },
3654
- {
3655
- "typeCalc": "COUNT",
3656
- "fieldCalc": "contact-name",
3657
- "color": "#E57373",
3658
- "axisType": "SECONDARY"
3659
- }
3660
- ],
3661
- "legend": { "position": "bottom" }
3437
+ "presentation": { "name": "Customer schedule" },
3438
+ "view": {
3439
+ "fields": ["contact-name", "due-date"]
3662
3440
  }
3663
3441
  }`
3664
3442
  },
3665
3443
  {
3666
- description: "Create a bars CHART widget with a quarterly time-serie x-axis.",
3667
- command: `zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --type CHART --name "Revenue by quarter" --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 QUARTER_YEAR --x-axis-time-series --y-axis-serie '{"typeCalc":"SUM","fieldCalc":"amount","color":"#4B9CD3","axisType":"PRIMARY"}' --legend '{"position":"bottom"}'`,
3444
+ description: "Create a KANBAN widget with a status filter and groupsExpanded config (rich query/view requires --raw).",
3445
+ 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}}}'`,
3668
3446
  raw: `{
3669
- "type": "CHART",
3447
+ "type": "KANBAN",
3670
3448
  "source": {
3671
3449
  "originResourceId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
3672
3450
  "isOriginSubSchema": false
3673
3451
  },
3674
3452
  "placement": {
3675
- "layout": { "x": 0, "y": 0, "w": 8, "h": 6 }
3453
+ "layout": { "x": 0, "y": 0, "w": 12, "h": 8 }
3676
3454
  },
3677
- "presentation": { "name": "Revenue by quarter" },
3678
- "chart": {
3679
- "chartType": "bars",
3680
- "xAxisFieldId": "due-date",
3681
- "xAxisDateFormat": "QUARTER_YEAR",
3682
- "xAxisAsTimeSerie": true,
3683
- "yAxisSeries": [
3455
+ "presentation": { "name": "Status board" },
3456
+ "query": {
3457
+ "filters": [
3684
3458
  {
3685
- "typeCalc": "SUM",
3686
- "fieldCalc": "amount",
3687
- "color": "#4B9CD3",
3688
- "axisType": "PRIMARY"
3459
+ "origin": {
3460
+ "schemaId": "contacts",
3461
+ "fieldId": "status"
3462
+ },
3463
+ "comparisonOperator": "ANY_OF",
3464
+ "values": ["1", "2", "3"]
3689
3465
  }
3690
- ],
3691
- "legend": { "position": "bottom" }
3466
+ ]
3467
+ },
3468
+ "view": {
3469
+ "fields": ["contact-name", "status", "amount"],
3470
+ "groupsExpanded": { "1": true, "2": true, "3": false }
3692
3471
  }
3693
3472
  }`
3694
3473
  },
3695
3474
  {
3696
- description: "Create a CHART widget with a yearly time-serie x-axis.",
3697
- command: `zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --type CHART --name "Revenue by year" --origin-resource 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --layout '{"x":0,"y":0,"w":8,"h":6}' --chart-type lines --x-axis-field due-date --x-axis-date-format YEAR --x-axis-time-series --y-axis-serie '{"typeCalc":"SUM","fieldCalc":"amount","color":"#4B9CD3","axisType":"PRIMARY"}' --legend '{"position":"bottom"}'`,
3475
+ description: "Create a HIERARCHY widget rooted on a parent field.",
3476
+ 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"}}}'`,
3698
3477
  raw: `{
3699
- "type": "CHART",
3700
- "source": {
3701
- "originResourceId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
3702
- "isOriginSubSchema": false
3703
- },
3704
- "placement": {
3705
- "layout": { "x": 0, "y": 0, "w": 8, "h": 6 }
3706
- },
3707
- "presentation": { "name": "Revenue by year" },
3708
- "chart": {
3709
- "chartType": "lines",
3710
- "xAxisFieldId": "due-date",
3711
- "xAxisDateFormat": "YEAR",
3712
- "xAxisAsTimeSerie": true,
3713
- "yAxisSeries": [
3714
- {
3715
- "typeCalc": "SUM",
3716
- "fieldCalc": "amount",
3717
- "color": "#4B9CD3",
3718
- "axisType": "PRIMARY"
3719
- }
3720
- ],
3721
- "legend": { "position": "bottom" }
3722
- }
3723
- }`
3724
- },
3725
- {
3726
- 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* ...).",
3727
- 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}'`,
3728
- raw: `{
3729
- "type": "TIMELINE",
3730
- "source": {
3731
- "originResourceId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
3732
- "isOriginSubSchema": false
3733
- },
3734
- "placement": {
3735
- "layout": { "x": 0, "y": 0, "w": 12, "h": 6 }
3736
- },
3737
- "presentation": { "name": "Customer schedule" },
3738
- "view": {
3739
- "fields": [
3740
- "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3741
- "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3742
- "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
3743
- "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90"
3744
- ],
3745
- "viewAdditionalProperties": {
3746
- "viewState": {
3747
- "granularity": "month",
3748
- "sidebarWidth": 300,
3749
- "showUngroupedEvents": true,
3750
- "showUnsubgroupedEvents": true,
3751
- "fieldMapping": {
3752
- "startDateField": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
3753
- "endDateField": "e5f6a7b8-c9d0-1e2f-3a4b-5c6d7e8f9012",
3754
- "labelField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3755
- "groupField": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3756
- "subgroupField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3757
- "progressField": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
3758
- "cardConfig": {
3759
- "titleField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3760
- "category1Field": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3761
- "category2Field": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
3762
- "category4Field": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
3763
- "descriptionField": "c60b8526-5835-4c9f-aecd-9a16c7704a34"
3764
- }
3765
- }
3766
- }
3767
- }
3768
- }
3769
- }`
3770
- },
3771
- {
3772
- 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.",
3773
- 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}'`,
3774
- raw: `{
3775
- "type": "KANBAN",
3776
- "source": {
3777
- "originResourceId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
3778
- "isOriginSubSchema": false
3779
- },
3780
- "placement": {
3781
- "layout": { "x": 0, "y": 0, "w": 12, "h": 8 }
3782
- },
3783
- "presentation": { "name": "Status board" },
3784
- "view": {
3785
- "fields": [
3786
- "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3787
- "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3788
- "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
3789
- "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90"
3790
- ],
3791
- "viewAdditionalProperties": {
3792
- "viewState": {
3793
- "hideEmptyColumns": false,
3794
- "showNoValueColumn": true,
3795
- "showNoValueSwimlane": true,
3796
- "fieldMapping": {
3797
- "columnField": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3798
- "swimlaneField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3799
- "cardConfig": {
3800
- "titleField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3801
- "category1Field": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3802
- "category2Field": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
3803
- "category3Field": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
3804
- "descriptionField": "c60b8526-5835-4c9f-aecd-9a16c7704a34"
3805
- },
3806
- "aggregationConfig": {
3807
- "method": "sum",
3808
- "fieldId": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043"
3809
- }
3810
- }
3811
- }
3812
- }
3813
- }
3814
- }`
3815
- },
3816
- {
3817
- 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.",
3818
- 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"}]}'`,
3819
- raw: `{
3820
- "type": "HIERARCHY",
3478
+ "type": "HIERARCHY",
3821
3479
  "source": {
3822
3480
  "originResourceId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
3823
3481
  "isOriginSubSchema": false
@@ -3827,46 +3485,9 @@ var specificExamples = {
3827
3485
  },
3828
3486
  "presentation": { "name": "Org tree" },
3829
3487
  "view": {
3830
- "fields": [
3831
- "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3832
- "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3833
- "c52efe3f-2825-4c60-a7e3-34dd4c1ce043"
3834
- ],
3488
+ "fields": ["contact-name", "status"],
3835
3489
  "hierarchyConfig": {
3836
- "columns": {
3837
- "label": "Name",
3838
- "infos": [
3839
- { "id": "col_1779975207355_zfndknslw", "name": "Status" },
3840
- { "id": "col_1779975243018_qm4t7xb2pa", "name": "Description" }
3841
- ],
3842
- "numbers": [
3843
- { "id": "col_1779975261490_h8kd3nv9ws", "name": "Total amount", "aggregation": "SUM" }
3844
- ]
3845
- },
3846
- "rootLevel": {
3847
- "name": "Customers",
3848
- "labelFieldId": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3849
- "infoMappings": [
3850
- { "columnId": "col_1779975207355_zfndknslw", "fieldId": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890" }
3851
- ],
3852
- "numberMappings": [
3853
- { "columnId": "col_1779975261490_h8kd3nv9ws", "fieldId": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043" }
3854
- ]
3855
- },
3856
- "childLevels": [
3857
- {
3858
- "name": "Projects",
3859
- "schemaId": "3ec9cdef-7e0a-4cdd-8019-8fb9281f5d6f",
3860
- "childFieldId": "80deefae-af3d-4000-b322-bfe1594f8073",
3861
- "labelFieldId": "50dbef0b-7e0a-4fdd-8019-8fb9281f5d70",
3862
- "infoMappings": [
3863
- { "columnId": "col_1779975243018_qm4t7xb2pa", "fieldId": "60dcef0c-8f1b-4eee-9120-9fc0392f6e71" }
3864
- ],
3865
- "numberMappings": [
3866
- { "columnId": "col_1779975261490_h8kd3nv9ws", "fieldId": "70ddef0d-9f2c-4fff-a221-afd0493f7f72" }
3867
- ]
3868
- }
3869
- ]
3490
+ "parentFieldId": "contact-name"
3870
3491
  }
3871
3492
  }
3872
3493
  }`
@@ -3875,13 +3496,13 @@ var specificExamples = {
3875
3496
  "displays widgets update": buildCommandExamples([
3876
3497
  {
3877
3498
  description: "Move placement, update view columns, rename the widget and lock it.",
3878
- 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`,
3499
+ 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`,
3879
3500
  raw: `{
3880
3501
  "placement": {
3881
3502
  "layout": { "x": 1, "y": 2, "w": 8, "h": 4 }
3882
3503
  },
3883
3504
  "view": {
3884
- "fields": ["contact-name", "status", "amount"]
3505
+ "fields": ["id", "contact-name", "status"]
3885
3506
  },
3886
3507
  "presentation": { "name": "Revenue Updated" },
3887
3508
  "behavior": { "readOnly": true }
@@ -3892,38 +3513,29 @@ var specificExamples = {
3892
3513
  }`
3893
3514
  },
3894
3515
  {
3895
- description: "Add query filters with --filter. The CLI parses the expression and emits the structured comparisonOperator payload the API expects.",
3896
- command: `zinkee --json displays widgets update 0f6f062f-1478-4df2-96a1-c495d037d260 11111111-1111-4111-a111-111111111111 --filter "status:eq:2" --filter "amount:gte:500"`,
3516
+ description: "Add query filters that match the full comparisonOperator contract (requires --raw because --filter only accepts free-form expressions).",
3517
+ command: `zinkee --json displays widgets update 0f6f062f-1478-4df2-96a1-c495d037d260 11111111-1111-4111-a111-111111111111 --raw '{"query":{"filters":[{"origin":{"schemaId":"contacts","fieldId":"status"},"comparisonOperator":"EQUAL","values":["2"]},{"origin":{"schemaId":"contacts","fieldId":"amount"},"comparisonOperator":"GREATER_OR_EQUAL","values":["500"]}]}}'`,
3897
3518
  raw: `{
3898
3519
  "query": {
3899
3520
  "filters": [
3900
3521
  {
3901
- "origin": { "fieldId": "status" },
3522
+ "origin": {
3523
+ "schemaId": "contacts",
3524
+ "fieldId": "status"
3525
+ },
3902
3526
  "comparisonOperator": "EQUAL",
3903
3527
  "values": ["2"]
3904
3528
  },
3905
3529
  {
3906
- "origin": { "fieldId": "amount" },
3530
+ "origin": {
3531
+ "schemaId": "contacts",
3532
+ "fieldId": "amount"
3533
+ },
3907
3534
  "comparisonOperator": "GREATER_OR_EQUAL",
3908
3535
  "values": ["500"]
3909
3536
  }
3910
3537
  ]
3911
3538
  }
3912
- }`
3913
- },
3914
- {
3915
- description: "Fall back to --raw for comparators the parser does not cover yet (e.g. NOT_CONTAINS, RANGE).",
3916
- command: `zinkee --json displays widgets update 0f6f062f-1478-4df2-96a1-c495d037d260 11111111-1111-4111-a111-111111111111 --raw '{"query":{"filters":[{"origin":{"fieldId":"due-date"},"comparisonOperator":"RANGE","values":["2025-01-01","2025-12-31"]}]}}'`,
3917
- raw: `{
3918
- "query": {
3919
- "filters": [
3920
- {
3921
- "origin": { "fieldId": "due-date" },
3922
- "comparisonOperator": "RANGE",
3923
- "values": ["2025-01-01", "2025-12-31"]
3924
- }
3925
- ]
3926
- }
3927
3539
  }`
3928
3540
  },
3929
3541
  {
@@ -3949,13 +3561,13 @@ var specificExamples = {
3949
3561
  }`
3950
3562
  },
3951
3563
  {
3952
- description: "Replace the chart series with quarterly lines.",
3953
- command: `zinkee --json displays widgets update 0f6f062f-1478-4df2-96a1-c495d037d260 22222222-2222-4222-a222-222222222222 --chart-type lines --x-axis-field due-date --x-axis-date-format QUARTER_YEAR --x-axis-time-series --y-axis-serie '{"typeCalc":"SUM","fieldCalc":"amount","color":"#2E7D32","axisType":"PRIMARY"}'`,
3564
+ description: "Replace the chart series with weekly lines.",
3565
+ command: `zinkee --json displays widgets update 0f6f062f-1478-4df2-96a1-c495d037d260 22222222-2222-4222-a222-222222222222 --chart-type lines --x-axis-field due-date --x-axis-date-format WEEK --x-axis-time-series --y-axis-serie '{"typeCalc":"SUM","fieldCalc":"amount","color":"#2E7D32","axisType":"PRIMARY"}'`,
3954
3566
  raw: `{
3955
3567
  "chart": {
3956
3568
  "chartType": "lines",
3957
3569
  "xAxisFieldId": "due-date",
3958
- "xAxisDateFormat": "QUARTER_YEAR",
3570
+ "xAxisDateFormat": "WEEK",
3959
3571
  "xAxisAsTimeSerie": true,
3960
3572
  "yAxisSeries": [
3961
3573
  {
@@ -4121,7 +3733,6 @@ var specificExamples = {
4121
3733
  },
4122
3734
  "auditable": true,
4123
3735
  "commentable": true,
4124
- "highlightedField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
4125
3736
  "fields": [
4126
3737
  {
4127
3738
  "id": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
@@ -4430,10 +4041,6 @@ var specificExamples = {
4430
4041
  "conditionalFormatting": []
4431
4042
  }
4432
4043
  }
4433
- ],
4434
- "uniqueFields": [
4435
- "c60b8526-5835-4c9f-aecd-9a16c7704a34",
4436
- "1d2e3f4a-5b6c-7d8e-9f01-23456789abcd"
4437
4044
  ]
4438
4045
  }`
4439
4046
  }
@@ -4592,24 +4199,10 @@ var specificExamples = {
4592
4199
  ]),
4593
4200
  "records delete": buildCommandExamples([
4594
4201
  {
4595
- description: "Delete one or more records by id (--record is repeatable).",
4596
- command: `zinkee --json records delete contacts --record 550e8400-e29b-41d4-a716-446655440000 --record 6c8a3e0d-4e5f-4a1b-9c2d-3e4f5a6b7c8d`,
4597
- response: `{
4598
- "recordIds": [
4599
- "550e8400-e29b-41d4-a716-446655440000",
4600
- "6c8a3e0d-4e5f-4a1b-9c2d-3e4f5a6b7c8d"
4601
- ],
4602
- "deleted": true
4603
- }`
4604
- },
4605
- {
4606
- description: "Delete many records listing one uuid per line in a file (merged with any --record flags and de-duplicated).",
4607
- command: `zinkee --json records delete contacts --records-file ./record-ids.txt`,
4202
+ description: "Delete a record.",
4203
+ command: `zinkee --json records delete contacts ${SAMPLE_UUID}`,
4608
4204
  response: `{
4609
- "recordIds": [
4610
- "550e8400-e29b-41d4-a716-446655440000",
4611
- "6c8a3e0d-4e5f-4a1b-9c2d-3e4f5a6b7c8d"
4612
- ],
4205
+ "recordId": "550e8400-e29b-41d4-a716-446655440000",
4613
4206
  "deleted": true
4614
4207
  }`
4615
4208
  }
@@ -4705,7 +4298,7 @@ var specificExamples = {
4705
4298
  "resources": [
4706
4299
  {
4707
4300
  "id": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
4708
- "name": "Customer records",
4301
+ "name": "Contacts",
4709
4302
  "type": "SCHEMA",
4710
4303
  "isInSpace": false,
4711
4304
  "additionalProperties": {}
@@ -4729,10 +4322,19 @@ var specificExamples = {
4729
4322
  "resources": [
4730
4323
  {
4731
4324
  "id": "3f8a2c1b-9d4e-4a5b-8c6d-7e8f90123456",
4732
- "name": "Shipments",
4733
- "type": "SCHEMA",
4325
+ "name": "Quote approval",
4326
+ "type": "WORKFLOW",
4734
4327
  "isInSpace": false,
4735
4328
  "additionalProperties": {}
4329
+ },
4330
+ {
4331
+ "id": "0f6f062f-1478-4df2-96a1-c495d037d260",
4332
+ "name": "Executive Revenue",
4333
+ "type": "DISPLAY",
4334
+ "isInSpace": true,
4335
+ "additionalProperties": {
4336
+ "pinned": true
4337
+ }
4736
4338
  }
4737
4339
  ],
4738
4340
  "additionalProperties": {
@@ -4779,13 +4381,8 @@ var specificExamples = {
4779
4381
  "name": "Shared Dashboards",
4780
4382
  "order": 1,
4781
4383
  "isRoot": false,
4782
- "resourceCount": 2,
4384
+ "resourceCount": 1,
4783
4385
  "resources": [
4784
- {
4785
- "id": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
4786
- "name": "Customer records",
4787
- "type": "SCHEMA"
4788
- },
4789
4386
  {
4790
4387
  "id": "0f6f062f-1478-4df2-96a1-c495d037d260",
4791
4388
  "name": "Executive Revenue",
@@ -4957,7 +4554,7 @@ var specificExamples = {
4957
4554
  "hideDeleteButton": false
4958
4555
  },
4959
4556
  "view": {
4960
- "fields": ["contact-name", "status", "amount"],
4557
+ "fields": ["id", "contact-name", "status", "amount"],
4961
4558
  "columnSize": { "contact-name": 240 }
4962
4559
  }
4963
4560
  }
@@ -5004,83 +4601,6 @@ var specificExamples = {
5004
4601
  command: "zinkee --json displays delete 0f6f062f-1478-4df2-96a1-c495d037d260"
5005
4602
  }
5006
4603
  ]),
5007
- "displays folders list": buildCommandExamples([
5008
- {
5009
- description: "List flat display folders (non-root folders plus the root bucket).",
5010
- command: "zinkee --json displays folders list",
5011
- response: `[
5012
- {
5013
- "id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
5014
- "name": "Executive Dashboards",
5015
- "isRoot": false,
5016
- "displayCount": 2
5017
- },
5018
- {
5019
- "id": "8b22282b-3db3-4dd7-87f7-b29365dcf3f6",
5020
- "name": null,
5021
- "isRoot": true,
5022
- "displayCount": 4
5023
- }
5024
- ]`
5025
- }
5026
- ]),
5027
- "displays folders create": buildCommandExamples([
5028
- {
5029
- description: "Create one flat display folder.",
5030
- command: 'zinkee --json displays folders create --name "Executive Dashboards"',
5031
- raw: `{
5032
- "name": "Executive Dashboards"
5033
- }`,
5034
- response: `{
5035
- "id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
5036
- "name": "Executive Dashboards",
5037
- "isRoot": false,
5038
- "displayCount": 0
5039
- }`
5040
- }
5041
- ]),
5042
- "displays folders update": buildCommandExamples([
5043
- {
5044
- description: "Rename a display folder. The folder argument accepts a UUID or an exact name.",
5045
- command: 'zinkee --json displays folders update "Executive Dashboards" --name "Executive Dashboards (2026)"',
5046
- raw: `{
5047
- "name": "Executive Dashboards (2026)"
5048
- }`,
5049
- response: `{
5050
- "id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
5051
- "name": "Executive Dashboards (2026)",
5052
- "isRoot": false,
5053
- "displayCount": 2
5054
- }`
5055
- }
5056
- ]),
5057
- "displays folders delete": buildCommandExamples([
5058
- {
5059
- description: "Delete a non-root display folder. Its displays move back to the root folder.",
5060
- command: 'zinkee --json displays folders delete "Executive Dashboards"',
5061
- response: `{
5062
- "id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
5063
- "name": "Executive Dashboards",
5064
- "isRoot": false,
5065
- "displayCount": 2
5066
- }`
5067
- }
5068
- ]),
5069
- "displays folders move": buildCommandExamples([
5070
- {
5071
- description: "Move one display into a target folder by exact folder name.",
5072
- command: 'zinkee --json displays folders move 0f6f062f-1478-4df2-96a1-c495d037d260 --to "Executive Dashboards"',
5073
- raw: `{
5074
- "displayId": "0f6f062f-1478-4df2-96a1-c495d037d260",
5075
- "targetFolderId": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e"
5076
- }`,
5077
- response: `{
5078
- "id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
5079
- "name": "Executive Dashboards",
5080
- "isRoot": false
5081
- }`
5082
- }
5083
- ]),
5084
4604
  "displays layout get": buildCommandExamples([
5085
4605
  {
5086
4606
  description: "Get the layout block of a display (template + tabs/freeformLayouts/slots).",
@@ -5174,7 +4694,7 @@ var specificExamples = {
5174
4694
  "hideDeleteButton": false
5175
4695
  },
5176
4696
  "view": {
5177
- "fields": ["contact-name", "status", "amount"],
4697
+ "fields": ["id", "contact-name", "status", "amount"],
5178
4698
  "columnSize": { "contact-name": 240 }
5179
4699
  }
5180
4700
  }`
@@ -5831,43 +5351,6 @@ var specificExamples = {
5831
5351
  "steps": ["one", "two"]
5832
5352
  }
5833
5353
  }
5834
- }`
5835
- },
5836
- {
5837
- description: "Add a send-message action. --to maps to fieldMapping.recipients and --message maps to fieldMapping.body. Values are wrapped in {rawValue, source} like every other automation field mapping; use --map / --map-json for extra keys.",
5838
- command: `zinkee --json automations actions add automation-1 --type send_message --name "Notify customer" --to customer@example.com --subject "Your order status has changed" --message "Hello, your order is now processed."`,
5839
- raw: `{
5840
- "type": "send_message",
5841
- "name": "Notify customer",
5842
- "config": {
5843
- "fieldMapping": {
5844
- "recipients": {
5845
- "rawValue": "customer@example.com",
5846
- "source": null
5847
- },
5848
- "subject": {
5849
- "rawValue": "Your order status has changed",
5850
- "source": null
5851
- },
5852
- "body": {
5853
- "rawValue": "Hello, your order is now processed.",
5854
- "source": null
5855
- }
5856
- }
5857
- }
5858
- }`
5859
- },
5860
- {
5861
- description: "Add a generate-document action. The renderer reads the template, writes the file, and stores its id in the target FileField of the target schema.",
5862
- command: 'zinkee --json automations actions add automation-1 --type generate_document --name "Generate invoice PDF" --document-template 6c08673e-f8a6-44d2-8c91-d09eca911f8f --target-schema 68d2c7be-4392-42de-b5ae-625ad79cfc3c --target-file-field c8edbde8-a361-4e9f-a39a-2e88971f21a7',
5863
- raw: `{
5864
- "type": "generate_document",
5865
- "name": "Generate invoice PDF",
5866
- "config": {
5867
- "documentTemplateId": "6c08673e-f8a6-44d2-8c91-d09eca911f8f",
5868
- "targetSchemaId": "68d2c7be-4392-42de-b5ae-625ad79cfc3c",
5869
- "targetFileFieldId": "c8edbde8-a361-4e9f-a39a-2e88971f21a7"
5870
- }
5871
5354
  }`
5872
5355
  }
5873
5356
  ]),
@@ -5918,30 +5401,6 @@ var specificExamples = {
5918
5401
  "authMode": "STORED",
5919
5402
  "connectionId": "connection-1"
5920
5403
  }
5921
- }`
5922
- },
5923
- {
5924
- description: "Replace a send-message action. --to maps to fieldMapping.recipients and --message maps to fieldMapping.body; values are wrapped in {rawValue, source}.",
5925
- command: `zinkee --json automations actions update automation-1 action-1 --type send_message --name "Notify customer" --to customer@example.com --subject "Your order status has changed" --message "Hello, your order is now processed."`,
5926
- raw: `{
5927
- "type": "send_message",
5928
- "name": "Notify customer",
5929
- "config": {
5930
- "fieldMapping": {
5931
- "recipients": {
5932
- "rawValue": "customer@example.com",
5933
- "source": null
5934
- },
5935
- "subject": {
5936
- "rawValue": "Your order status has changed",
5937
- "source": null
5938
- },
5939
- "body": {
5940
- "rawValue": "Hello, your order is now processed.",
5941
- "source": null
5942
- }
5943
- }
5944
- }
5945
5404
  }`
5946
5405
  }
5947
5406
  ]),
@@ -6094,8 +5553,7 @@ var specificExamples = {
6094
5553
  description: "Move one automation into a target folder by exact folder name.",
6095
5554
  command: 'zinkee --json automations folders move automation-1 --to "Codex Frontend Demo"',
6096
5555
  raw: `{
6097
- "automationId": "automation-1",
6098
- "targetFolderId": "cdfc14e3-3169-4ffb-8d9b-b11858a9240f"
5556
+ "automationId": "automation-1"
6099
5557
  }`,
6100
5558
  response: `{
6101
5559
  "id": "cdfc14e3-3169-4ffb-8d9b-b11858a9240f",
@@ -6103,232 +5561,67 @@ var specificExamples = {
6103
5561
  "isRoot": false
6104
5562
  }`
6105
5563
  }
6106
- ]),
6107
- "document-templates list": buildCommandExamples([
6108
- {
6109
- description: "List every document template in the workspace. Each asset's link is a relative path to the asset download endpoint, ready to call without composition.",
6110
- command: "zinkee --json document-templates list",
6111
- response: `[
6112
- {
6113
- "id": "7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e",
6114
- "name": "Quarterly report",
6115
- "assets": [
6116
- {
6117
- "id": "9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f",
6118
- "name": "Requirements.docx",
6119
- "link": "/api/v2/document-templates/7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e/assets/9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f/download"
5564
+ ])
5565
+ };
5566
+ function fallbackExamples(commandName) {
5567
+ switch (commandName) {
5568
+ default:
5569
+ return [];
5570
+ }
5571
+ }
5572
+ function buildSchemaFieldCreateExamples(type) {
5573
+ const definitions = getSchemaFieldTypeDefinitions();
5574
+ const selectedDefinition = resolveSchemaFieldType(type);
5575
+ const filteredDefinitions = selectedDefinition ? definitions.filter((definition) => definition.key === selectedDefinition.key) : definitions;
5576
+ const flat = filteredDefinitions.flatMap(
5577
+ (definition) => definition.examplePayloads.map((example) => ({ definition, example }))
5578
+ );
5579
+ return buildCommandExamples(
5580
+ flat.map(({ example }, index) => {
5581
+ const slug = typeof example.payload.slug === "string" ? example.payload.slug : "field";
5582
+ const command = `zinkee --json schemas fields create contacts --raw '${JSON.stringify(example.payload)}'`;
5583
+ if (index === 0) {
5584
+ return {
5585
+ description: example.name,
5586
+ command,
5587
+ response: `{
5588
+ "schemaId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
5589
+ "fieldId": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
5590
+ "slug": "${slug}"
5591
+ }`
5592
+ };
6120
5593
  }
6121
- ],
6122
- "createdAt": "2026-01-15T10:00:00Z",
6123
- "updatedAt": "2026-01-20T14:30:00Z",
6124
- "createdBy": "creator@example.com",
6125
- "updatedBy": "updater@example.com"
5594
+ return {
5595
+ description: example.name,
5596
+ command
5597
+ };
5598
+ })
5599
+ );
5600
+ }
5601
+ function getCommandExamples(commandName, filters = {}) {
5602
+ if (commandName === "schemas fields create") {
5603
+ return buildSchemaFieldCreateExamples(filters.type);
6126
5604
  }
6127
- ]`
6128
- }
6129
- ]),
6130
- "document-templates get": buildCommandExamples([
6131
- {
6132
- description: "Look up one template by UUID. The CLI filters the list endpoint locally (the backend does not expose a get-one route).",
6133
- command: "zinkee --json document-templates get 7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e",
6134
- response: `{
6135
- "id": "7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e",
6136
- "name": "Quarterly report",
6137
- "assets": [
6138
- {
6139
- "id": "9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f",
6140
- "name": "Requirements.docx",
6141
- "link": "/api/v2/document-templates/7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e/assets/9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f/download"
6142
- }
6143
- ],
6144
- "createdAt": "2026-01-15T10:00:00Z",
6145
- "updatedAt": "2026-01-20T14:30:00Z",
6146
- "createdBy": "creator@example.com",
6147
- "updatedBy": "creator@example.com"
6148
- }`
6149
- },
6150
- {
6151
- description: "Look up by exact template name. Names are unique within the workspace; ambiguity is reported as an error.",
6152
- command: 'zinkee --json document-templates get "Quarterly report"'
6153
- }
6154
- ]),
6155
- "document-templates create": buildCommandExamples([
6156
- {
6157
- description: "Typical create: empty template by name. Assets are uploaded afterwards via document-templates assets add.",
6158
- command: 'zinkee --json document-templates create --name "Quarterly report"',
6159
- raw: `{
6160
- "name": "Quarterly report",
6161
- "assets": []
6162
- }`,
6163
- response: `{
6164
- "id": "7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e",
6165
- "name": "Quarterly report",
6166
- "assets": [],
6167
- "createdAt": "2026-01-15T10:00:00Z",
6168
- "updatedAt": "2026-01-15T10:00:00Z",
6169
- "createdBy": "creator@example.com",
6170
- "updatedBy": "creator@example.com"
6171
- }`
6172
- },
6173
- {
6174
- description: "Create with pre-existing asset records via --raw. Used for import/migration flows where the assets already exist elsewhere; the typical UX is to create empty and upload via assets add.",
6175
- command: `zinkee --json document-templates create --raw '{"name":"Annual report","assets":[{"id":"9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f","name":"Cover.docx","link":"/existing/cover.docx"},{"id":"3f2e1d0c-9b8a-7654-3210-fedcba987654","name":"Appendix.docx","link":"/existing/appendix.docx"}]}'`,
6176
- raw: `{
6177
- "name": "Annual report",
6178
- "assets": [
6179
- {
6180
- "id": "9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f",
6181
- "name": "Cover.docx",
6182
- "link": "/existing/cover.docx"
6183
- },
6184
- {
6185
- "id": "3f2e1d0c-9b8a-7654-3210-fedcba987654",
6186
- "name": "Appendix.docx",
6187
- "link": "/existing/appendix.docx"
6188
- }
6189
- ]
6190
- }`
6191
- }
6192
- ]),
6193
- "document-templates update": buildCommandExamples([
6194
- {
6195
- description: "Rename a template. The template argument accepts a UUID or an exact current name. Only the name is updatable through this endpoint; assets are managed via the assets subcommands.",
6196
- command: 'zinkee --json document-templates update "Quarterly report" --name "Annual report"',
6197
- raw: `{
6198
- "name": "Annual report"
6199
- }`,
6200
- response: `{
6201
- "id": "7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e",
6202
- "name": "Annual report",
6203
- "assets": [
6204
- {
6205
- "id": "9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f",
6206
- "name": "Requirements.docx",
6207
- "link": "/api/v2/document-templates/7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e/assets/9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f/download"
6208
- }
6209
- ],
6210
- "createdAt": "2026-01-15T10:00:00Z",
6211
- "updatedAt": "2026-01-22T09:15:00Z",
6212
- "createdBy": "creator@example.com",
6213
- "updatedBy": "updater@example.com"
6214
- }`
6215
- }
6216
- ]),
6217
- "document-templates delete": buildCommandExamples([
6218
- {
6219
- description: "Delete a template and remove its asset files from storage. Record fields that reference previously generated documents are not modified.",
6220
- command: "zinkee --json document-templates delete 7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e",
6221
- response: `{
6222
- "id": "7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e",
6223
- "deleted": true
6224
- }`
6225
- }
6226
- ]),
6227
- "document-templates assets add": buildCommandExamples([
6228
- {
6229
- description: 'Upload a local file as an asset of a template. The CLI sends a multipart form with a part named "file"; the asset display name defaults to the uploaded filename.',
6230
- command: 'zinkee --json document-templates assets add "Quarterly report" ./contract.docx',
6231
- response: `{
6232
- "id": "7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e",
6233
- "name": "Quarterly report",
6234
- "assets": [
6235
- {
6236
- "id": "9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f",
6237
- "name": "contract.docx",
6238
- "link": "/api/v2/document-templates/7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e/assets/9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f/download"
6239
- }
6240
- ],
6241
- "createdAt": "2026-01-15T10:00:00Z",
6242
- "updatedAt": "2026-01-22T09:15:00Z",
6243
- "createdBy": "creator@example.com",
6244
- "updatedBy": "updater@example.com"
6245
- }`
6246
- },
6247
- {
6248
- description: "Override the asset display name with --name (otherwise the uploaded filename is used).",
6249
- command: 'zinkee --json document-templates assets add "Quarterly report" ./contract.docx --name "Customer Contract"'
6250
- }
6251
- ]),
6252
- "document-templates assets delete": buildCommandExamples([
6253
- {
6254
- description: "Delete one asset from a template and remove its file from storage.",
6255
- command: "zinkee --json document-templates assets delete 7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e 9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f",
6256
- response: `{
6257
- "id": "9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f",
6258
- "deleted": true
6259
- }`
6260
- }
6261
- ]),
6262
- "document-templates assets download": buildCommandExamples([
6263
- {
6264
- description: "Download asset bytes to disk. The CLI streams the raw bytes to --output; in --json mode --output is required and the JSON envelope only carries metadata.",
6265
- command: "zinkee --json document-templates assets download 7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e 9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f --output ./contract.docx"
6266
- },
6267
- {
6268
- description: "Stream asset bytes to stdout (omit --json and --output). Useful for piping into other tools.",
6269
- command: "zinkee document-templates assets download 7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e 9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f > contract.docx"
6270
- }
6271
- ])
6272
- };
6273
- function fallbackExamples(commandName) {
6274
- switch (commandName) {
6275
- default:
6276
- return [];
6277
- }
6278
- }
6279
- function buildSchemaFieldCreateExamples(type) {
6280
- const definitions = getSchemaFieldTypeDefinitions();
6281
- const selectedDefinition = resolveSchemaFieldType(type);
6282
- const filteredDefinitions = selectedDefinition ? definitions.filter((definition) => definition.key === selectedDefinition.key) : definitions;
6283
- const flat = filteredDefinitions.flatMap(
6284
- (definition) => definition.examplePayloads.map((example) => ({ definition, example }))
6285
- );
6286
- return buildCommandExamples(
6287
- flat.map(({ example }, index) => {
6288
- const slug = typeof example.payload.slug === "string" ? example.payload.slug : "field";
6289
- const command = `zinkee --json schemas fields create contacts --raw '${JSON.stringify(example.payload)}'`;
6290
- if (index === 0) {
6291
- return {
6292
- description: example.name,
6293
- command,
6294
- response: `{
6295
- "schemaId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
6296
- "fieldId": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
6297
- "slug": "${slug}"
6298
- }`
6299
- };
6300
- }
6301
- return {
6302
- description: example.name,
6303
- command
6304
- };
6305
- })
6306
- );
6307
- }
6308
- function getCommandExamples(commandName, filters = {}) {
6309
- if (commandName === "schemas fields create") {
6310
- return buildSchemaFieldCreateExamples(filters.type);
6311
- }
6312
- return specificExamples[commandName] ?? fallbackExamples(commandName);
6313
- }
6314
- function getResolvedCommandExamples(commandName, filters = {}) {
6315
- return getCommandExamples(commandName, filters);
6316
- }
6317
-
6318
- // src/cli-examples.ts
6319
- function getStdout(stdout) {
6320
- return stdout ?? process.stdout;
6321
- }
6322
- function extractExampleFilters(tokens) {
6323
- const filters = {};
6324
- for (let index = 0; index < tokens.length; index += 1) {
6325
- const token = tokens[index];
6326
- if (token === "--type") {
6327
- const value = tokens[index + 1];
6328
- if (value && !value.startsWith("-")) {
6329
- filters.type = value;
6330
- index += 1;
6331
- }
5605
+ return specificExamples[commandName] ?? fallbackExamples(commandName);
5606
+ }
5607
+ function getResolvedCommandExamples(commandName, filters = {}) {
5608
+ return getCommandExamples(commandName, filters);
5609
+ }
5610
+
5611
+ // src/cli-examples.ts
5612
+ function getStdout(stdout) {
5613
+ return stdout ?? process.stdout;
5614
+ }
5615
+ function extractExampleFilters(tokens) {
5616
+ const filters = {};
5617
+ for (let index = 0; index < tokens.length; index += 1) {
5618
+ const token = tokens[index];
5619
+ if (token === "--type") {
5620
+ const value = tokens[index + 1];
5621
+ if (value && !value.startsWith("-")) {
5622
+ filters.type = value;
5623
+ index += 1;
5624
+ }
6332
5625
  }
6333
5626
  }
6334
5627
  return filters;
@@ -6387,7 +5680,7 @@ ${index + 1}. ${example.description}
6387
5680
 
6388
5681
  // src/program.ts
6389
5682
  import { createRequire } from "module";
6390
- import { Command as Command11 } from "commander";
5683
+ import { Command as Command10 } from "commander";
6391
5684
 
6392
5685
  // src/config.ts
6393
5686
  import { mkdirSync, readFileSync, writeFileSync } from "fs";
@@ -6741,7 +6034,7 @@ var AutomationsApi = class {
6741
6034
  }
6742
6035
  moveAutomation(input) {
6743
6036
  return this.client.requestJson(
6744
- "/api/v2/automation-folders/automations:move",
6037
+ `/api/v2/automation-folders/${segment(input.targetFolderId)}/automations:move`,
6745
6038
  jsonOptions(input, "POST")
6746
6039
  );
6747
6040
  }
@@ -7148,11 +6441,11 @@ function hasSetPath(target, path) {
7148
6441
  return Object.hasOwn(target, path);
7149
6442
  }
7150
6443
  let current = target;
7151
- for (const segment4 of segments) {
7152
- if (!isJsonObject2(current) || !Object.hasOwn(current, segment4)) {
6444
+ for (const segment3 of segments) {
6445
+ if (!isJsonObject2(current) || !Object.hasOwn(current, segment3)) {
7153
6446
  return false;
7154
6447
  }
7155
- current = current[segment4];
6448
+ current = current[segment3];
7156
6449
  }
7157
6450
  return true;
7158
6451
  }
@@ -7615,15 +6908,6 @@ function buildActionInput(options, mode) {
7615
6908
  if (options.targetSchema !== void 0) {
7616
6909
  config.targetSchemaId = options.targetSchema;
7617
6910
  }
7618
- if (options.to !== void 0) {
7619
- mappings.recipients = options.to;
7620
- }
7621
- if (options.subject !== void 0) {
7622
- mappings.subject = options.subject;
7623
- }
7624
- if (options.message !== void 0) {
7625
- mappings.body = options.message;
7626
- }
7627
6911
  if (!isEmptyObject(mappings)) {
7628
6912
  config.fieldMapping = mappings;
7629
6913
  }
@@ -7667,12 +6951,6 @@ function buildActionInput(options, mode) {
7667
6951
  if (!isEmptyObject(args)) {
7668
6952
  config.pluginArgs = args;
7669
6953
  }
7670
- if (options.documentTemplate !== void 0) {
7671
- config.documentTemplateId = options.documentTemplate;
7672
- }
7673
- if (options.targetFileField !== void 0) {
7674
- config.targetFileFieldId = options.targetFileField;
7675
- }
7676
6954
  if (!isEmptyObject(config)) {
7677
6955
  if (isJsonObject2(config.fieldMapping)) {
7678
6956
  config.fieldMapping = normalizeAutomationFieldMapping(
@@ -7859,35 +7137,19 @@ function addTriggerPayloadOptions(command) {
7859
7137
  []
7860
7138
  ).option("--webhook-endpoint-id <uuid>", "webhook endpoint id").option("--raw <json>", "raw trigger JSON payload").option("--raw-file <path>", "path to raw trigger JSON payload");
7861
7139
  }
7862
- var ACTION_TYPES_HELP = `
7863
- Action types and their flags:
7864
- create_record --target-schema, --map, --map-json
7865
- update_record --target-schema, --use-trigger-record, --map,
7866
- --condition, --condition-json
7867
- search_records --target-schema, --condition, --condition-json
7868
- send_message --to, --subject, --message
7869
- (--map / --map-json also accepted for extra keys)
7870
- http_request --method, --url, --header, --body, --content-type,
7871
- --timeout-ms, --var, --auth-mode, --connection
7872
- execute_plugin --plugin, --arg, --arg-json
7873
- generate_document --document-template, --target-schema, --target-file-field
7874
- `;
7875
7140
  function addActionPayloadOptions(command) {
7876
- return command.option(
7877
- "--type <type>",
7878
- "action type (create_record|update_record|search_records|send_message|http_request|execute_plugin|generate_document)"
7879
- ).option("--name <name>", "action name").option("--target-schema <uuid>", "target schema id").option("--map <field=value>", "field mapping", collectValues, []).option("--map-json <field=json>", "JSON field mapping", collectValues, []).option("--condition <field:comparator:value>", "action condition", collectValues, []).option("--condition-json <json>", "action condition as JSON", collectValues, []).option("--use-trigger-record", "use the triggering record").option("--method <method>", "HTTP method").option("--url <url>", "HTTP target URL").option("--header <key=value>", "HTTP header", collectValues, []).option("--body <json>", "HTTP request body as JSON").option("--body-file <path>", "path to HTTP request body JSON").option("--content-type <type>", "HTTP content type").option(
7141
+ return command.option("--type <type>", "action type").option("--name <name>", "action name").option("--target-schema <uuid>", "target schema id").option("--map <field=value>", "field mapping", collectValues, []).option("--map-json <field=json>", "JSON field mapping", collectValues, []).option("--condition <field:comparator:value>", "action condition", collectValues, []).option("--condition-json <json>", "action condition as JSON", collectValues, []).option("--use-trigger-record", "use the triggering record").option("--method <method>", "HTTP method").option("--url <url>", "HTTP target URL").option("--header <key=value>", "HTTP header", collectValues, []).option("--body <json>", "HTTP request body as JSON").option("--body-file <path>", "path to HTTP request body JSON").option("--content-type <type>", "HTTP content type").option(
7880
7142
  "--timeout-ms <n>",
7881
7143
  "HTTP timeout in milliseconds",
7882
7144
  parseNonNegativeInteger
7883
- ).option("--var <key=value>", "HTTP variable", collectValues, []).option("--auth-mode <mode>", "HTTP auth mode").option("--connection <uuid>", "connection id for HTTP auth").option("--plugin <id>", "plugin id for execute_plugin").option("--arg <key=value>", "plugin argument", collectValues, []).option("--arg-json <key=json>", "plugin argument as JSON", collectValues, []).option("--to <recipient>", "send_message recipient (maps to fieldMapping.recipients)").option("--subject <text>", "send_message subject").option("--message <text>", "send_message body text (maps to fieldMapping.body)").option("--document-template <uuid>", "generate_document template id").option("--target-file-field <uuid>", "generate_document target FileField id").option("--raw <json>", "raw action JSON payload").option("--raw-file <path>", "path to raw action JSON payload").addHelpText("after", ACTION_TYPES_HELP);
7145
+ ).option("--var <key=value>", "HTTP variable", collectValues, []).option("--auth-mode <mode>", "HTTP auth mode").option("--connection <uuid>", "connection id for HTTP auth").option("--plugin <id>", "plugin id for execute_plugin").option("--arg <key=value>", "plugin argument", collectValues, []).option("--arg-json <key=json>", "plugin argument as JSON", collectValues, []).option("--raw <json>", "raw action JSON payload").option("--raw-file <path>", "path to raw action JSON payload");
7884
7146
  }
7885
7147
  function registerAutomationsCommands(program, options = {}) {
7886
7148
  const filePath = options.configPath ?? defaultConfigPath;
7887
7149
  const stdout = getCommandIo2(options.stdout);
7888
7150
  const automations = program.command("automations").description("Manage automations, triggers, actions, and connections");
7889
- const folders = automations.command("folders").description("Manage automation folders (flat: a folder only has a name, no order or properties)");
7890
- folders.command("list").description("List automation folders (non-root folders plus the root bucket, whose name is null)").action(async function action() {
7151
+ const folders = automations.command("folders").description("Manage automation folders");
7152
+ folders.command("list").description("List automation folders").action(async function action() {
7891
7153
  const { api, json } = createAutomationsApi(this, filePath);
7892
7154
  const data = await api.listFolders();
7893
7155
  if (json) {
@@ -7937,11 +7199,7 @@ function registerAutomationsCommands(program, options = {}) {
7937
7199
  }
7938
7200
  writeLine2(stdout, `Deleted automation folder "${folder.value}".`);
7939
7201
  });
7940
- folders.command("move").description("Move an automation into a folder").argument("<automation>", "automation UUID", parseUuidOrSlugSelector).requiredOption(
7941
- "--to <folder>",
7942
- "target folder UUID or exact name (use the root folder to move it out of any folder)",
7943
- parseUuidOrSlugSelector
7944
- ).action(async function action(automation, commandOptions) {
7202
+ folders.command("move").description("Move an automation into a folder").argument("<automation>", "automation UUID", parseUuidOrSlugSelector).requiredOption("--to <folder>", "target folder UUID or exact name", parseUuidOrSlugSelector).action(async function action(automation, commandOptions) {
7945
7203
  const { api, json, readOnly } = createAutomationsApi(this, filePath);
7946
7204
  ensureWritable("automations folders move", readOnly, "write");
7947
7205
  if (!commandOptions.to) {
@@ -8626,117 +7884,9 @@ var DisplaysApi = class {
8626
7884
  { method: "DELETE" }
8627
7885
  );
8628
7886
  }
8629
- listFolders() {
8630
- return this.client.getJson("/api/v2/display-folders");
8631
- }
8632
- createFolder(body) {
8633
- return this.client.requestJson(
8634
- "/api/v2/display-folders",
8635
- jsonOptions3(body, "POST")
8636
- );
8637
- }
8638
- updateFolder(folder, body) {
8639
- return this.client.requestJson(
8640
- `/api/v2/display-folders/${selectorValue3(folder)}`,
8641
- jsonOptions3(body, "PATCH")
8642
- );
8643
- }
8644
- deleteFolder(folder) {
8645
- return this.client.requestJson(
8646
- `/api/v2/display-folders/${selectorValue3(folder)}`,
8647
- { method: "DELETE" }
8648
- );
8649
- }
8650
- moveDisplay(input) {
8651
- return this.client.requestJson(
8652
- "/api/v2/display-folders/displays:move",
8653
- jsonOptions3(input, "POST")
8654
- );
8655
- }
8656
7887
  };
8657
7888
 
8658
- // src/parsers/expressions.ts
8659
- var supportedComparators = /* @__PURE__ */ new Set([
8660
- "eq",
8661
- "neq",
8662
- "gt",
8663
- "gte",
8664
- "lt",
8665
- "lte",
8666
- "contains",
8667
- "in",
8668
- "is_empty",
8669
- "is_not_empty"
8670
- ]);
8671
- var noValueComparators = /* @__PURE__ */ new Set(["is_empty", "is_not_empty"]);
8672
- function parseColonExpression(input) {
8673
- const parts = input.split(":");
8674
- if (parts.length < 2) {
8675
- throw new Error(`Expected a field:comparator[:value] expression, got "${input}".`);
8676
- }
8677
- const field = parts[0]?.trim();
8678
- const comparator = parts[1]?.trim();
8679
- if (!field) {
8680
- throw new Error(`Expected a field before ":", got "${input}".`);
8681
- }
8682
- if (!comparator) {
8683
- throw new Error(`Expected a comparator after "${field}:", got "${input}".`);
8684
- }
8685
- return [field, comparator, parts.slice(2).join(":").trim()];
8686
- }
8687
- function parseSpaceExpression(input) {
8688
- const parts = input.trim().split(/\s+/);
8689
- if (parts.length < 2) {
8690
- throw new Error(`Expected a field comparator expression, got "${input}".`);
8691
- }
8692
- const field = parts[0];
8693
- const comparator = parts[1];
8694
- if (!field) {
8695
- throw new Error(`Expected a field comparator expression, got "${input}".`);
8696
- }
8697
- if (!comparator) {
8698
- throw new Error(`Expected a comparator after "${field}", got "${input}".`);
8699
- }
8700
- return [field.trim(), comparator.trim(), parts.slice(2).join(" ").trim()];
8701
- }
8702
- function normalizeValue(comparator, rawValue) {
8703
- if (noValueComparators.has(comparator)) {
8704
- if (rawValue.length > 0) {
8705
- throw new Error(`Comparator "${comparator}" does not accept a value.`);
8706
- }
8707
- return null;
8708
- }
8709
- if (comparator === "in") {
8710
- const values = rawValue.split(",").map((value) => value.trim()).filter(Boolean);
8711
- if (values.length === 0) {
8712
- throw new Error(`Comparator "${comparator}" requires at least one value.`);
8713
- }
8714
- return values;
8715
- }
8716
- if (rawValue.length === 0) {
8717
- throw new Error(`Comparator "${comparator}" requires a value.`);
8718
- }
8719
- return rawValue;
8720
- }
8721
- function parseExpression(input) {
8722
- const trimmed = input.trim();
8723
- const [field, comparatorCandidate, rawValue] = trimmed.includes(":") && !trimmed.includes(" ") ? parseColonExpression(trimmed) : parseSpaceExpression(trimmed);
8724
- if (!supportedComparators.has(comparatorCandidate)) {
8725
- throw new Error(
8726
- `Unsupported comparator "${comparatorCandidate}" in expression "${input}".`
8727
- );
8728
- }
8729
- const comparator = comparatorCandidate;
8730
- return {
8731
- field,
8732
- comparator,
8733
- value: normalizeValue(comparator, rawValue),
8734
- raw: trimmed
8735
- };
8736
- }
8737
-
8738
7889
  // src/commands/displays.ts
8739
- var DATE_DYNAMIC_OPTIONS = "today, thisWeek, thisMonth, thisQuarter, thisSemester, thisYear, next7Days, next30Days, next6Months, next12Months, last12Months";
8740
7890
  function getCommandIo4(stdout) {
8741
7891
  return stdout ?? process.stdout;
8742
7892
  }
@@ -8800,37 +7950,6 @@ function parseUuidOrSlugSelector3(input) {
8800
7950
  throw new InvalidArgumentError3(message);
8801
7951
  }
8802
7952
  }
8803
- var COMPARATOR_TO_DISPLAY_OPERATOR = {
8804
- eq: "EQUAL",
8805
- neq: "NOT_EQUAL",
8806
- gt: "GREATER",
8807
- gte: "GREATER_OR_EQUAL",
8808
- lt: "LESS",
8809
- lte: "LESS_OR_EQUAL",
8810
- contains: "CONTAINS",
8811
- in: "ANY_OF",
8812
- is_empty: "IS_EMPTY",
8813
- is_not_empty: "IS_NOT_EMPTY"
8814
- };
8815
- function toDisplayFilter(parsed) {
8816
- const values = parsed.value === null ? [] : Array.isArray(parsed.value) ? [...parsed.value] : [parsed.value];
8817
- return {
8818
- origin: { fieldId: parsed.field },
8819
- comparisonOperator: COMPARATOR_TO_DISPLAY_OPERATOR[parsed.comparator],
8820
- values
8821
- };
8822
- }
8823
- function parseFilterExpression(input) {
8824
- try {
8825
- return parseExpression(input);
8826
- } catch (error) {
8827
- const message = error instanceof Error ? error.message : "Invalid filter expression.";
8828
- throw new InvalidArgumentError3(message);
8829
- }
8830
- }
8831
- function collectFilters(value, previous = []) {
8832
- return [...previous, parseFilterExpression(value)];
8833
- }
8834
7953
  function readRawObject2(raw, rawFile) {
8835
7954
  if (raw && rawFile) {
8836
7955
  throw new CliError("invalid_cli_usage", 'Use either "--raw" or "--raw-file", not both.');
@@ -8865,189 +7984,20 @@ function readNamedJsonOption(raw, rawFile, inlineFlag = "--option", fileFlag = "
8865
7984
  function isEmptyObject3(value) {
8866
7985
  return Object.keys(value).length === 0;
8867
7986
  }
8868
- function isPlainObject(value) {
8869
- return typeof value === "object" && value !== null && !Array.isArray(value);
7987
+ function displayRows(displays) {
7988
+ return displays.map((display) => ({
7989
+ id: display.id,
7990
+ name: display.name ?? "",
7991
+ layoutTemplate: display.layoutTemplate ?? "",
7992
+ variableCount: display.variableCount ?? "",
7993
+ widgetCount: display.widgetCount ?? ""
7994
+ }));
8870
7995
  }
8871
- function deepMerge(target, source) {
8872
- const out = { ...target };
8873
- for (const [key, value] of Object.entries(source)) {
8874
- const existing = out[key];
8875
- out[key] = isPlainObject(existing) && isPlainObject(value) ? deepMerge(existing, value) : value;
7996
+ function getDisplaySubresource(value) {
7997
+ if (!Array.isArray(value)) {
7998
+ return [];
8876
7999
  }
8877
- return out;
8878
- }
8879
- function assignDefined(target, key, value) {
8880
- if (value !== void 0) target[key] = value;
8881
- }
8882
- function readNamedJsonObject(raw, rawFile, inlineFlag, fileFlag) {
8883
- const parsed = readNamedJsonOption(raw, rawFile, inlineFlag, fileFlag);
8884
- if (parsed === void 0) return void 0;
8885
- if (!isPlainObject(parsed)) {
8886
- throw new CliError("invalid_cli_usage", `${inlineFlag} payload must be a JSON object.`);
8887
- }
8888
- return parsed;
8889
- }
8890
- var HIERARCHY_AGGREGATIONS = /* @__PURE__ */ new Set([
8891
- "SUM",
8892
- "AVERAGE",
8893
- "MINIMUM",
8894
- "MAXIMUM",
8895
- "COUNT",
8896
- "COUNT_DISTINCT"
8897
- ]);
8898
- function parseHierarchyInfo(value) {
8899
- const idx = value.indexOf(":");
8900
- if (idx <= 0 || idx === value.length - 1) {
8901
- throw new CliError("invalid_cli_usage", `--hierarchy-info "${value}" must use the format <id:name>.`);
8902
- }
8903
- return { id: value.slice(0, idx).trim(), name: value.slice(idx + 1).trim() };
8904
- }
8905
- function parseHierarchyNumber(value) {
8906
- const parts = value.split(":");
8907
- if (parts.length < 3) {
8908
- throw new CliError(
8909
- "invalid_cli_usage",
8910
- `--hierarchy-number "${value}" must use the format <id:name:aggregation>.`
8911
- );
8912
- }
8913
- const id = parts[0]?.trim() ?? "";
8914
- const aggregation = (parts[parts.length - 1]?.trim() ?? "").toUpperCase();
8915
- const name = parts.slice(1, -1).join(":").trim();
8916
- if (!id || !name) {
8917
- throw new CliError(
8918
- "invalid_cli_usage",
8919
- `--hierarchy-number "${value}" must use the format <id:name:aggregation>.`
8920
- );
8921
- }
8922
- if (!HIERARCHY_AGGREGATIONS.has(aggregation)) {
8923
- throw new CliError(
8924
- "invalid_cli_usage",
8925
- `--hierarchy-number aggregation "${aggregation}" must be one of SUM, AVERAGE, MINIMUM, MAXIMUM, COUNT, COUNT_DISTINCT.`
8926
- );
8927
- }
8928
- return { id, name, aggregation };
8929
- }
8930
- function parseHierarchyMapping(value, flag) {
8931
- const idx = value.indexOf(":");
8932
- if (idx <= 0 || idx === value.length - 1) {
8933
- throw new CliError("invalid_cli_usage", `${flag} "${value}" must use the format <columnId:fieldId>.`);
8934
- }
8935
- return { columnId: value.slice(0, idx).trim(), fieldId: value.slice(idx + 1).trim() };
8936
- }
8937
- function buildWidgetFieldMapping(options) {
8938
- const mapping = {};
8939
- assignDefined(mapping, "columnField", options.columnField);
8940
- assignDefined(mapping, "swimlaneField", options.swimlaneField);
8941
- assignDefined(mapping, "startDateField", options.startDateField);
8942
- assignDefined(mapping, "endDateField", options.endDateField);
8943
- assignDefined(mapping, "labelField", options.labelField);
8944
- assignDefined(mapping, "groupField", options.groupField);
8945
- assignDefined(mapping, "subgroupField", options.subgroupField);
8946
- assignDefined(mapping, "progressField", options.progressField);
8947
- const cardConfig = {};
8948
- assignDefined(cardConfig, "titleField", options.cardTitleField);
8949
- assignDefined(cardConfig, "category1Field", options.cardCategory1Field);
8950
- assignDefined(cardConfig, "category2Field", options.cardCategory2Field);
8951
- assignDefined(cardConfig, "category3Field", options.cardCategory3Field);
8952
- assignDefined(cardConfig, "category4Field", options.cardCategory4Field);
8953
- assignDefined(cardConfig, "descriptionField", options.cardDescriptionField);
8954
- if (Object.keys(cardConfig).length > 0) mapping.cardConfig = cardConfig;
8955
- const aggregationConfig = {};
8956
- assignDefined(aggregationConfig, "method", options.aggregationMethod);
8957
- assignDefined(aggregationConfig, "fieldId", options.aggregationField);
8958
- if (Object.keys(aggregationConfig).length > 0) mapping.aggregationConfig = aggregationConfig;
8959
- return Object.keys(mapping).length > 0 ? mapping : void 0;
8960
- }
8961
- function buildHierarchyConfig(options) {
8962
- const base = readNamedJsonObject(
8963
- options.hierarchyConfig,
8964
- options.hierarchyConfigFile,
8965
- "--hierarchy-config",
8966
- "--hierarchy-config-file"
8967
- );
8968
- const patch = {};
8969
- const columns = {};
8970
- assignDefined(columns, "label", options.hierarchyLabel);
8971
- if (options.hierarchyInfo && options.hierarchyInfo.length > 0) {
8972
- columns.infos = options.hierarchyInfo.map(parseHierarchyInfo);
8973
- }
8974
- if (options.hierarchyNumber && options.hierarchyNumber.length > 0) {
8975
- columns.numbers = options.hierarchyNumber.map(parseHierarchyNumber);
8976
- }
8977
- if (Object.keys(columns).length > 0) patch.columns = columns;
8978
- const rootLevel = {};
8979
- assignDefined(rootLevel, "name", options.hierarchyRootName);
8980
- assignDefined(rootLevel, "labelFieldId", options.hierarchyRootLabelField);
8981
- if (options.hierarchyRootInfo && options.hierarchyRootInfo.length > 0) {
8982
- rootLevel.infoMappings = options.hierarchyRootInfo.map(
8983
- (entry) => parseHierarchyMapping(entry, "--hierarchy-root-info")
8984
- );
8985
- }
8986
- if (options.hierarchyRootNumber && options.hierarchyRootNumber.length > 0) {
8987
- rootLevel.numberMappings = options.hierarchyRootNumber.map(
8988
- (entry) => parseHierarchyMapping(entry, "--hierarchy-root-number")
8989
- );
8990
- }
8991
- if (Object.keys(rootLevel).length > 0) patch.rootLevel = rootLevel;
8992
- if (options.hierarchyChild && options.hierarchyChild.length > 0) {
8993
- patch.childLevels = options.hierarchyChild.map((entry, index) => {
8994
- let parsed;
8995
- try {
8996
- parsed = JSON.parse(entry);
8997
- } catch {
8998
- throw new CliError("invalid_cli_usage", `--hierarchy-child payload #${index + 1} is invalid JSON.`);
8999
- }
9000
- if (!isPlainObject(parsed)) {
9001
- throw new CliError(
9002
- "invalid_cli_usage",
9003
- `--hierarchy-child payload #${index + 1} must be a JSON object.`
9004
- );
9005
- }
9006
- return parsed;
9007
- });
9008
- }
9009
- if (base === void 0 && Object.keys(patch).length === 0) return void 0;
9010
- return deepMerge(base ?? {}, patch);
9011
- }
9012
- function displayRows(displays) {
9013
- return displays.map((display) => ({
9014
- id: display.id,
9015
- name: display.name ?? "",
9016
- layoutTemplate: display.layoutTemplate ?? "",
9017
- variableCount: display.variableCount ?? "",
9018
- widgetCount: display.widgetCount ?? ""
9019
- }));
9020
- }
9021
- function getDisplaySubresource(value) {
9022
- if (!Array.isArray(value)) {
9023
- return [];
9024
- }
9025
- return value.filter((entry) => Boolean(entry) && typeof entry === "object");
9026
- }
9027
- function displayFolderRows(folders) {
9028
- return folders.map((folder) => ({
9029
- id: folder.id ?? "",
9030
- name: folder.name ?? "",
9031
- isRoot: folder.isRoot ?? "",
9032
- displayCount: folder.displayCount ?? ""
9033
- }));
9034
- }
9035
- async function resolveDisplayFolderId(api, selector) {
9036
- if (selector.kind === "uuid") {
9037
- return selector.value;
9038
- }
9039
- const folders = await api.listFolders();
9040
- const matches = folders.filter((folder) => folder.name === selector.value);
9041
- if (matches.length === 1 && typeof matches[0]?.id === "string" && matches[0].id.length > 0) {
9042
- return matches[0].id;
9043
- }
9044
- if (matches.length > 1) {
9045
- throw new CliError(
9046
- "invalid_cli_usage",
9047
- `Folder "${selector.value}" is ambiguous. Found ${matches.length} matches.`
9048
- );
9049
- }
9050
- throw new CliError("invalid_cli_usage", `Folder "${selector.value}" was not found.`);
8000
+ return value.filter((entry) => Boolean(entry) && typeof entry === "object");
9051
8001
  }
9052
8002
  function buildVariableBody(options) {
9053
8003
  const body = {
@@ -9066,7 +8016,7 @@ function buildVariableBody(options) {
9066
8016
  };
9067
8017
  }
9068
8018
  if (options.filter && options.filter.length > 0) {
9069
- body.filters = options.filter.map(toDisplayFilter);
8019
+ body.filters = options.filter.map((entry) => ({ raw: entry }));
9070
8020
  }
9071
8021
  if (options.dateMode || options.dateDynamicOption || options.dateSpecific || options.dateRangeStart || options.dateRangeEnd) {
9072
8022
  body.date = {
@@ -9115,39 +8065,15 @@ function buildWidgetBody(options) {
9115
8065
  layout
9116
8066
  };
9117
8067
  }
9118
- const viewPatch = {};
9119
- if (options.field && options.field.length > 0) {
9120
- viewPatch.fields = options.field;
9121
- }
9122
- const fieldMapping = buildWidgetFieldMapping(options);
9123
- const viewStateBase = readNamedJsonObject(
9124
- options.viewState,
9125
- options.viewStateFile,
9126
- "--view-state",
9127
- "--view-state-file"
9128
- );
9129
- let viewState = viewStateBase ? { ...viewStateBase } : void 0;
9130
- if (fieldMapping) {
9131
- viewState = deepMerge(viewState ?? {}, { fieldMapping });
9132
- }
9133
- if (viewState !== void 0) {
9134
- viewPatch.viewAdditionalProperties = { viewState };
9135
- }
9136
- const hierarchyConfig = buildHierarchyConfig(options);
9137
- if (hierarchyConfig !== void 0) {
9138
- viewPatch.hierarchyConfig = hierarchyConfig;
9139
- }
9140
- if (Object.keys(viewPatch).length > 0) {
9141
- const existingView = typeof body.view === "object" && body.view ? body.view : {};
9142
- body.view = deepMerge(existingView, viewPatch);
9143
- }
9144
- const queryMerge = {};
9145
- if (options.sort && options.sort.length > 0) queryMerge.sorts = options.sort;
9146
- if (options.filter && options.filter.length > 0) queryMerge.filters = options.filter.map(toDisplayFilter);
9147
- if (Object.keys(queryMerge).length > 0) {
8068
+ if (options.field?.length || options.sort?.length || options.filter?.length) {
8069
+ body.view = {
8070
+ ...typeof body.view === "object" && body.view ? body.view : {},
8071
+ fields: options.field
8072
+ };
9148
8073
  body.query = {
9149
8074
  ...typeof body.query === "object" && body.query ? body.query : {},
9150
- ...queryMerge
8075
+ sorts: options.sort,
8076
+ filters: options.filter?.map((entry) => ({ raw: entry }))
9151
8077
  };
9152
8078
  }
9153
8079
  if (options.widgetReadOnly !== void 0 || options.hideAddButton !== void 0 || options.hideDeleteButton !== void 0 || options.hideSortButton !== void 0 || options.hideFilterButton !== void 0 || options.hideSeeButton !== void 0) {
@@ -9274,72 +8200,6 @@ function registerDisplaysCommands(program, options = {}) {
9274
8200
  }
9275
8201
  writeLine4(stdout, `Deleted display "${display.value}".`);
9276
8202
  });
9277
- const folders = displays.command("folders").description("Manage display folders (flat: a folder only has a name, no order or properties)");
9278
- folders.command("list").description("List display folders (non-root folders plus the root bucket, whose name is null)").action(async function action() {
9279
- const { api, json } = createDisplaysApi(this, filePath);
9280
- const data = await api.listFolders();
9281
- if (json) {
9282
- emitJson4(stdout, "displays folders list", data);
9283
- return;
9284
- }
9285
- printTable(displayFolderRows(data), ["id", "name", "isRoot", "displayCount"], stdout);
9286
- });
9287
- folders.command("create").description("Create a display folder").requiredOption("--name <name>", "folder name").action(async function action(commandOptions) {
9288
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9289
- ensureWritable3("displays folders create", readOnly, "write");
9290
- if (commandOptions.name === void 0) {
9291
- throw new CliError("invalid_cli_usage", 'Provide folder name via "--name".');
9292
- }
9293
- const data = await api.createFolder({ name: commandOptions.name });
9294
- if (json) {
9295
- emitJson4(stdout, "displays folders create", data);
9296
- return;
9297
- }
9298
- writeLine4(stdout, `Created display folder "${String(data.name ?? commandOptions.name)}".`);
9299
- });
9300
- 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) {
9301
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9302
- ensureWritable3("displays folders update", readOnly, "write");
9303
- if (commandOptions.name === void 0) {
9304
- throw new CliError("invalid_cli_usage", 'Provide folder name via "--name".');
9305
- }
9306
- const folderId = await resolveDisplayFolderId(api, folder);
9307
- const data = await api.updateFolder({ kind: "uuid", value: folderId }, { name: commandOptions.name });
9308
- if (json) {
9309
- emitJson4(stdout, "displays folders update", data);
9310
- return;
9311
- }
9312
- writeLine4(stdout, `Updated display folder "${String(data.name ?? folder.value)}".`);
9313
- });
9314
- 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) {
9315
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9316
- ensureWritable3("displays folders delete", readOnly, "destructive");
9317
- const folderId = await resolveDisplayFolderId(api, folder);
9318
- const data = await api.deleteFolder({ kind: "uuid", value: folderId });
9319
- if (json) {
9320
- emitJson4(stdout, "displays folders delete", data);
9321
- return;
9322
- }
9323
- writeLine4(stdout, `Deleted display folder "${folder.value}".`);
9324
- });
9325
- folders.command("move").description("Move a display into a folder").argument("<display>", "display UUID", parseUuidOrSlugSelector3).requiredOption(
9326
- "--to <folder>",
9327
- "target folder UUID or exact name (use the root folder to move it out of any folder)",
9328
- parseUuidOrSlugSelector3
9329
- ).action(async function action(display, commandOptions) {
9330
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9331
- ensureWritable3("displays folders move", readOnly, "write");
9332
- if (!commandOptions.to) {
9333
- throw new CliError("invalid_cli_usage", 'Provide target folder via "--to".');
9334
- }
9335
- const targetFolderId = await resolveDisplayFolderId(api, commandOptions.to);
9336
- const data = await api.moveDisplay({ displayId: display.value, targetFolderId });
9337
- if (json) {
9338
- emitJson4(stdout, "displays folders move", data);
9339
- return;
9340
- }
9341
- writeLine4(stdout, `Moved display "${display.value}" to folder "${targetFolderId}".`);
9342
- });
9343
8203
  const layout = displays.command("layout").description("Manage display layout");
9344
8204
  layout.command("get").description("Get display layout").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).action(async function action(display) {
9345
8205
  const { api, json } = createDisplaysApi(this, filePath);
@@ -9428,7 +8288,7 @@ function registerDisplaysCommands(program, options = {}) {
9428
8288
  }
9429
8289
  printTable([match], void 0, stdout);
9430
8290
  });
9431
- variables.command("create").description("Create variable").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).option("--type <type>").option("--name <name>").option("--allow-multiple").option("--static").option("--default <value>").option("--default-value <value>", "repeatable default value", (v, p = []) => [...p, v], []).option("--source-schema <id>").option("--source-field <id>").option("--filter <expr>", "repeatable filter", collectFilters, []).option("--date-mode <mode>").option("--date-dynamic-option <option>", `dynamic date period (${DATE_DYNAMIC_OPTIONS})`).option("--date-specific <iso>").option("--date-range-start <iso>").option("--date-range-end <iso>").option("--raw <json>").option("--raw-file <path>").action(async function action(display, commandOptions) {
8291
+ variables.command("create").description("Create variable").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).option("--type <type>").option("--name <name>").option("--allow-multiple").option("--static").option("--default <value>").option("--default-value <value>", "repeatable default value", (v, p = []) => [...p, v], []).option("--source-schema <id>").option("--source-field <id>").option("--filter <expr>", "repeatable filter", (v, p = []) => [...p, v], []).option("--date-mode <mode>").option("--date-dynamic-option <option>").option("--date-specific <iso>").option("--date-range-start <iso>").option("--date-range-end <iso>").option("--raw <json>").option("--raw-file <path>").action(async function action(display, commandOptions) {
9432
8292
  const { api, json, readOnly } = createDisplaysApi(this, filePath);
9433
8293
  ensureWritable3("displays variables create", readOnly, "write");
9434
8294
  const data = await api.createVariable(display, buildVariableBody(commandOptions));
@@ -9438,7 +8298,7 @@ function registerDisplaysCommands(program, options = {}) {
9438
8298
  }
9439
8299
  writeLine4(stdout, `Created variable on display "${display.value}".`);
9440
8300
  });
9441
- variables.command("update").description("Update variable").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).argument("<variable>", "variable id").option("--type <type>").option("--name <name>").option("--allow-multiple").option("--static").option("--default <value>").option("--default-value <value>", "repeatable default value", (v, p = []) => [...p, v], []).option("--source-schema <id>").option("--source-field <id>").option("--filter <expr>", "repeatable filter", collectFilters, []).option("--date-mode <mode>").option("--date-dynamic-option <option>", `dynamic date period (${DATE_DYNAMIC_OPTIONS})`).option("--date-specific <iso>").option("--date-range-start <iso>").option("--date-range-end <iso>").option("--raw <json>").option("--raw-file <path>").action(async function action(display, variableId, commandOptions) {
8301
+ variables.command("update").description("Update variable").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).argument("<variable>", "variable id").option("--type <type>").option("--name <name>").option("--allow-multiple").option("--static").option("--default <value>").option("--default-value <value>", "repeatable default value", (v, p = []) => [...p, v], []).option("--source-schema <id>").option("--source-field <id>").option("--filter <expr>", "repeatable filter", (v, p = []) => [...p, v], []).option("--date-mode <mode>").option("--date-dynamic-option <option>").option("--date-specific <iso>").option("--date-range-start <iso>").option("--date-range-end <iso>").option("--raw <json>").option("--raw-file <path>").action(async function action(display, variableId, commandOptions) {
9442
8302
  const { api, json, readOnly } = createDisplaysApi(this, filePath);
9443
8303
  ensureWritable3("displays variables update", readOnly, "write");
9444
8304
  const data = await api.updateVariable(display, variableId, buildVariableBody(commandOptions));
@@ -9475,523 +8335,120 @@ function registerDisplaysCommands(program, options = {}) {
9475
8335
  if (json) {
9476
8336
  emitJson4(stdout, "displays widgets get", data);
9477
8337
  return;
9478
- }
9479
- printTable([data], void 0, stdout);
9480
- });
9481
- 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) {
9482
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9483
- ensureWritable3("displays widgets create", readOnly, "write");
9484
- const data = await api.createWidget(display, buildWidgetBody(commandOptions));
9485
- if (json) {
9486
- emitJson4(stdout, "displays widgets create", data);
9487
- return;
9488
- }
9489
- writeLine4(stdout, `Created widget on display "${display.value}".`);
9490
- });
9491
- 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) {
9492
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9493
- ensureWritable3("displays widgets update", readOnly, "write");
9494
- const data = await api.updateWidget(display, widgetId, buildWidgetBody(commandOptions));
9495
- if (json) {
9496
- emitJson4(stdout, "displays widgets update", data);
9497
- return;
9498
- }
9499
- writeLine4(stdout, `Updated widget "${widgetId}".`);
9500
- });
9501
- widgets.command("delete").description("Delete widget").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).argument("<widget>", "widget id").action(async function action(display, widgetId) {
9502
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9503
- ensureWritable3("displays widgets delete", readOnly, "destructive");
9504
- const data = await api.deleteWidget(display, widgetId);
9505
- if (json) {
9506
- emitJson4(stdout, "displays widgets delete", data);
9507
- return;
9508
- }
9509
- writeLine4(stdout, `Deleted widget "${widgetId}".`);
9510
- });
9511
- const targets = displays.command("navigation-targets").description("Manage navigation targets");
9512
- targets.command("list").description("List navigation targets").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).action(async function action(display) {
9513
- const { api, json } = createDisplaysApi(this, filePath);
9514
- const data = await api.getDisplay(display);
9515
- const items = getDisplaySubresource(data.navigationTargets);
9516
- if (json) {
9517
- emitJson4(stdout, "displays navigation-targets list", items);
9518
- return;
9519
- }
9520
- printTable(items, void 0, stdout);
9521
- });
9522
- targets.command("create").description("Create navigation target").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).requiredOption("--source-widget <id>").requiredOption("--target-display <id>").requiredOption("--target-variable <id>").option("--label <label>").action(async function action(display, commandOptions) {
9523
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9524
- ensureWritable3("displays navigation-targets create", readOnly, "write");
9525
- const data = await api.createNavigationTarget(display, buildNavigationTargetBody(commandOptions));
9526
- if (json) {
9527
- emitJson4(stdout, "displays navigation-targets create", data);
9528
- return;
9529
- }
9530
- writeLine4(stdout, `Created navigation target on display "${display.value}".`);
9531
- });
9532
- targets.command("update").description("Update navigation target").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).argument("<target>", "target id").option("--source-widget <id>").option("--target-display <id>").option("--target-variable <id>").option("--label <label>").action(async function action(display, targetId, commandOptions) {
9533
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9534
- ensureWritable3("displays navigation-targets update", readOnly, "write");
9535
- const data = await api.updateNavigationTarget(display, targetId, buildNavigationTargetBody(commandOptions));
9536
- if (json) {
9537
- emitJson4(stdout, "displays navigation-targets update", data);
9538
- return;
9539
- }
9540
- writeLine4(stdout, `Updated navigation target "${targetId}".`);
9541
- });
9542
- targets.command("delete").description("Delete navigation target").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).argument("<target>", "target id").action(async function action(display, targetId) {
9543
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9544
- ensureWritable3("displays navigation-targets delete", readOnly, "destructive");
9545
- const data = await api.deleteNavigationTarget(display, targetId);
9546
- if (json) {
9547
- emitJson4(stdout, "displays navigation-targets delete", data);
9548
- return;
9549
- }
9550
- writeLine4(stdout, `Deleted navigation target "${targetId}".`);
9551
- });
9552
- const cross = displays.command("cross-widget-filter").description("Manage cross widget filter");
9553
- cross.command("get").description("Get cross widget filter").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).action(async function action(display) {
9554
- const { api, json } = createDisplaysApi(this, filePath);
9555
- const data = await api.getDisplay(display);
9556
- const item = data.crossWidgetFilter ?? null;
9557
- if (json) {
9558
- emitJson4(stdout, "displays cross-widget-filter get", item);
9559
- return;
9560
- }
9561
- printTable(item ? [item] : [], void 0, stdout);
9562
- });
9563
- cross.command("set").description("Set cross widget filter").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).requiredOption("--source-widget <id>").requiredOption("--source-field <id>").requiredOption("--target <widget:field>", "repeatable target", (v, p = []) => [...p, v], []).action(async function action(display, commandOptions) {
9564
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9565
- ensureWritable3("displays cross-widget-filter set", readOnly, "write");
9566
- const data = await api.setCrossWidgetFilter(display, buildCrossWidgetFilterBody(commandOptions));
9567
- if (json) {
9568
- emitJson4(stdout, "displays cross-widget-filter set", data);
9569
- return;
9570
- }
9571
- writeLine4(stdout, `Updated cross widget filter for display "${display.value}".`);
9572
- });
9573
- cross.command("delete").description("Delete cross widget filter").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).action(async function action(display) {
9574
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9575
- ensureWritable3("displays cross-widget-filter delete", readOnly, "destructive");
9576
- const data = await api.deleteCrossWidgetFilter(display);
9577
- if (json) {
9578
- emitJson4(stdout, "displays cross-widget-filter delete", data);
9579
- return;
9580
- }
9581
- writeLine4(stdout, `Deleted cross widget filter for display "${display.value}".`);
9582
- });
9583
- }
9584
-
9585
- // src/commands/document-templates.ts
9586
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
9587
- import { basename } from "path";
9588
- import { InvalidArgumentError as InvalidArgumentError4 } from "commander";
9589
-
9590
- // src/api/document-templates.ts
9591
- function jsonOptions4(body, method) {
9592
- return {
9593
- method,
9594
- headers: {
9595
- "content-type": "application/json"
9596
- },
9597
- body: JSON.stringify(body)
9598
- };
9599
- }
9600
- function selectorValue4(selector) {
9601
- return encodeURIComponent(selector.value);
9602
- }
9603
- function segment3(value) {
9604
- return encodeURIComponent(value);
9605
- }
9606
- var DocumentTemplatesApi = class {
9607
- constructor(client) {
9608
- this.client = client;
9609
- }
9610
- listTemplates() {
9611
- return this.client.getJson("/api/v2/document-templates");
9612
- }
9613
- createTemplate(input) {
9614
- return this.client.requestJson(
9615
- "/api/v2/document-templates",
9616
- jsonOptions4(input, "POST")
9617
- );
9618
- }
9619
- updateTemplate(template, input) {
9620
- return this.client.requestJson(
9621
- `/api/v2/document-templates/${selectorValue4(template)}`,
9622
- jsonOptions4(input, "PATCH")
9623
- );
9624
- }
9625
- deleteTemplate(template) {
9626
- return this.client.requestJson(
9627
- `/api/v2/document-templates/${selectorValue4(template)}`,
9628
- { method: "DELETE" }
9629
- );
9630
- }
9631
- addAsset(template, input) {
9632
- return this.client.requestJson(
9633
- `/api/v2/document-templates/${selectorValue4(template)}/assets`,
9634
- { method: "POST", body: input }
9635
- );
9636
- }
9637
- deleteAsset(template, assetId) {
9638
- return this.client.requestJson(
9639
- `/api/v2/document-templates/${selectorValue4(template)}/assets/${segment3(assetId)}`,
9640
- { method: "DELETE" }
9641
- );
9642
- }
9643
- downloadAsset(template, assetId) {
9644
- return this.client.requestBinary(
9645
- `/api/v2/document-templates/${selectorValue4(template)}/assets/${segment3(assetId)}/download`
9646
- );
9647
- }
9648
- };
9649
-
9650
- // src/commands/document-templates.ts
9651
- function getCommandIo5(stdout) {
9652
- return stdout ?? process.stdout;
9653
- }
9654
- function writeLine5(stdout, value) {
9655
- stdout.write(`${value}
9656
- `);
9657
- }
9658
- function writeBinary(stdout, value) {
9659
- stdout.write(Buffer.from(value));
9660
- }
9661
- function getGlobalOptions5(command) {
9662
- return command.optsWithGlobals();
9663
- }
9664
- function emitJson5(stdout, commandName, data, configPath, meta = {}) {
9665
- writeLine5(
9666
- stdout,
9667
- JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath, ...meta }))
9668
- );
9669
- }
9670
- function toConfigurationError5(filePath, error) {
9671
- if (error instanceof CliError) {
9672
- throw error;
9673
- }
9674
- if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
9675
- throw new CliError("configuration_error", `Config file not found at ${filePath}.`);
9676
- }
9677
- if (error instanceof Error) {
9678
- throw new CliError("configuration_error", error.message);
9679
- }
9680
- throw error;
9681
- }
9682
- function createDocumentTemplatesApi(command, filePath) {
9683
- try {
9684
- const config = readRuntimeConfig(filePath);
9685
- const runtime = resolveRuntimeContext(config, getGlobalOptions5(command));
9686
- if (!runtime.baseUrl) {
9687
- throw new CliError(
9688
- "configuration_error",
9689
- `Resolved profile "${runtime.profile}" is missing a base URL.`
9690
- );
9691
- }
9692
- return {
9693
- api: new DocumentTemplatesApi(
9694
- new ApiClient({
9695
- baseUrl: runtime.baseUrl,
9696
- apiKey: runtime.apiKey
9697
- })
9698
- ),
9699
- json: runtime.json,
9700
- readOnly: runtime.readOnly
9701
- };
9702
- } catch (error) {
9703
- toConfigurationError5(filePath, error);
9704
- }
9705
- }
9706
- function ensureWritable4(commandName, readOnly, commandMode) {
9707
- if (readOnly) {
9708
- throw new CliError(
9709
- "command_not_allowed_in_read_only_mode",
9710
- `Command "${commandName}" is not allowed in read-only mode.`,
9711
- {
9712
- commandMode,
9713
- executionMode: "read-only"
9714
- }
9715
- );
9716
- }
9717
- }
9718
- function parseUuidOrSlugSelector4(input) {
9719
- try {
9720
- return normalizeUuidOrSlug(input);
9721
- } catch (error) {
9722
- const message = error instanceof Error ? error.message : "Invalid selector.";
9723
- throw new InvalidArgumentError4(message);
9724
- }
9725
- }
9726
- function isJsonObject4(value) {
9727
- return typeof value === "object" && value !== null && !Array.isArray(value);
9728
- }
9729
- function isEmptyObject4(value) {
9730
- return Object.keys(value).length === 0;
9731
- }
9732
- function parseJsonValue2(input, sourceLabel) {
9733
- try {
9734
- return JSON.parse(input);
9735
- } catch (error) {
9736
- const message = error instanceof Error ? error.message : "Invalid JSON.";
9737
- throw new CliError(
9738
- "invalid_cli_usage",
9739
- `Failed to parse JSON from ${sourceLabel}: ${message}`
9740
- );
9741
- }
9742
- }
9743
- function readTextFile2(filePath, label) {
9744
- try {
9745
- return readFileSync5(filePath, "utf8");
9746
- } catch (error) {
9747
- const message = error instanceof Error ? error.message : "Unable to read file.";
9748
- throw new CliError(
9749
- "invalid_cli_usage",
9750
- `Failed to read ${label} from ${filePath}: ${message}`
9751
- );
9752
- }
9753
- }
9754
- function readJsonObjectOption2(raw, rawFile, rawLabel, rawFileLabel) {
9755
- if (raw && rawFile) {
9756
- throw new CliError(
9757
- "invalid_cli_usage",
9758
- `Provide either "${rawLabel}" or "${rawFileLabel}", not both.`
9759
- );
9760
- }
9761
- let parsed;
9762
- if (raw) {
9763
- parsed = parseJsonValue2(raw, rawLabel);
9764
- } else if (rawFile) {
9765
- parsed = parseJsonValue2(readTextFile2(rawFile, rawFileLabel), `${rawFileLabel} ${rawFile}`);
9766
- } else {
9767
- return {};
9768
- }
9769
- if (!isJsonObject4(parsed)) {
9770
- throw new CliError(
9771
- "invalid_cli_usage",
9772
- `Expected ${raw ? rawLabel : rawFileLabel} to contain a JSON object.`
9773
- );
9774
- }
9775
- return parsed;
9776
- }
9777
- function readLocalFile(filePath) {
9778
- try {
9779
- return readFileSync5(filePath);
9780
- } catch (error) {
9781
- const message = error instanceof Error ? error.message : "Unable to read file.";
9782
- throw new CliError("invalid_cli_usage", `Failed to read file at ${filePath}: ${message}`);
9783
- }
9784
- }
9785
- function writeDownloadedFile(outputPath, value) {
9786
- try {
9787
- writeFileSync2(outputPath, Buffer.from(value));
9788
- } catch (error) {
9789
- const message = error instanceof Error ? error.message : "Unable to write file.";
9790
- throw new CliError(
9791
- "invalid_cli_usage",
9792
- `Failed to write downloaded file to ${outputPath}: ${message}`
9793
- );
9794
- }
9795
- }
9796
- function templateRows(templates) {
9797
- return templates.map((template) => ({
9798
- id: template.id ?? "",
9799
- name: template.name ?? "",
9800
- assetCount: Array.isArray(template.assets) ? template.assets.length : 0,
9801
- updatedAt: template.updatedAt ?? ""
9802
- }));
9803
- }
9804
- function resolveTemplate(templates, selector) {
9805
- if (selector.kind === "uuid") {
9806
- const match = templates.find((template) => template.id === selector.value);
9807
- if (match) {
9808
- return match;
9809
- }
9810
- throw new CliError(
9811
- "invalid_cli_usage",
9812
- `Document template "${selector.value}" was not found.`
9813
- );
9814
- }
9815
- const matches = templates.filter((template) => template.name === selector.value);
9816
- if (matches.length === 1) {
9817
- return matches[0];
9818
- }
9819
- if (matches.length > 1) {
9820
- throw new CliError(
9821
- "invalid_cli_usage",
9822
- `Document template "${selector.value}" is ambiguous. Found ${matches.length} matches.`
9823
- );
9824
- }
9825
- throw new CliError(
9826
- "invalid_cli_usage",
9827
- `Document template "${selector.value}" was not found.`
9828
- );
9829
- }
9830
- async function resolveTemplateSelector(api, selector) {
9831
- if (selector.kind === "uuid") {
9832
- return selector;
9833
- }
9834
- const templates = await api.listTemplates();
9835
- const resolved = resolveTemplate(templates, selector);
9836
- if (typeof resolved.id !== "string" || resolved.id.length === 0) {
9837
- throw new CliError(
9838
- "invalid_cli_usage",
9839
- `Document template "${selector.value}" is missing an id in the API response.`
9840
- );
9841
- }
9842
- return { kind: "uuid", value: resolved.id };
9843
- }
9844
- function buildCreateInput(options) {
9845
- const raw = readJsonObjectOption2(options.raw, options.rawFile, "--raw", "--raw-file");
9846
- const input = { ...raw };
9847
- if (options.name !== void 0) {
9848
- input.name = options.name;
9849
- }
9850
- if (typeof input.name !== "string" || input.name.trim().length === 0) {
9851
- throw new CliError("invalid_cli_usage", 'Provide template name via "--name".');
9852
- }
9853
- if (input.assets === void 0) {
9854
- input.assets = [];
9855
- }
9856
- return input;
9857
- }
9858
- function buildUpdateInput(options) {
9859
- const input = {};
9860
- if (options.name !== void 0) {
9861
- input.name = options.name;
9862
- }
9863
- if (isEmptyObject4(input)) {
9864
- throw new CliError("invalid_cli_usage", 'Provide template updates via "--name".');
9865
- }
9866
- return input;
9867
- }
9868
- function registerDocumentTemplatesCommands(program, options = {}) {
9869
- const filePath = options.configPath ?? defaultConfigPath;
9870
- const stdout = getCommandIo5(options.stdout);
9871
- const templates = program.command("document-templates").description("Manage document templates and their assets");
9872
- templates.command("list").description("List document templates").action(async function action() {
9873
- const { api, json } = createDocumentTemplatesApi(this, filePath);
9874
- const data = await api.listTemplates();
8338
+ }
8339
+ printTable([data], void 0, stdout);
8340
+ });
8341
+ 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", (v, p = []) => [...p, v], []).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>").option("--x-axis-field <uuid>").option("--x-axis-date-format <granularity>").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) {
8342
+ const { api, json, readOnly } = createDisplaysApi(this, filePath);
8343
+ ensureWritable3("displays widgets create", readOnly, "write");
8344
+ const data = await api.createWidget(display, buildWidgetBody(commandOptions));
9875
8345
  if (json) {
9876
- emitJson5(stdout, "document-templates list", data, filePath);
8346
+ emitJson4(stdout, "displays widgets create", data);
9877
8347
  return;
9878
8348
  }
9879
- printTable(templateRows(data), ["id", "name", "assetCount", "updatedAt"], stdout);
8349
+ writeLine4(stdout, `Created widget on display "${display.value}".`);
9880
8350
  });
9881
- templates.command("get").description("Get a document template by UUID or exact name").argument("<template>", "template UUID or exact name", parseUuidOrSlugSelector4).action(async function action(template) {
9882
- const { api, json } = createDocumentTemplatesApi(this, filePath);
9883
- const list = await api.listTemplates();
9884
- const data = resolveTemplate(list, template);
8351
+ 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", (v, p = []) => [...p, v], []).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>").option("--x-axis-field <uuid>").option("--x-axis-date-format <granularity>").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) {
8352
+ const { api, json, readOnly } = createDisplaysApi(this, filePath);
8353
+ ensureWritable3("displays widgets update", readOnly, "write");
8354
+ const data = await api.updateWidget(display, widgetId, buildWidgetBody(commandOptions));
9885
8355
  if (json) {
9886
- emitJson5(stdout, "document-templates get", data, filePath);
8356
+ emitJson4(stdout, "displays widgets update", data);
9887
8357
  return;
9888
8358
  }
9889
- printTable([data], void 0, stdout);
8359
+ writeLine4(stdout, `Updated widget "${widgetId}".`);
9890
8360
  });
9891
- templates.command("create").description("Create a document template").option("--name <name>", "template name").option("--raw <json>", "raw create JSON payload").option("--raw-file <path>", "path to raw create JSON payload").action(async function action(commandOptions) {
9892
- const { api, json, readOnly } = createDocumentTemplatesApi(this, filePath);
9893
- ensureWritable4("document-templates create", readOnly, "write");
9894
- const data = await api.createTemplate(buildCreateInput(commandOptions));
8361
+ widgets.command("delete").description("Delete widget").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).argument("<widget>", "widget id").action(async function action(display, widgetId) {
8362
+ const { api, json, readOnly } = createDisplaysApi(this, filePath);
8363
+ ensureWritable3("displays widgets delete", readOnly, "destructive");
8364
+ const data = await api.deleteWidget(display, widgetId);
9895
8365
  if (json) {
9896
- emitJson5(stdout, "document-templates create", data, filePath);
8366
+ emitJson4(stdout, "displays widgets delete", data);
9897
8367
  return;
9898
8368
  }
9899
- writeLine5(stdout, `Created document template "${String(data.name ?? commandOptions.name)}".`);
8369
+ writeLine4(stdout, `Deleted widget "${widgetId}".`);
9900
8370
  });
9901
- templates.command("update").description("Rename a document template").argument("<template>", "template UUID or exact name", parseUuidOrSlugSelector4).option("--name <name>", "new template name").action(async function action(template, commandOptions) {
9902
- const { api, json, readOnly } = createDocumentTemplatesApi(this, filePath);
9903
- ensureWritable4("document-templates update", readOnly, "write");
9904
- const resolved = await resolveTemplateSelector(api, template);
9905
- const data = await api.updateTemplate(resolved, buildUpdateInput(commandOptions));
8371
+ const targets = displays.command("navigation-targets").description("Manage navigation targets");
8372
+ targets.command("list").description("List navigation targets").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).action(async function action(display) {
8373
+ const { api, json } = createDisplaysApi(this, filePath);
8374
+ const data = await api.getDisplay(display);
8375
+ const items = getDisplaySubresource(data.navigationTargets);
9906
8376
  if (json) {
9907
- emitJson5(stdout, "document-templates update", data, filePath);
8377
+ emitJson4(stdout, "displays navigation-targets list", items);
9908
8378
  return;
9909
8379
  }
9910
- writeLine5(stdout, `Updated document template "${String(data.name ?? template.value)}".`);
8380
+ printTable(items, void 0, stdout);
9911
8381
  });
9912
- templates.command("delete").description("Delete a document template (and its assets)").argument("<template>", "template UUID or exact name", parseUuidOrSlugSelector4).action(async function action(template) {
9913
- const { api, json, readOnly } = createDocumentTemplatesApi(this, filePath);
9914
- ensureWritable4("document-templates delete", readOnly, "destructive");
9915
- const resolved = await resolveTemplateSelector(api, template);
9916
- const data = await api.deleteTemplate(resolved);
8382
+ targets.command("create").description("Create navigation target").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).requiredOption("--source-widget <id>").requiredOption("--target-display <id>").requiredOption("--target-variable <id>").option("--label <label>").action(async function action(display, commandOptions) {
8383
+ const { api, json, readOnly } = createDisplaysApi(this, filePath);
8384
+ ensureWritable3("displays navigation-targets create", readOnly, "write");
8385
+ const data = await api.createNavigationTarget(display, buildNavigationTargetBody(commandOptions));
9917
8386
  if (json) {
9918
- emitJson5(stdout, "document-templates delete", data, filePath);
8387
+ emitJson4(stdout, "displays navigation-targets create", data);
9919
8388
  return;
9920
8389
  }
9921
- writeLine5(stdout, `Deleted document template "${template.value}".`);
8390
+ writeLine4(stdout, `Created navigation target on display "${display.value}".`);
9922
8391
  });
9923
- const assets = templates.command("assets").description("Manage document template assets");
9924
- assets.command("add").description("Upload an asset file to a document template").argument("<template>", "template UUID or exact name", parseUuidOrSlugSelector4).argument("<path>", "path to the local file").option("--name <name>", "override the asset display name").action(async function action(template, localPath, commandOptions) {
9925
- const { api, json, readOnly } = createDocumentTemplatesApi(this, filePath);
9926
- ensureWritable4("document-templates assets add", readOnly, "write");
9927
- const contents = readLocalFile(localPath);
9928
- const formData = new FormData();
9929
- formData.append("file", new Blob([contents]), basename(localPath));
9930
- if (commandOptions.name !== void 0) {
9931
- formData.append("name", commandOptions.name);
8392
+ targets.command("update").description("Update navigation target").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).argument("<target>", "target id").option("--source-widget <id>").option("--target-display <id>").option("--target-variable <id>").option("--label <label>").action(async function action(display, targetId, commandOptions) {
8393
+ const { api, json, readOnly } = createDisplaysApi(this, filePath);
8394
+ ensureWritable3("displays navigation-targets update", readOnly, "write");
8395
+ const data = await api.updateNavigationTarget(display, targetId, buildNavigationTargetBody(commandOptions));
8396
+ if (json) {
8397
+ emitJson4(stdout, "displays navigation-targets update", data);
8398
+ return;
9932
8399
  }
9933
- const resolved = await resolveTemplateSelector(api, template);
9934
- const data = await api.addAsset(resolved, formData);
8400
+ writeLine4(stdout, `Updated navigation target "${targetId}".`);
8401
+ });
8402
+ targets.command("delete").description("Delete navigation target").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).argument("<target>", "target id").action(async function action(display, targetId) {
8403
+ const { api, json, readOnly } = createDisplaysApi(this, filePath);
8404
+ ensureWritable3("displays navigation-targets delete", readOnly, "destructive");
8405
+ const data = await api.deleteNavigationTarget(display, targetId);
9935
8406
  if (json) {
9936
- emitJson5(stdout, "document-templates assets add", data, filePath);
8407
+ emitJson4(stdout, "displays navigation-targets delete", data);
9937
8408
  return;
9938
8409
  }
9939
- writeLine5(
9940
- stdout,
9941
- `Added asset "${commandOptions.name ?? basename(localPath)}" to template "${template.value}".`
9942
- );
8410
+ writeLine4(stdout, `Deleted navigation target "${targetId}".`);
9943
8411
  });
9944
- assets.command("delete").description("Delete one asset from a document template").argument("<template>", "template UUID or exact name", parseUuidOrSlugSelector4).argument("<asset>", "asset UUID").action(async function action(template, assetId) {
9945
- const { api, json, readOnly } = createDocumentTemplatesApi(this, filePath);
9946
- ensureWritable4("document-templates assets delete", readOnly, "destructive");
9947
- const resolved = await resolveTemplateSelector(api, template);
9948
- const data = await api.deleteAsset(resolved, assetId);
8412
+ const cross = displays.command("cross-widget-filter").description("Manage cross widget filter");
8413
+ cross.command("get").description("Get cross widget filter").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).action(async function action(display) {
8414
+ const { api, json } = createDisplaysApi(this, filePath);
8415
+ const data = await api.getDisplay(display);
8416
+ const item = data.crossWidgetFilter ?? null;
9949
8417
  if (json) {
9950
- emitJson5(stdout, "document-templates assets delete", data, filePath);
8418
+ emitJson4(stdout, "displays cross-widget-filter get", item);
9951
8419
  return;
9952
8420
  }
9953
- writeLine5(stdout, `Deleted asset "${assetId}" from template "${template.value}".`);
8421
+ printTable(item ? [item] : [], void 0, stdout);
9954
8422
  });
9955
- assets.command("download").description("Download the raw bytes of a document template asset").argument("<template>", "template UUID or exact name", parseUuidOrSlugSelector4).argument("<asset>", "asset UUID").option("--output <path>", "write the downloaded bytes to a path").action(async function action(template, assetId, commandOptions) {
9956
- const { api, json } = createDocumentTemplatesApi(this, filePath);
9957
- if (json && !commandOptions.output) {
9958
- throw new CliError(
9959
- "invalid_cli_usage",
9960
- 'Provide "--output" when using "--json" with "document-templates assets download".'
9961
- );
8423
+ cross.command("set").description("Set cross widget filter").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).requiredOption("--source-widget <id>").requiredOption("--source-field <id>").requiredOption("--target <widget:field>", "repeatable target", (v, p = []) => [...p, v], []).action(async function action(display, commandOptions) {
8424
+ const { api, json, readOnly } = createDisplaysApi(this, filePath);
8425
+ ensureWritable3("displays cross-widget-filter set", readOnly, "write");
8426
+ const data = await api.setCrossWidgetFilter(display, buildCrossWidgetFilterBody(commandOptions));
8427
+ if (json) {
8428
+ emitJson4(stdout, "displays cross-widget-filter set", data);
8429
+ return;
9962
8430
  }
9963
- const resolved = await resolveTemplateSelector(api, template);
9964
- const data = await api.downloadAsset(resolved, assetId);
9965
- if (commandOptions.output) {
9966
- writeDownloadedFile(commandOptions.output, data);
9967
- if (json) {
9968
- emitJson5(
9969
- stdout,
9970
- "document-templates assets download",
9971
- {
9972
- template: resolved.value,
9973
- asset: assetId,
9974
- output: commandOptions.output,
9975
- bytes: data.byteLength
9976
- },
9977
- filePath
9978
- );
9979
- return;
9980
- }
9981
- writeLine5(stdout, `Downloaded asset to "${commandOptions.output}".`);
8431
+ writeLine4(stdout, `Updated cross widget filter for display "${display.value}".`);
8432
+ });
8433
+ cross.command("delete").description("Delete cross widget filter").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).action(async function action(display) {
8434
+ const { api, json, readOnly } = createDisplaysApi(this, filePath);
8435
+ ensureWritable3("displays cross-widget-filter delete", readOnly, "destructive");
8436
+ const data = await api.deleteCrossWidgetFilter(display);
8437
+ if (json) {
8438
+ emitJson4(stdout, "displays cross-widget-filter delete", data);
9982
8439
  return;
9983
8440
  }
9984
- writeBinary(stdout, data);
8441
+ writeLine4(stdout, `Deleted cross widget filter for display "${display.value}".`);
9985
8442
  });
9986
8443
  }
9987
8444
 
9988
8445
  // src/commands/files.ts
9989
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "fs";
9990
- import { basename as basename2 } from "path";
9991
- import { InvalidArgumentError as InvalidArgumentError5 } from "commander";
8446
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
8447
+ import { basename } from "path";
8448
+ import { InvalidArgumentError as InvalidArgumentError4 } from "commander";
9992
8449
 
9993
8450
  // src/api/files.ts
9994
- function selectorValue5(selector) {
8451
+ function selectorValue4(selector) {
9995
8452
  return selector.value;
9996
8453
  }
9997
8454
  var FilesApi = class {
@@ -10005,11 +8462,11 @@ var FilesApi = class {
10005
8462
  });
10006
8463
  }
10007
8464
  downloadFile(file) {
10008
- return this.client.requestBinary(`/api/v2/files/${selectorValue5(file)}`);
8465
+ return this.client.requestBinary(`/api/v2/files/${selectorValue4(file)}`);
10009
8466
  }
10010
8467
  deleteFile(file) {
10011
8468
  return this.client.requestJson(
10012
- `/api/v2/files/${selectorValue5(file)}`,
8469
+ `/api/v2/files/${selectorValue4(file)}`,
10013
8470
  { method: "DELETE" }
10014
8471
  );
10015
8472
  }
@@ -10019,26 +8476,26 @@ var FilesApi = class {
10019
8476
  };
10020
8477
 
10021
8478
  // src/commands/files.ts
10022
- function getCommandIo6(stdout) {
8479
+ function getCommandIo5(stdout) {
10023
8480
  return stdout ?? process.stdout;
10024
8481
  }
10025
- function writeLine6(stdout, value) {
8482
+ function writeLine5(stdout, value) {
10026
8483
  stdout.write(`${value}
10027
8484
  `);
10028
8485
  }
10029
- function writeBinary2(stdout, value) {
8486
+ function writeBinary(stdout, value) {
10030
8487
  stdout.write(Buffer.from(value));
10031
8488
  }
10032
- function getGlobalOptions6(command) {
8489
+ function getGlobalOptions5(command) {
10033
8490
  return command.optsWithGlobals();
10034
8491
  }
10035
- function emitJson6(stdout, commandName, data, configPath, meta = {}) {
10036
- writeLine6(
8492
+ function emitJson5(stdout, commandName, data, configPath, meta = {}) {
8493
+ writeLine5(
10037
8494
  stdout,
10038
8495
  JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath, ...meta }))
10039
8496
  );
10040
8497
  }
10041
- function toConfigurationError6(filePath, error) {
8498
+ function toConfigurationError5(filePath, error) {
10042
8499
  if (error instanceof CliError) {
10043
8500
  throw error;
10044
8501
  }
@@ -10053,7 +8510,7 @@ function toConfigurationError6(filePath, error) {
10053
8510
  function createFilesApi(command, filePath) {
10054
8511
  try {
10055
8512
  const config = readRuntimeConfig(filePath);
10056
- const runtime = resolveRuntimeContext(config, getGlobalOptions6(command));
8513
+ const runtime = resolveRuntimeContext(config, getGlobalOptions5(command));
10057
8514
  if (!runtime.baseUrl) {
10058
8515
  throw new CliError(
10059
8516
  "configuration_error",
@@ -10071,10 +8528,10 @@ function createFilesApi(command, filePath) {
10071
8528
  readOnly: runtime.readOnly
10072
8529
  };
10073
8530
  } catch (error) {
10074
- toConfigurationError6(filePath, error);
8531
+ toConfigurationError5(filePath, error);
10075
8532
  }
10076
8533
  }
10077
- function ensureWritable5(commandName, readOnly, commandMode) {
8534
+ function ensureWritable4(commandName, readOnly, commandMode) {
10078
8535
  if (readOnly) {
10079
8536
  throw new CliError(
10080
8537
  "command_not_allowed_in_read_only_mode",
@@ -10086,28 +8543,28 @@ function ensureWritable5(commandName, readOnly, commandMode) {
10086
8543
  );
10087
8544
  }
10088
8545
  }
10089
- function parseUuidOrSlugSelector5(input) {
8546
+ function parseUuidOrSlugSelector4(input) {
10090
8547
  try {
10091
8548
  return normalizeUuidOrSlug(input);
10092
8549
  } catch (error) {
10093
8550
  const message = error instanceof Error ? error.message : "Invalid selector.";
10094
- throw new InvalidArgumentError5(message);
8551
+ throw new InvalidArgumentError4(message);
10095
8552
  }
10096
8553
  }
10097
8554
  function isRecord3(value) {
10098
8555
  return typeof value === "object" && value !== null && !Array.isArray(value);
10099
8556
  }
10100
- function readLocalFile2(filePath) {
8557
+ function readLocalFile(filePath) {
10101
8558
  try {
10102
- return readFileSync6(filePath);
8559
+ return readFileSync5(filePath);
10103
8560
  } catch (error) {
10104
8561
  const message = error instanceof Error ? error.message : "Unable to read file.";
10105
8562
  throw new CliError("invalid_cli_usage", `Failed to read file at ${filePath}: ${message}`);
10106
8563
  }
10107
8564
  }
10108
- function writeDownloadedFile2(outputPath, value) {
8565
+ function writeDownloadedFile(outputPath, value) {
10109
8566
  try {
10110
- writeFileSync3(outputPath, Buffer.from(value));
8567
+ writeFileSync2(outputPath, Buffer.from(value));
10111
8568
  } catch (error) {
10112
8569
  const message = error instanceof Error ? error.message : "Unable to write file.";
10113
8570
  throw new CliError(
@@ -10118,20 +8575,20 @@ function writeDownloadedFile2(outputPath, value) {
10118
8575
  }
10119
8576
  function registerFilesCommands(program, options = {}) {
10120
8577
  const filePath = options.configPath ?? defaultConfigPath;
10121
- const stdout = getCommandIo6(options.stdout);
8578
+ const stdout = getCommandIo5(options.stdout);
10122
8579
  const files = program.command("files").description("Manage files and storage");
10123
8580
  files.command("upload").description("Upload a local file").argument("<path>", "path to the local file").action(function action(path) {
10124
8581
  const { api, json, readOnly } = createFilesApi(this, filePath);
10125
- ensureWritable5("files upload", readOnly, "write");
10126
- const contents = readLocalFile2(path);
8582
+ ensureWritable4("files upload", readOnly, "write");
8583
+ const contents = readLocalFile(path);
10127
8584
  const formData = new FormData();
10128
- formData.append("file", new Blob([contents]), basename2(path));
8585
+ formData.append("file", new Blob([contents]), basename(path));
10129
8586
  return api.uploadFile(formData).then((data) => {
10130
8587
  if (json) {
10131
- emitJson6(stdout, "files upload", data, filePath);
8588
+ emitJson5(stdout, "files upload", data, filePath);
10132
8589
  return;
10133
8590
  }
10134
- writeLine6(stdout, `Uploaded file "${basename2(path)}".`);
8591
+ writeLine5(stdout, `Uploaded file "${basename(path)}".`);
10135
8592
  });
10136
8593
  });
10137
8594
  files.command("download").description("Download a file").argument("<file>", "file identifier").option("--output <path>", "write the downloaded file to a path").action(function action(file, commandOptions) {
@@ -10142,12 +8599,12 @@ function registerFilesCommands(program, options = {}) {
10142
8599
  'Provide "--output" when using "--json" with "files download".'
10143
8600
  );
10144
8601
  }
10145
- const fileSelector = parseUuidOrSlugSelector5(file);
8602
+ const fileSelector = parseUuidOrSlugSelector4(file);
10146
8603
  return api.downloadFile(fileSelector).then((data) => {
10147
8604
  if (commandOptions.output) {
10148
- writeDownloadedFile2(commandOptions.output, data);
8605
+ writeDownloadedFile(commandOptions.output, data);
10149
8606
  if (json) {
10150
- emitJson6(
8607
+ emitJson5(
10151
8608
  stdout,
10152
8609
  "files download",
10153
8610
  {
@@ -10159,45 +8616,45 @@ function registerFilesCommands(program, options = {}) {
10159
8616
  );
10160
8617
  return;
10161
8618
  }
10162
- writeLine6(stdout, `Downloaded file to "${commandOptions.output}".`);
8619
+ writeLine5(stdout, `Downloaded file to "${commandOptions.output}".`);
10163
8620
  return;
10164
8621
  }
10165
- writeBinary2(stdout, data);
8622
+ writeBinary(stdout, data);
10166
8623
  });
10167
8624
  });
10168
8625
  files.command("delete").description("Delete a file").argument("<file>", "file identifier").action(function action(file) {
10169
8626
  const { api, json, readOnly } = createFilesApi(this, filePath);
10170
- ensureWritable5("files delete", readOnly, "destructive");
10171
- const fileSelector = parseUuidOrSlugSelector5(file);
8627
+ ensureWritable4("files delete", readOnly, "destructive");
8628
+ const fileSelector = parseUuidOrSlugSelector4(file);
10172
8629
  return api.deleteFile(fileSelector).then((data) => {
10173
8630
  if (json) {
10174
- emitJson6(stdout, "files delete", data, filePath);
8631
+ emitJson5(stdout, "files delete", data, filePath);
10175
8632
  return;
10176
8633
  }
10177
- writeLine6(stdout, `Deleted file "${fileSelector.value}".`);
8634
+ writeLine5(stdout, `Deleted file "${fileSelector.value}".`);
10178
8635
  });
10179
8636
  });
10180
8637
  files.command("storage").description("Show storage usage information").action(function action() {
10181
8638
  const { api, json } = createFilesApi(this, filePath);
10182
8639
  return api.getStorageInfo().then((data) => {
10183
8640
  if (json) {
10184
- emitJson6(stdout, "files storage", data, filePath);
8641
+ emitJson5(stdout, "files storage", data, filePath);
10185
8642
  return;
10186
8643
  }
10187
8644
  if (isRecord3(data)) {
10188
8645
  printTable([data], Object.keys(data), stdout);
10189
8646
  return;
10190
8647
  }
10191
- writeLine6(stdout, String(data));
8648
+ writeLine5(stdout, String(data));
10192
8649
  });
10193
8650
  });
10194
8651
  }
10195
8652
 
10196
8653
  // src/commands/logs.ts
10197
- import { InvalidArgumentError as InvalidArgumentError6 } from "commander";
8654
+ import { InvalidArgumentError as InvalidArgumentError5 } from "commander";
10198
8655
 
10199
8656
  // src/api/logs.ts
10200
- function selectorValue6(selector) {
8657
+ function selectorValue5(selector) {
10201
8658
  return selector.value;
10202
8659
  }
10203
8660
  var LogsApi = class {
@@ -10206,29 +8663,29 @@ var LogsApi = class {
10206
8663
  }
10207
8664
  listLogs(schema, recordId) {
10208
8665
  return this.client.getJson(
10209
- `/api/v2/schemas/${selectorValue6(schema)}/records/${recordId}/logs`
8666
+ `/api/v2/schemas/${selectorValue5(schema)}/records/${recordId}/logs`
10210
8667
  );
10211
8668
  }
10212
8669
  };
10213
8670
 
10214
8671
  // src/commands/logs.ts
10215
- function getCommandIo7(stdout) {
8672
+ function getCommandIo6(stdout) {
10216
8673
  return stdout ?? process.stdout;
10217
8674
  }
10218
- function writeLine7(stdout, value) {
8675
+ function writeLine6(stdout, value) {
10219
8676
  stdout.write(`${value}
10220
8677
  `);
10221
8678
  }
10222
- function getGlobalOptions7(command) {
8679
+ function getGlobalOptions6(command) {
10223
8680
  return command.optsWithGlobals();
10224
8681
  }
10225
- function emitJson7(stdout, commandName, data, ..._extra) {
10226
- writeLine7(
8682
+ function emitJson6(stdout, commandName, data, ..._extra) {
8683
+ writeLine6(
10227
8684
  stdout,
10228
8685
  JSON.stringify(buildJsonSuccess(data, { command: commandName }))
10229
8686
  );
10230
8687
  }
10231
- function toConfigurationError7(filePath, error) {
8688
+ function toConfigurationError6(filePath, error) {
10232
8689
  if (error instanceof CliError) {
10233
8690
  throw error;
10234
8691
  }
@@ -10243,7 +8700,7 @@ function toConfigurationError7(filePath, error) {
10243
8700
  function createLogsApi(command, filePath) {
10244
8701
  try {
10245
8702
  const config = readRuntimeConfig(filePath);
10246
- const runtime = resolveRuntimeContext(config, getGlobalOptions7(command));
8703
+ const runtime = resolveRuntimeContext(config, getGlobalOptions6(command));
10247
8704
  if (!runtime.baseUrl) {
10248
8705
  throw new CliError(
10249
8706
  "configuration_error",
@@ -10260,25 +8717,25 @@ function createLogsApi(command, filePath) {
10260
8717
  json: runtime.json
10261
8718
  };
10262
8719
  } catch (error) {
10263
- toConfigurationError7(filePath, error);
8720
+ toConfigurationError6(filePath, error);
10264
8721
  }
10265
8722
  }
10266
- function parseUuidOrSlugSelector6(input) {
8723
+ function parseUuidOrSlugSelector5(input) {
10267
8724
  try {
10268
8725
  return normalizeUuidOrSlug(input);
10269
8726
  } catch (error) {
10270
8727
  const message = error instanceof Error ? error.message : "Invalid selector.";
10271
- throw new InvalidArgumentError6(message);
8728
+ throw new InvalidArgumentError5(message);
10272
8729
  }
10273
8730
  }
10274
- function isJsonObject5(value) {
8731
+ function isJsonObject4(value) {
10275
8732
  return typeof value === "object" && value !== null && !Array.isArray(value);
10276
8733
  }
10277
8734
  function toTableRows3(data) {
10278
8735
  if (Array.isArray(data)) {
10279
- return data.map((entry) => isJsonObject5(entry) ? entry : { value: entry });
8736
+ return data.map((entry) => isJsonObject4(entry) ? entry : { value: entry });
10280
8737
  }
10281
- if (isJsonObject5(data)) {
8738
+ if (isJsonObject4(data)) {
10282
8739
  return [data];
10283
8740
  }
10284
8741
  return [{ value: data }];
@@ -10288,13 +8745,13 @@ function emitTable3(stdout, data) {
10288
8745
  }
10289
8746
  function registerLogsCommands(program, options = {}) {
10290
8747
  const filePath = options.configPath ?? defaultConfigPath;
10291
- const stdout = getCommandIo7(options.stdout);
8748
+ const stdout = getCommandIo6(options.stdout);
10292
8749
  const logs = program.command("logs").description("Inspect record change logs");
10293
- logs.command("list").description("List change logs for a record").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector6).argument("<record>", "record uuid or slug", parseUuidOrSlugSelector6).action(async function action(schema, record) {
8750
+ logs.command("list").description("List change logs for a record").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector5).argument("<record>", "record uuid or slug", parseUuidOrSlugSelector5).action(async function action(schema, record) {
10294
8751
  const { api, json } = createLogsApi(this, filePath);
10295
8752
  const data = await api.listLogs(schema, record.value);
10296
8753
  if (json) {
10297
- emitJson7(stdout, "logs list", data, filePath);
8754
+ emitJson6(stdout, "logs list", data, filePath);
10298
8755
  return;
10299
8756
  }
10300
8757
  emitTable3(stdout, data);
@@ -10302,11 +8759,11 @@ function registerLogsCommands(program, options = {}) {
10302
8759
  }
10303
8760
 
10304
8761
  // src/commands/navigation.ts
10305
- import { readFileSync as readFileSync7 } from "fs";
10306
- import { InvalidArgumentError as InvalidArgumentError7 } from "commander";
8762
+ import { readFileSync as readFileSync6 } from "fs";
8763
+ import { InvalidArgumentError as InvalidArgumentError6 } from "commander";
10307
8764
 
10308
8765
  // src/api/navigation.ts
10309
- function jsonOptions5(body, method) {
8766
+ function jsonOptions4(body, method) {
10310
8767
  return {
10311
8768
  method,
10312
8769
  headers: {
@@ -10315,7 +8772,7 @@ function jsonOptions5(body, method) {
10315
8772
  body: JSON.stringify(body)
10316
8773
  };
10317
8774
  }
10318
- function selectorValue7(selector) {
8775
+ function selectorValue6(selector) {
10319
8776
  return selector.value;
10320
8777
  }
10321
8778
  var NavigationApi = class {
@@ -10328,44 +8785,44 @@ var NavigationApi = class {
10328
8785
  createFolder(body) {
10329
8786
  return this.client.requestJson(
10330
8787
  "/api/v2/navigation/folders",
10331
- jsonOptions5(body, "POST")
8788
+ jsonOptions4(body, "POST")
10332
8789
  );
10333
8790
  }
10334
8791
  updateFolder(folder, body) {
10335
8792
  return this.client.requestJson(
10336
- `/api/v2/navigation/folders/${selectorValue7(folder)}`,
10337
- jsonOptions5(body, "PATCH")
8793
+ `/api/v2/navigation/folders/${selectorValue6(folder)}`,
8794
+ jsonOptions4(body, "PATCH")
10338
8795
  );
10339
8796
  }
10340
8797
  deleteFolder(folder) {
10341
8798
  return this.client.requestJson(
10342
- `/api/v2/navigation/folders/${selectorValue7(folder)}`,
8799
+ `/api/v2/navigation/folders/${selectorValue6(folder)}`,
10343
8800
  { method: "DELETE" }
10344
8801
  );
10345
8802
  }
10346
8803
  moveResource(body) {
10347
8804
  return this.client.requestJson(
10348
8805
  "/api/v2/navigation/resources:move",
10349
- jsonOptions5(body, "POST")
8806
+ jsonOptions4(body, "POST")
10350
8807
  );
10351
8808
  }
10352
8809
  };
10353
8810
 
10354
8811
  // src/commands/navigation.ts
10355
- function getCommandIo8(stdout) {
8812
+ function getCommandIo7(stdout) {
10356
8813
  return stdout ?? process.stdout;
10357
8814
  }
10358
- function writeLine8(stdout, value) {
8815
+ function writeLine7(stdout, value) {
10359
8816
  stdout.write(`${value}
10360
8817
  `);
10361
8818
  }
10362
- function getGlobalOptions8(command) {
8819
+ function getGlobalOptions7(command) {
10363
8820
  return command.optsWithGlobals();
10364
8821
  }
10365
- function emitJson8(stdout, commandName, data, configPath) {
10366
- writeLine8(stdout, JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath })));
8822
+ function emitJson7(stdout, commandName, data, configPath) {
8823
+ writeLine7(stdout, JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath })));
10367
8824
  }
10368
- function toConfigurationError8(filePath, error) {
8825
+ function toConfigurationError7(filePath, error) {
10369
8826
  if (error instanceof CliError) {
10370
8827
  throw error;
10371
8828
  }
@@ -10380,7 +8837,7 @@ function toConfigurationError8(filePath, error) {
10380
8837
  function createNavigationApi(command, filePath) {
10381
8838
  try {
10382
8839
  const config = readRuntimeConfig(filePath);
10383
- const runtime = resolveRuntimeContext(config, getGlobalOptions8(command));
8840
+ const runtime = resolveRuntimeContext(config, getGlobalOptions7(command));
10384
8841
  if (!runtime.baseUrl) {
10385
8842
  throw new CliError("configuration_error", `Resolved profile "${runtime.profile}" is missing a base URL.`);
10386
8843
  }
@@ -10395,10 +8852,10 @@ function createNavigationApi(command, filePath) {
10395
8852
  readOnly: runtime.readOnly
10396
8853
  };
10397
8854
  } catch (error) {
10398
- toConfigurationError8(filePath, error);
8855
+ toConfigurationError7(filePath, error);
10399
8856
  }
10400
8857
  }
10401
- function ensureWritable6(commandName, readOnly, mode) {
8858
+ function ensureWritable5(commandName, readOnly, mode) {
10402
8859
  if (readOnly) {
10403
8860
  throw new CliError(
10404
8861
  "command_not_allowed_in_read_only_mode",
@@ -10407,12 +8864,12 @@ function ensureWritable6(commandName, readOnly, mode) {
10407
8864
  );
10408
8865
  }
10409
8866
  }
10410
- function parseUuidOrSlugSelector7(input) {
8867
+ function parseUuidOrSlugSelector6(input) {
10411
8868
  try {
10412
8869
  return normalizeUuidOrSlug(input);
10413
8870
  } catch (error) {
10414
8871
  const message = error instanceof Error ? error.message : "Invalid selector.";
10415
- throw new InvalidArgumentError7(message);
8872
+ throw new InvalidArgumentError6(message);
10416
8873
  }
10417
8874
  }
10418
8875
  function parseInteger(value, flagName) {
@@ -10429,7 +8886,7 @@ function readJsonObject(raw, rawFile) {
10429
8886
  if (raw && rawFile) {
10430
8887
  throw new CliError("invalid_cli_usage", 'Use either "--props" or "--props-file", not both.');
10431
8888
  }
10432
- const source = rawFile ? readFileSync7(rawFile, "utf8") : raw;
8889
+ const source = rawFile ? readFileSync6(rawFile, "utf8") : raw;
10433
8890
  if (!source) {
10434
8891
  return {};
10435
8892
  }
@@ -10491,41 +8948,41 @@ function folderRows2(folders) {
10491
8948
  }
10492
8949
  function registerNavigationCommands(program, options = {}) {
10493
8950
  const filePath = options.configPath ?? defaultConfigPath;
10494
- const stdout = getCommandIo8(options.stdout);
8951
+ const stdout = getCommandIo7(options.stdout);
10495
8952
  const navigation = program.command("navigation").description("Manage workspace navigation");
10496
8953
  const folders = navigation.command("folders").description("Manage navigation folders");
10497
8954
  folders.command("list").description("List navigation folders").action(async function action() {
10498
8955
  const { api, json } = createNavigationApi(this, filePath);
10499
8956
  const data = await api.listFolders();
10500
8957
  if (json) {
10501
- emitJson8(stdout, "navigation folders list", data, filePath);
8958
+ emitJson7(stdout, "navigation folders list", data, filePath);
10502
8959
  return;
10503
8960
  }
10504
8961
  printTable(folderRows2(data), ["id", "order", "name", "resourceCount"], stdout);
10505
8962
  });
10506
- folders.command("get").description("Get a navigation folder by UUID or exact name").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector7).action(async function action(folder) {
8963
+ folders.command("get").description("Get a navigation folder by UUID or exact name").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector6).action(async function action(folder) {
10507
8964
  const { api, json } = createNavigationApi(this, filePath);
10508
8965
  const data = await api.listFolders();
10509
8966
  const resolved = resolveFolder2(data, folder);
10510
8967
  if (json) {
10511
- emitJson8(stdout, "navigation folders get", resolved, filePath);
8968
+ emitJson7(stdout, "navigation folders get", resolved, filePath);
10512
8969
  return;
10513
8970
  }
10514
8971
  printTable(folderRows2([resolved]), ["id", "order", "name", "resourceCount"], stdout);
10515
8972
  });
10516
- 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) {
8973
+ folders.command("create").description("Create a navigation folder").requiredOption("--name <name>", "folder name").option("--order <n>", "folder order").option("--props <json>", "folder additionalProperties JSON").option("--props-file <path>", "folder additionalProperties JSON file").action(async function action(commandOptions) {
10517
8974
  const { api, json, readOnly } = createNavigationApi(this, filePath);
10518
- ensureWritable6("navigation folders create", readOnly, "write");
8975
+ ensureWritable5("navigation folders create", readOnly, "write");
10519
8976
  const data = await api.createFolder(buildFolderBody(commandOptions));
10520
8977
  if (json) {
10521
- emitJson8(stdout, "navigation folders create", data, filePath);
8978
+ emitJson7(stdout, "navigation folders create", data, filePath);
10522
8979
  return;
10523
8980
  }
10524
- writeLine8(stdout, `Created navigation folder "${String(data.name ?? commandOptions.name)}".`);
8981
+ writeLine7(stdout, `Created navigation folder "${String(data.name ?? commandOptions.name)}".`);
10525
8982
  });
10526
- 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) {
8983
+ folders.command("update").description("Update a navigation folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector6).option("--name <name>", "folder name").option("--order <n>", "folder order").option("--props <json>", "folder additionalProperties JSON").option("--props-file <path>", "folder additionalProperties JSON file").action(async function action(folder, commandOptions) {
10527
8984
  const { api, json, readOnly } = createNavigationApi(this, filePath);
10528
- ensureWritable6("navigation folders update", readOnly, "write");
8985
+ ensureWritable5("navigation folders update", readOnly, "write");
10529
8986
  const allFolders = await api.listFolders();
10530
8987
  const resolved = resolveFolder2(allFolders, folder);
10531
8988
  const body = buildFolderBody(commandOptions);
@@ -10534,55 +8991,54 @@ function registerNavigationCommands(program, options = {}) {
10534
8991
  }
10535
8992
  const data = await api.updateFolder({ kind: "uuid", value: resolved.id }, body);
10536
8993
  if (json) {
10537
- emitJson8(stdout, "navigation folders update", data, filePath);
8994
+ emitJson7(stdout, "navigation folders update", data, filePath);
10538
8995
  return;
10539
8996
  }
10540
- writeLine8(stdout, `Updated navigation folder "${String(data.name ?? resolved.name ?? resolved.id)}".`);
8997
+ writeLine7(stdout, `Updated navigation folder "${String(data.name ?? resolved.name ?? resolved.id)}".`);
10541
8998
  });
10542
- folders.command("delete").description("Delete a navigation folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector7).action(async function action(folder) {
8999
+ folders.command("delete").description("Delete a navigation folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector6).action(async function action(folder) {
10543
9000
  const { api, json, readOnly } = createNavigationApi(this, filePath);
10544
- ensureWritable6("navigation folders delete", readOnly, "destructive");
9001
+ ensureWritable5("navigation folders delete", readOnly, "destructive");
10545
9002
  const allFolders = await api.listFolders();
10546
9003
  const resolved = resolveFolder2(allFolders, folder);
10547
9004
  const data = await api.deleteFolder({ kind: "uuid", value: resolved.id });
10548
9005
  if (json) {
10549
- emitJson8(stdout, "navigation folders delete", data, filePath);
9006
+ emitJson7(stdout, "navigation folders delete", data, filePath);
10550
9007
  return;
10551
9008
  }
10552
- writeLine8(stdout, `Deleted navigation folder "${resolved.name ?? resolved.id}".`);
9009
+ writeLine7(stdout, `Deleted navigation folder "${resolved.name ?? resolved.id}".`);
10553
9010
  });
10554
- navigation.command("resources").description("Manage navigation resources").command("move").description(
10555
- "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."
10556
- ).argument("<resource>", "schema UUID").requiredOption("--to <folder>", "target folder UUID or exact name").action(async function action(resourceId, commandOptions) {
9011
+ navigation.command("resources").description("Manage navigation resources").command("move").description("Move a resource into a folder").argument("<resource>", "resource UUID").requiredOption("--type <type>", "resource type").requiredOption("--to <folder>", "target folder UUID or exact name").action(async function action(resourceId, commandOptions) {
10557
9012
  const { api, json, readOnly } = createNavigationApi(this, filePath);
10558
- ensureWritable6("navigation resources move", readOnly, "write");
9013
+ ensureWritable5("navigation resources move", readOnly, "write");
10559
9014
  const allFolders = await api.listFolders();
10560
- const resolved = resolveFolder2(allFolders, parseUuidOrSlugSelector7(commandOptions.to));
9015
+ const resolved = resolveFolder2(allFolders, parseUuidOrSlugSelector6(commandOptions.to));
10561
9016
  const data = await api.moveResource({
10562
9017
  resourceId,
9018
+ resourceType: commandOptions.type.toUpperCase(),
10563
9019
  targetFolderId: resolved.id
10564
9020
  });
10565
9021
  if (json) {
10566
- emitJson8(stdout, "navigation resources move", data, filePath);
9022
+ emitJson7(stdout, "navigation resources move", data, filePath);
10567
9023
  return;
10568
9024
  }
10569
- writeLine8(stdout, `Moved resource "${resourceId}" to "${resolved.name ?? resolved.id}".`);
9025
+ writeLine7(stdout, `Moved resource "${resourceId}" to "${resolved.name ?? resolved.id}".`);
10570
9026
  });
10571
9027
  }
10572
9028
 
10573
9029
  // src/commands/profiles.ts
10574
- function getCommandIo9(stdout) {
9030
+ function getCommandIo8(stdout) {
10575
9031
  return stdout ?? process.stdout;
10576
9032
  }
10577
- function writeLine9(stdout, value) {
9033
+ function writeLine8(stdout, value) {
10578
9034
  stdout.write(`${value}
10579
9035
  `);
10580
9036
  }
10581
- function getGlobalOptions9(command) {
9037
+ function getGlobalOptions8(command) {
10582
9038
  return command.optsWithGlobals();
10583
9039
  }
10584
- function emitJson9(stdout, commandName, data, configPath) {
10585
- writeLine9(
9040
+ function emitJson8(stdout, commandName, data, configPath) {
9041
+ writeLine8(
10586
9042
  stdout,
10587
9043
  JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath }))
10588
9044
  );
@@ -10638,15 +9094,15 @@ function emitProfilesTable(stdout, data) {
10638
9094
  }
10639
9095
  function registerProfilesCommands(program, options = {}) {
10640
9096
  const filePath = options.configPath ?? defaultConfigPath;
10641
- const stdout = getCommandIo9(options.stdout);
9097
+ const stdout = getCommandIo8(options.stdout);
10642
9098
  const profiles = program.command("profiles").description("Manage local CLI profiles");
10643
9099
  profiles.command("list").description("List configured profiles").action(function action() {
10644
9100
  const config = readRequiredConfig(filePath);
10645
9101
  const data = Object.entries(config.profiles).map(
10646
9102
  ([name, profile]) => toDisplayProfile(name, profile, config.defaultProfile)
10647
9103
  );
10648
- if (getGlobalOptions9(this).json) {
10649
- emitJson9(stdout, "profiles list", data, filePath);
9104
+ if (getGlobalOptions8(this).json) {
9105
+ emitJson8(stdout, "profiles list", data, filePath);
10650
9106
  return;
10651
9107
  }
10652
9108
  emitProfilesTable(stdout, data);
@@ -10655,8 +9111,8 @@ function registerProfilesCommands(program, options = {}) {
10655
9111
  const config = readRequiredConfig(filePath);
10656
9112
  const profile = getRequiredProfile(config, profileName);
10657
9113
  const data = toDisplayProfile(profileName, profile, config.defaultProfile);
10658
- if (getGlobalOptions9(this).json) {
10659
- emitJson9(stdout, "profiles get", data, filePath);
9114
+ if (getGlobalOptions8(this).json) {
9115
+ emitJson8(stdout, "profiles get", data, filePath);
10660
9116
  return;
10661
9117
  }
10662
9118
  emitProfilesTable(stdout, [data]);
@@ -10670,11 +9126,11 @@ function registerProfilesCommands(program, options = {}) {
10670
9126
  profile: profileName,
10671
9127
  defaultProfile: nextConfig.defaultProfile
10672
9128
  };
10673
- if (getGlobalOptions9(this).json) {
10674
- emitJson9(stdout, "profiles use", data, filePath);
9129
+ if (getGlobalOptions8(this).json) {
9130
+ emitJson8(stdout, "profiles use", data, filePath);
10675
9131
  return;
10676
9132
  }
10677
- writeLine9(stdout, `Using profile "${profileName}".`);
9133
+ writeLine8(stdout, `Using profile "${profileName}".`);
10678
9134
  });
10679
9135
  profiles.command("add").description("Add a profile to the local config").argument("<profile>", "profile name").requiredOption("--api-key <token>", "API key").option("--base-url <url>", "base URL").action(function action(profileName, commandOptions) {
10680
9136
  const config = loadConfigForAdd(filePath);
@@ -10698,11 +9154,11 @@ function registerProfilesCommands(program, options = {}) {
10698
9154
  nextConfig.profiles[profileName] ?? {},
10699
9155
  nextConfig.defaultProfile
10700
9156
  );
10701
- if (getGlobalOptions9(this).json) {
10702
- emitJson9(stdout, "profiles add", data, filePath);
9157
+ if (getGlobalOptions8(this).json) {
9158
+ emitJson8(stdout, "profiles add", data, filePath);
10703
9159
  return;
10704
9160
  }
10705
- writeLine9(stdout, `Added profile "${profileName}".`);
9161
+ writeLine8(stdout, `Added profile "${profileName}".`);
10706
9162
  });
10707
9163
  profiles.command("update").description("Update an existing profile").argument("<profile>", "profile name").option("--api-key <token>", "API key").option("--base-url <url>", "base URL").action(function action(profileName, commandOptions) {
10708
9164
  if (commandOptions.apiKey === void 0 && commandOptions.baseUrl === void 0) {
@@ -10724,11 +9180,11 @@ function registerProfilesCommands(program, options = {}) {
10724
9180
  nextConfig.profiles[profileName] ?? {},
10725
9181
  nextConfig.defaultProfile
10726
9182
  );
10727
- if (getGlobalOptions9(this).json) {
10728
- emitJson9(stdout, "profiles update", data, filePath);
9183
+ if (getGlobalOptions8(this).json) {
9184
+ emitJson8(stdout, "profiles update", data, filePath);
10729
9185
  return;
10730
9186
  }
10731
- writeLine9(stdout, `Updated profile "${profileName}".`);
9187
+ writeLine8(stdout, `Updated profile "${profileName}".`);
10732
9188
  });
10733
9189
  profiles.command("remove").description("Remove a profile from the local config").argument("<profile>", "profile name").action(function action(profileName) {
10734
9190
  const config = readRequiredConfig(filePath);
@@ -10739,20 +9195,20 @@ function registerProfilesCommands(program, options = {}) {
10739
9195
  profile: profileName,
10740
9196
  defaultProfile: nextConfig.defaultProfile
10741
9197
  };
10742
- if (getGlobalOptions9(this).json) {
10743
- emitJson9(stdout, "profiles remove", data, filePath);
9198
+ if (getGlobalOptions8(this).json) {
9199
+ emitJson8(stdout, "profiles remove", data, filePath);
10744
9200
  return;
10745
9201
  }
10746
- writeLine9(stdout, `Removed profile "${profileName}".`);
9202
+ writeLine8(stdout, `Removed profile "${profileName}".`);
10747
9203
  });
10748
9204
  }
10749
9205
 
10750
9206
  // src/commands/records.ts
10751
- import { readFileSync as readFileSync8 } from "fs";
10752
- import { InvalidArgumentError as InvalidArgumentError8 } from "commander";
9207
+ import { readFileSync as readFileSync7 } from "fs";
9208
+ import { InvalidArgumentError as InvalidArgumentError7 } from "commander";
10753
9209
 
10754
9210
  // src/api/records.ts
10755
- function jsonOptions6(body, method) {
9211
+ function jsonOptions5(body, method) {
10756
9212
  return {
10757
9213
  method,
10758
9214
  headers: {
@@ -10761,7 +9217,7 @@ function jsonOptions6(body, method) {
10761
9217
  body: JSON.stringify(body)
10762
9218
  };
10763
9219
  }
10764
- function selectorValue8(selector) {
9220
+ function selectorValue7(selector) {
10765
9221
  return selector.value;
10766
9222
  }
10767
9223
  var RecordsApi = class {
@@ -10776,7 +9232,7 @@ var RecordsApi = class {
10776
9232
  if (query.offset !== void 0) {
10777
9233
  params.set("offset", String(query.offset));
10778
9234
  }
10779
- const path = `/api/v2/schemas/${selectorValue8(schema)}/records`;
9235
+ const path = `/api/v2/schemas/${selectorValue7(schema)}/records`;
10780
9236
  const queryString = params.toString();
10781
9237
  return this.client.getJson(
10782
9238
  queryString ? `${path}?${queryString}` : path
@@ -10785,36 +9241,36 @@ var RecordsApi = class {
10785
9241
  queryRecords(schema, query) {
10786
9242
  const body = this.normalizeQueryInput(query);
10787
9243
  return this.client.requestJson(
10788
- `/api/v2/schemas/${selectorValue8(schema)}/records:query`,
10789
- jsonOptions6(body, "POST")
9244
+ `/api/v2/schemas/${selectorValue7(schema)}/records:query`,
9245
+ jsonOptions5(body, "POST")
10790
9246
  );
10791
9247
  }
10792
9248
  getRecord(schema, record) {
10793
9249
  return this.client.getJson(
10794
- `/api/v2/schemas/${selectorValue8(schema)}/records/${selectorValue8(record)}`
9250
+ `/api/v2/schemas/${selectorValue7(schema)}/records/${selectorValue7(record)}`
10795
9251
  );
10796
9252
  }
10797
- createRecords(schema, records) {
9253
+ createRecord(schema, input) {
10798
9254
  return this.client.requestJson(
10799
- `/api/v2/schemas/${selectorValue8(schema)}/records`,
10800
- jsonOptions6({ records }, "POST")
9255
+ `/api/v2/schemas/${selectorValue7(schema)}/records`,
9256
+ jsonOptions5(input, "POST")
10801
9257
  );
10802
9258
  }
10803
9259
  updateRecord(schema, record, input) {
10804
9260
  return this.client.requestJson(
10805
- `/api/v2/schemas/${selectorValue8(schema)}/records/${selectorValue8(record)}`,
10806
- jsonOptions6(input, "PATCH")
9261
+ `/api/v2/schemas/${selectorValue7(schema)}/records/${selectorValue7(record)}`,
9262
+ jsonOptions5(input, "PATCH")
10807
9263
  );
10808
9264
  }
10809
- deleteRecords(schema, recordIds) {
9265
+ deleteRecord(schema, record) {
10810
9266
  return this.client.requestJson(
10811
- `/api/v2/schemas/${selectorValue8(schema)}/records:delete`,
10812
- jsonOptions6({ recordIds }, "POST")
9267
+ `/api/v2/schemas/${selectorValue7(schema)}/records/${selectorValue7(record)}`,
9268
+ { method: "DELETE" }
10813
9269
  );
10814
9270
  }
10815
9271
  clearRecords(schema) {
10816
9272
  return this.client.requestJson(
10817
- `/api/v2/schemas/${selectorValue8(schema)}/records:clear`,
9273
+ `/api/v2/schemas/${selectorValue7(schema)}/records:clear`,
10818
9274
  { method: "DELETE" }
10819
9275
  );
10820
9276
  }
@@ -10847,7 +9303,7 @@ var RecordsApi = class {
10847
9303
  };
10848
9304
 
10849
9305
  // src/api/schemas.ts
10850
- function jsonOptions7(body, method) {
9306
+ function jsonOptions6(body, method) {
10851
9307
  return {
10852
9308
  method,
10853
9309
  headers: {
@@ -10856,7 +9312,7 @@ function jsonOptions7(body, method) {
10856
9312
  body: JSON.stringify(body)
10857
9313
  };
10858
9314
  }
10859
- function selectorValue9(selector) {
9315
+ function selectorValue8(selector) {
10860
9316
  return selector.value;
10861
9317
  }
10862
9318
  var SchemasApi = class {
@@ -10867,76 +9323,150 @@ var SchemasApi = class {
10867
9323
  return this.client.getJson("/api/v2/schemas");
10868
9324
  }
10869
9325
  getSchema(schema) {
10870
- return this.client.getJson(`/api/v2/schemas/${selectorValue9(schema)}`);
9326
+ return this.client.getJson(`/api/v2/schemas/${selectorValue8(schema)}`);
10871
9327
  }
10872
9328
  createSchema(input) {
10873
- return this.client.requestJson("/api/v2/schemas", jsonOptions7(input, "POST"));
9329
+ return this.client.requestJson("/api/v2/schemas", jsonOptions6(input, "POST"));
10874
9330
  }
10875
9331
  updateSchema(schema, input) {
10876
9332
  return this.client.requestJson(
10877
- `/api/v2/schemas/${selectorValue9(schema)}`,
10878
- jsonOptions7(input, "PATCH")
9333
+ `/api/v2/schemas/${selectorValue8(schema)}`,
9334
+ jsonOptions6(input, "PATCH")
10879
9335
  );
10880
9336
  }
10881
- setUniqueFields(schema, input) {
9337
+ deleteSchema(schema) {
10882
9338
  return this.client.requestJson(
10883
- `/api/v2/schemas/${selectorValue9(schema)}/unique-fields`,
10884
- jsonOptions7(input, "PUT")
9339
+ `/api/v2/schemas/${selectorValue8(schema)}`,
9340
+ { method: "DELETE" }
10885
9341
  );
10886
9342
  }
10887
- deleteSchema(schema) {
9343
+ async listFields(schema) {
9344
+ const result = await this.getSchema(schema);
9345
+ return Array.isArray(result.fields) ? result.fields : [];
9346
+ }
9347
+ getField(schema, field) {
9348
+ return this.client.getJson(
9349
+ `/api/v2/schemas/${selectorValue8(schema)}/fields/${selectorValue8(field)}`
9350
+ );
9351
+ }
9352
+ createField(schema, input) {
10888
9353
  return this.client.requestJson(
10889
- `/api/v2/schemas/${selectorValue9(schema)}`,
9354
+ `/api/v2/schemas/${selectorValue8(schema)}/fields`,
9355
+ jsonOptions6(input, "POST")
9356
+ );
9357
+ }
9358
+ updateField(schema, field, input) {
9359
+ return this.client.requestJson(
9360
+ `/api/v2/schemas/${selectorValue8(schema)}/fields/${selectorValue8(field)}`,
9361
+ jsonOptions6(input, "PATCH")
9362
+ );
9363
+ }
9364
+ deleteField(schema, field) {
9365
+ return this.client.requestJson(
9366
+ `/api/v2/schemas/${selectorValue8(schema)}/fields/${selectorValue8(field)}`,
10890
9367
  { method: "DELETE" }
10891
9368
  );
10892
9369
  }
10893
- async listFields(schema) {
10894
- const result = await this.getSchema(schema);
10895
- return Array.isArray(result.fields) ? result.fields : [];
9370
+ };
9371
+
9372
+ // src/parsers/expressions.ts
9373
+ var supportedComparators = /* @__PURE__ */ new Set([
9374
+ "eq",
9375
+ "neq",
9376
+ "gt",
9377
+ "gte",
9378
+ "lt",
9379
+ "lte",
9380
+ "contains",
9381
+ "in",
9382
+ "is_empty",
9383
+ "is_not_empty"
9384
+ ]);
9385
+ var noValueComparators = /* @__PURE__ */ new Set(["is_empty", "is_not_empty"]);
9386
+ function parseColonExpression(input) {
9387
+ const parts = input.split(":");
9388
+ if (parts.length < 2) {
9389
+ throw new Error(`Expected a field:comparator[:value] expression, got "${input}".`);
9390
+ }
9391
+ const field = parts[0]?.trim();
9392
+ const comparator = parts[1]?.trim();
9393
+ if (!field) {
9394
+ throw new Error(`Expected a field before ":", got "${input}".`);
9395
+ }
9396
+ if (!comparator) {
9397
+ throw new Error(`Expected a comparator after "${field}:", got "${input}".`);
9398
+ }
9399
+ return [field, comparator, parts.slice(2).join(":").trim()];
9400
+ }
9401
+ function parseSpaceExpression(input) {
9402
+ const parts = input.trim().split(/\s+/);
9403
+ if (parts.length < 2) {
9404
+ throw new Error(`Expected a field comparator expression, got "${input}".`);
9405
+ }
9406
+ const field = parts[0];
9407
+ const comparator = parts[1];
9408
+ if (!field) {
9409
+ throw new Error(`Expected a field comparator expression, got "${input}".`);
9410
+ }
9411
+ if (!comparator) {
9412
+ throw new Error(`Expected a comparator after "${field}", got "${input}".`);
10896
9413
  }
10897
- getField(schema, field) {
10898
- return this.client.getJson(
10899
- `/api/v2/schemas/${selectorValue9(schema)}/fields/${selectorValue9(field)}`
10900
- );
9414
+ return [field.trim(), comparator.trim(), parts.slice(2).join(" ").trim()];
9415
+ }
9416
+ function normalizeValue(comparator, rawValue) {
9417
+ if (noValueComparators.has(comparator)) {
9418
+ if (rawValue.length > 0) {
9419
+ throw new Error(`Comparator "${comparator}" does not accept a value.`);
9420
+ }
9421
+ return null;
10901
9422
  }
10902
- createField(schema, input) {
10903
- return this.client.requestJson(
10904
- `/api/v2/schemas/${selectorValue9(schema)}/fields`,
10905
- jsonOptions7(input, "POST")
10906
- );
9423
+ if (comparator === "in") {
9424
+ const values = rawValue.split(",").map((value) => value.trim()).filter(Boolean);
9425
+ if (values.length === 0) {
9426
+ throw new Error(`Comparator "${comparator}" requires at least one value.`);
9427
+ }
9428
+ return values;
10907
9429
  }
10908
- updateField(schema, field, input) {
10909
- return this.client.requestJson(
10910
- `/api/v2/schemas/${selectorValue9(schema)}/fields/${selectorValue9(field)}`,
10911
- jsonOptions7(input, "PATCH")
10912
- );
9430
+ if (rawValue.length === 0) {
9431
+ throw new Error(`Comparator "${comparator}" requires a value.`);
10913
9432
  }
10914
- deleteField(schema, field) {
10915
- return this.client.requestJson(
10916
- `/api/v2/schemas/${selectorValue9(schema)}/fields/${selectorValue9(field)}`,
10917
- { method: "DELETE" }
9433
+ return rawValue;
9434
+ }
9435
+ function parseExpression(input) {
9436
+ const trimmed = input.trim();
9437
+ const [field, comparatorCandidate, rawValue] = trimmed.includes(":") && !trimmed.includes(" ") ? parseColonExpression(trimmed) : parseSpaceExpression(trimmed);
9438
+ if (!supportedComparators.has(comparatorCandidate)) {
9439
+ throw new Error(
9440
+ `Unsupported comparator "${comparatorCandidate}" in expression "${input}".`
10918
9441
  );
10919
9442
  }
10920
- };
9443
+ const comparator = comparatorCandidate;
9444
+ return {
9445
+ field,
9446
+ comparator,
9447
+ value: normalizeValue(comparator, rawValue),
9448
+ raw: trimmed
9449
+ };
9450
+ }
10921
9451
 
10922
9452
  // src/commands/records.ts
10923
- function getCommandIo10(stdout) {
9453
+ function getCommandIo9(stdout) {
10924
9454
  return stdout ?? process.stdout;
10925
9455
  }
10926
- function writeLine10(stdout, value) {
9456
+ function writeLine9(stdout, value) {
10927
9457
  stdout.write(`${value}
10928
9458
  `);
10929
9459
  }
10930
- function getGlobalOptions10(command) {
9460
+ function getGlobalOptions9(command) {
10931
9461
  return command.optsWithGlobals();
10932
9462
  }
10933
- function emitJson10(stdout, commandName, data, configPath, meta = {}) {
10934
- writeLine10(
9463
+ function emitJson9(stdout, commandName, data, configPath, meta = {}) {
9464
+ writeLine9(
10935
9465
  stdout,
10936
9466
  JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath, ...meta }))
10937
9467
  );
10938
9468
  }
10939
- function toConfigurationError9(filePath, error) {
9469
+ function toConfigurationError8(filePath, error) {
10940
9470
  if (error instanceof CliError) {
10941
9471
  throw error;
10942
9472
  }
@@ -10951,7 +9481,7 @@ function toConfigurationError9(filePath, error) {
10951
9481
  function createRecordsApi(command, filePath) {
10952
9482
  try {
10953
9483
  const config = readRuntimeConfig(filePath);
10954
- const runtime = resolveRuntimeContext(config, getGlobalOptions10(command));
9484
+ const runtime = resolveRuntimeContext(config, getGlobalOptions9(command));
10955
9485
  if (!runtime.baseUrl) {
10956
9486
  throw new CliError(
10957
9487
  "configuration_error",
@@ -10970,10 +9500,10 @@ function createRecordsApi(command, filePath) {
10970
9500
  readOnly: runtime.readOnly
10971
9501
  };
10972
9502
  } catch (error) {
10973
- toConfigurationError9(filePath, error);
9503
+ toConfigurationError8(filePath, error);
10974
9504
  }
10975
9505
  }
10976
- function ensureWritable7(commandName, readOnly, commandMode) {
9506
+ function ensureWritable6(commandName, readOnly, commandMode) {
10977
9507
  if (readOnly) {
10978
9508
  throw new CliError(
10979
9509
  "command_not_allowed_in_read_only_mode",
@@ -10985,24 +9515,24 @@ function ensureWritable7(commandName, readOnly, commandMode) {
10985
9515
  );
10986
9516
  }
10987
9517
  }
10988
- function parseUuidOrSlugSelector8(input) {
9518
+ function parseUuidOrSlugSelector7(input) {
10989
9519
  try {
10990
9520
  return normalizeUuidOrSlug(input);
10991
9521
  } catch (error) {
10992
9522
  const message = error instanceof Error ? error.message : "Invalid selector.";
10993
- throw new InvalidArgumentError8(message);
9523
+ throw new InvalidArgumentError7(message);
10994
9524
  }
10995
9525
  }
10996
9526
  function parseNonNegativeInteger2(input) {
10997
9527
  if (!/^\d+$/.test(input.trim())) {
10998
- throw new InvalidArgumentError8(`Expected a non-negative integer, received "${input}".`);
9528
+ throw new InvalidArgumentError7(`Expected a non-negative integer, received "${input}".`);
10999
9529
  }
11000
9530
  return Number(input);
11001
9531
  }
11002
9532
  function parseCommaSeparatedValues(input, label) {
11003
9533
  const values = input.split(",").map((value) => value.trim()).filter(Boolean);
11004
9534
  if (values.length === 0) {
11005
- throw new InvalidArgumentError8(`Expected ${label} to contain at least one value.`);
9535
+ throw new InvalidArgumentError7(`Expected ${label} to contain at least one value.`);
11006
9536
  }
11007
9537
  return values;
11008
9538
  }
@@ -11011,7 +9541,7 @@ function parseExpressionValue(input) {
11011
9541
  return parseExpression(input);
11012
9542
  } catch (error) {
11013
9543
  const message = error instanceof Error ? error.message : "Invalid expression.";
11014
- throw new InvalidArgumentError8(message);
9544
+ throw new InvalidArgumentError7(message);
11015
9545
  }
11016
9546
  }
11017
9547
  function parseKeyValueAssignment(input) {
@@ -11019,7 +9549,7 @@ function parseKeyValueAssignment(input) {
11019
9549
  return parseKeyValue(input);
11020
9550
  } catch (error) {
11021
9551
  const message = error instanceof Error ? error.message : "Invalid assignment.";
11022
- throw new InvalidArgumentError8(message);
9552
+ throw new InvalidArgumentError7(message);
11023
9553
  }
11024
9554
  }
11025
9555
  function parseJsonKeyValueAssignment(input) {
@@ -11027,75 +9557,14 @@ function parseJsonKeyValueAssignment(input) {
11027
9557
  return parseJsonAssignment(input);
11028
9558
  } catch (error) {
11029
9559
  const message = error instanceof Error ? error.message : "Invalid JSON assignment.";
11030
- throw new InvalidArgumentError8(message);
11031
- }
11032
- }
11033
- function dedupeStrings(values) {
11034
- return [...new Set(values)];
11035
- }
11036
- function toRecordUuid(value) {
11037
- try {
11038
- const normalized = normalizeUuidOrSlug(value);
11039
- return normalized.kind === "uuid" ? normalized.value : null;
11040
- } catch {
11041
- return null;
11042
- }
11043
- }
11044
- function collectRecordIds(value, previous = []) {
11045
- const uuid = toRecordUuid(value.trim());
11046
- if (!uuid) {
11047
- throw new InvalidArgumentError8(`Expected a record UUID, received "${value}".`);
11048
- }
11049
- return [...previous, uuid];
11050
- }
11051
- function readRecordIdsFromFile(path) {
11052
- let contents;
11053
- try {
11054
- contents = readFileSync8(path, "utf8");
11055
- } catch (error) {
11056
- const message = error instanceof Error ? error.message : "Unable to read file.";
11057
- throw new CliError(
11058
- "invalid_cli_usage",
11059
- `Failed to read record ids from ${path}: ${message}`
11060
- );
11061
- }
11062
- const ids = [];
11063
- contents.split(/\r?\n/).forEach((line, index) => {
11064
- const value = line.trim();
11065
- if (!value) {
11066
- return;
11067
- }
11068
- const uuid = toRecordUuid(value);
11069
- if (!uuid) {
11070
- throw new CliError(
11071
- "invalid_cli_usage",
11072
- `Invalid record UUID "${value}" at ${path}:${index + 1}.`
11073
- );
11074
- }
11075
- ids.push(uuid);
11076
- });
11077
- return ids;
11078
- }
11079
- function resolveDeleteRecordIds(options) {
11080
- const flagIds = options.record ?? [];
11081
- const fileIds = options.recordsFile ? readRecordIdsFromFile(options.recordsFile) : [];
11082
- const recordIds = dedupeStrings([...flagIds, ...fileIds]);
11083
- if (recordIds.length === 0) {
11084
- throw new CliError(
11085
- "invalid_cli_usage",
11086
- 'Provide at least one record id via "--record <uuid>" (repeatable) or "--records-file <path>".'
11087
- );
9560
+ throw new InvalidArgumentError7(message);
11088
9561
  }
11089
- return recordIds;
11090
9562
  }
11091
9563
  function collectStringValues(value, previous = []) {
11092
9564
  return [...previous, value];
11093
9565
  }
11094
- function collectSelectValues(value, previous = []) {
11095
- return dedupeStrings([...previous, ...parseCommaSeparatedValues(value, "--select")]);
11096
- }
11097
9566
  function collectSortValues(value, previous = []) {
11098
- return dedupeStrings([...previous, ...parseCommaSeparatedValues(value, "--sort")]);
9567
+ return [...previous, ...parseCommaSeparatedValues(value, "--sort")];
11099
9568
  }
11100
9569
  function collectWhereExpressions(value, previous = []) {
11101
9570
  return [...previous, parseExpressionValue(value)];
@@ -11106,7 +9575,7 @@ function collectKeyValueAssignments(value, previous = []) {
11106
9575
  function collectJsonAssignments(value, previous = []) {
11107
9576
  return [...previous, parseJsonKeyValueAssignment(value)];
11108
9577
  }
11109
- function isJsonObject6(value) {
9578
+ function isJsonObject5(value) {
11110
9579
  return typeof value === "object" && value !== null && !Array.isArray(value);
11111
9580
  }
11112
9581
  function parseRawJsonObject2(input, sourceLabel) {
@@ -11120,7 +9589,7 @@ function parseRawJsonObject2(input, sourceLabel) {
11120
9589
  `Failed to parse JSON from ${sourceLabel}: ${message}`
11121
9590
  );
11122
9591
  }
11123
- if (!isJsonObject6(parsed)) {
9592
+ if (!isJsonObject5(parsed)) {
11124
9593
  throw new CliError(
11125
9594
  "invalid_cli_usage",
11126
9595
  `Expected ${sourceLabel} to contain a JSON object.`
@@ -11141,7 +9610,7 @@ function readRawObject3(raw, rawFile) {
11141
9610
  if (rawFile) {
11142
9611
  let contents;
11143
9612
  try {
11144
- contents = readFileSync8(rawFile, "utf8");
9613
+ contents = readFileSync7(rawFile, "utf8");
11145
9614
  } catch (error) {
11146
9615
  const message = error instanceof Error ? error.message : "Unable to read file.";
11147
9616
  throw new CliError(
@@ -11153,7 +9622,7 @@ function readRawObject3(raw, rawFile) {
11153
9622
  }
11154
9623
  return {};
11155
9624
  }
11156
- function isEmptyObject5(value) {
9625
+ function isEmptyObject4(value) {
11157
9626
  return Object.keys(value).length === 0;
11158
9627
  }
11159
9628
  function buildAssignmentObject(assignments = [], jsonAssignments = []) {
@@ -11185,9 +9654,6 @@ function buildRecordQueryInput(options, allowRaw) {
11185
9654
  if (where && where.length > 0) {
11186
9655
  input.where = where;
11187
9656
  }
11188
- if (options.search !== void 0) {
11189
- input.search = { term: options.search };
11190
- }
11191
9657
  if (options.sort && options.sort.length > 0) {
11192
9658
  input.sort = [...options.sort];
11193
9659
  }
@@ -11199,80 +9665,53 @@ function buildRecordQueryInput(options, allowRaw) {
11199
9665
  }
11200
9666
  return input;
11201
9667
  }
11202
- function readRecordsFromFile(path) {
11203
- let contents;
11204
- try {
11205
- contents = readFileSync8(path, "utf8");
11206
- } catch (error) {
11207
- const message = error instanceof Error ? error.message : "Unable to read file.";
11208
- throw new CliError(
11209
- "invalid_cli_usage",
11210
- `Failed to read records from ${path}: ${message}`
11211
- );
11212
- }
11213
- let parsed;
11214
- try {
11215
- parsed = JSON.parse(contents);
11216
- } catch (error) {
11217
- const message = error instanceof Error ? error.message : "Invalid JSON.";
9668
+ function buildRecordCreateInput(options) {
9669
+ const values = {
9670
+ ...readRawObject3(options.raw, options.rawFile),
9671
+ ...buildAssignmentObject(options.set, options.setJson)
9672
+ };
9673
+ if (isEmptyObject4(values)) {
11218
9674
  throw new CliError(
11219
9675
  "invalid_cli_usage",
11220
- `Failed to parse JSON from --records-file ${path}: ${message}`
9676
+ 'Provide record fields via "--set", "--set-json", "--raw", or "--raw-file".'
11221
9677
  );
11222
9678
  }
11223
- if (!Array.isArray(parsed)) {
11224
- throw new CliError(
11225
- "invalid_cli_usage",
11226
- `Expected --records-file ${path} to contain a JSON array of record objects.`
11227
- );
9679
+ return { values };
9680
+ }
9681
+ function readRawSetPayload2(raw) {
9682
+ const setValue = raw.set;
9683
+ if (setValue === void 0) {
9684
+ return {};
11228
9685
  }
11229
- if (parsed.length === 0) {
9686
+ if (!isJsonObject5(setValue)) {
11230
9687
  throw new CliError(
11231
9688
  "invalid_cli_usage",
11232
- `--records-file ${path} must contain at least one record.`
9689
+ 'Expected raw update payload field "set" to be a JSON object.'
11233
9690
  );
11234
9691
  }
11235
- return parsed.map((record, index) => {
11236
- if (!isJsonObject6(record)) {
11237
- throw new CliError(
11238
- "invalid_cli_usage",
11239
- `Record at index ${index} in --records-file ${path} must be a JSON object.`
11240
- );
11241
- }
11242
- return record;
11243
- });
9692
+ return { ...setValue };
11244
9693
  }
11245
- function buildCreateRecords(options) {
11246
- const hasSingleRecordFlags = (options.set?.length ?? 0) > 0 || (options.setJson?.length ?? 0) > 0 || options.raw !== void 0 || options.rawFile !== void 0;
11247
- if (options.recordsFile !== void 0) {
11248
- if (hasSingleRecordFlags) {
11249
- throw new CliError(
11250
- "invalid_cli_usage",
11251
- 'Provide either "--records-file" or the single-record flags (--set/--set-json/--raw/--raw-file), not both.'
11252
- );
11253
- }
11254
- return readRecordsFromFile(options.recordsFile);
9694
+ function readRawUnsetPayload2(raw) {
9695
+ const unsetValue = raw.unset;
9696
+ if (unsetValue === void 0) {
9697
+ return [];
11255
9698
  }
11256
- const values = {
11257
- ...readRawObject3(options.raw, options.rawFile),
11258
- ...buildAssignmentObject(options.set, options.setJson)
11259
- };
11260
- if (isEmptyObject5(values)) {
9699
+ if (!Array.isArray(unsetValue) || !unsetValue.every((value) => typeof value === "string")) {
11261
9700
  throw new CliError(
11262
9701
  "invalid_cli_usage",
11263
- 'Provide record fields via "--set", "--set-json", "--raw", "--raw-file", or load multiple records with "--records-file".'
9702
+ 'Expected raw update payload field "unset" to be an array of strings.'
11264
9703
  );
11265
9704
  }
11266
- return [values];
9705
+ return [...unsetValue];
11267
9706
  }
11268
9707
  function buildRecordUpdateInput(options) {
11269
9708
  const raw = readRawObject3(options.raw, options.rawFile);
11270
- const input = {};
9709
+ const input = { ...raw };
11271
9710
  const setPayload = {
11272
- ...raw,
9711
+ ...readRawSetPayload2(raw),
11273
9712
  ...buildAssignmentObject(options.set, options.setJson)
11274
9713
  };
11275
- const unsetPayload = [...options.unset ?? []];
9714
+ const unsetPayload = [...readRawUnsetPayload2(raw), ...options.unset ?? []];
11276
9715
  for (const key of Object.keys(setPayload)) {
11277
9716
  const unsetIndex = unsetPayload.indexOf(key);
11278
9717
  if (unsetIndex !== -1) {
@@ -11289,7 +9728,7 @@ function buildRecordUpdateInput(options) {
11289
9728
  } else {
11290
9729
  delete input.unset;
11291
9730
  }
11292
- if (isEmptyObject5(input)) {
9731
+ if (isEmptyObject4(input)) {
11293
9732
  throw new CliError(
11294
9733
  "invalid_cli_usage",
11295
9734
  'Provide record updates via "--set", "--set-json", "--unset", "--raw", or "--raw-file".'
@@ -11299,9 +9738,9 @@ function buildRecordUpdateInput(options) {
11299
9738
  }
11300
9739
  function toTableRows4(data) {
11301
9740
  if (Array.isArray(data)) {
11302
- return data.map((entry) => isJsonObject6(entry) ? entry : { value: entry });
9741
+ return data.map((entry) => isJsonObject5(entry) ? entry : { value: entry });
11303
9742
  }
11304
- if (isJsonObject6(data)) {
9743
+ if (isJsonObject5(data)) {
11305
9744
  return [data];
11306
9745
  }
11307
9746
  return [{ value: data }];
@@ -11331,9 +9770,9 @@ async function resolveSchemaSelector(api, selector) {
11331
9770
  }
11332
9771
  function registerRecordsCommands(program, options = {}) {
11333
9772
  const filePath = options.configPath ?? defaultConfigPath;
11334
- const stdout = getCommandIo10(options.stdout);
9773
+ const stdout = getCommandIo9(options.stdout);
11335
9774
  const records = program.command("records").description("Manage schema records");
11336
- records.command("list").description("List records for a schema with simple pagination").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).option("--limit <number>", "limit results", parseNonNegativeInteger2).option("--offset <number>", "offset results", parseNonNegativeInteger2).action(async function action(schema, commandOptions) {
9775
+ records.command("list").description("List records for a schema with simple pagination").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).option("--limit <number>", "limit results", parseNonNegativeInteger2).option("--offset <number>", "offset results", parseNonNegativeInteger2).action(async function action(schema, commandOptions) {
11337
9776
  const { api, schemasApi, json } = createRecordsApi(this, filePath);
11338
9777
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
11339
9778
  const data = await api.listRecords(
@@ -11342,7 +9781,7 @@ function registerRecordsCommands(program, options = {}) {
11342
9781
  );
11343
9782
  const recordsData = getQueryRecords(data);
11344
9783
  if (json) {
11345
- emitJson10(
9784
+ emitJson9(
11346
9785
  stdout,
11347
9786
  "records list",
11348
9787
  recordsData,
@@ -11353,10 +9792,7 @@ function registerRecordsCommands(program, options = {}) {
11353
9792
  }
11354
9793
  emitTable4(stdout, recordsData);
11355
9794
  });
11356
- records.command("query").description("Query records for a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).option("--select <fields>", "field selection (comma-separated, repeatable)", collectSelectValues, []).option("--where <expression>", "where expression", collectWhereExpressions, []).option(
11357
- "--search <term>",
11358
- "free-text search term (matched across the schema's searchable fields)"
11359
- ).option("--sort <field:direction>", "sort field(s)", collectSortValues, []).option("--limit <number>", "limit results", parseNonNegativeInteger2).option("--offset <number>", "offset results", parseNonNegativeInteger2).option("--raw <json>", "raw JSON object payload").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, commandOptions) {
9795
+ records.command("query").description("Query records for a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).option("--select <fields>", "comma-separated field selection", (value) => parseCommaSeparatedValues(value, "--select")).option("--where <expression>", "where expression", collectWhereExpressions, []).option("--sort <field:direction>", "sort field(s)", collectSortValues, []).option("--limit <number>", "limit results", parseNonNegativeInteger2).option("--offset <number>", "offset results", parseNonNegativeInteger2).option("--raw <json>", "raw JSON object payload").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, commandOptions) {
11360
9796
  const { api, schemasApi, json } = createRecordsApi(this, filePath);
11361
9797
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
11362
9798
  const data = await api.queryRecords(
@@ -11365,7 +9801,7 @@ function registerRecordsCommands(program, options = {}) {
11365
9801
  );
11366
9802
  const recordsData = getQueryRecords(data);
11367
9803
  if (json) {
11368
- emitJson10(
9804
+ emitJson9(
11369
9805
  stdout,
11370
9806
  "records query",
11371
9807
  recordsData,
@@ -11376,50 +9812,33 @@ function registerRecordsCommands(program, options = {}) {
11376
9812
  }
11377
9813
  emitTable4(stdout, recordsData);
11378
9814
  });
11379
- records.command("get").description("Get a record by UUID or slug").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).argument("<record>", "record uuid or slug", parseUuidOrSlugSelector8).action(async function action(schema, record) {
9815
+ records.command("get").description("Get a record by UUID or slug").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).argument("<record>", "record uuid or slug", parseUuidOrSlugSelector7).action(async function action(schema, record) {
11380
9816
  const { api, schemasApi, json } = createRecordsApi(this, filePath);
11381
9817
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
11382
9818
  const data = await api.getRecord(resolvedSchema, record);
11383
9819
  if (json) {
11384
- emitJson10(stdout, "records get", data, filePath);
9820
+ emitJson9(stdout, "records get", data, filePath);
11385
9821
  return;
11386
9822
  }
11387
9823
  emitTable4(stdout, data);
11388
9824
  });
11389
- records.command("create").description("Create one or more records").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).option(
11390
- "--set <field=value>",
11391
- "set a string field (reference fields: a record id, 'recordId::label', or an exact display value)",
11392
- collectKeyValueAssignments,
11393
- []
11394
- ).option("--set-json <field=json>", "set a structured field", collectJsonAssignments, []).option("--raw <json>", "raw JSON object payload").option("--raw-file <path>", "path to a raw JSON object payload").option(
11395
- "--records-file <path>",
11396
- "path to a JSON array of record objects (mutually exclusive with --set/--set-json/--raw/--raw-file)"
11397
- ).action(async function action(schema, commandOptions) {
9825
+ records.command("create").description("Create a record").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).option("--set <field=value>", "set a string field", collectKeyValueAssignments, []).option("--set-json <field=json>", "set a structured field", collectJsonAssignments, []).option("--raw <json>", "raw JSON object payload").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, commandOptions) {
11398
9826
  const { api, schemasApi, json, readOnly } = createRecordsApi(this, filePath);
11399
- ensureWritable7("records create", readOnly, "write");
11400
- const records2 = buildCreateRecords(commandOptions);
9827
+ ensureWritable6("records create", readOnly, "write");
11401
9828
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
11402
- const data = await api.createRecords(resolvedSchema, records2);
9829
+ const data = await api.createRecord(
9830
+ resolvedSchema,
9831
+ buildRecordCreateInput(commandOptions)
9832
+ );
11403
9833
  if (json) {
11404
- emitJson10(stdout, "records create", data, filePath);
9834
+ emitJson9(stdout, "records create", data, filePath);
11405
9835
  return;
11406
9836
  }
11407
- writeLine10(stdout, `Created ${data.created.length} record(s) in schema "${schema.value}".`);
11408
- if (data.errors.length > 0) {
11409
- writeLine10(stdout, `${data.errors.length} record(s) rejected:`);
11410
- for (const error of data.errors) {
11411
- writeLine10(stdout, ` - index ${error.index}: ${error.message}`);
11412
- }
11413
- }
9837
+ writeLine9(stdout, `Created record "${getRecordIdentifier(data)}".`);
11414
9838
  });
11415
- records.command("update").description("Update a record").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).argument("<record>", "record uuid or slug", parseUuidOrSlugSelector8).option(
11416
- "--set <field=value>",
11417
- "set a string field (reference fields: a record id, 'recordId::label', or an exact display value)",
11418
- collectKeyValueAssignments,
11419
- []
11420
- ).option("--set-json <field=json>", "set a structured field", collectJsonAssignments, []).option("--unset <field>", "unset a field", collectStringValues, []).option("--raw <json>", "raw JSON object of fields to set").option("--raw-file <path>", "path to a JSON object of fields to set").action(async function action(schema, record, commandOptions) {
9839
+ records.command("update").description("Update a record").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).argument("<record>", "record uuid or slug", parseUuidOrSlugSelector7).option("--set <field=value>", "set a string field", collectKeyValueAssignments, []).option("--set-json <field=json>", "set a structured field", collectJsonAssignments, []).option("--unset <field>", "unset a field", collectStringValues, []).option("--raw <json>", "raw JSON object payload").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, record, commandOptions) {
11421
9840
  const { api, schemasApi, json, readOnly } = createRecordsApi(this, filePath);
11422
- ensureWritable7("records update", readOnly, "write");
9841
+ ensureWritable6("records update", readOnly, "write");
11423
9842
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
11424
9843
  const data = await api.updateRecord(
11425
9844
  resolvedSchema,
@@ -11427,71 +9846,60 @@ function registerRecordsCommands(program, options = {}) {
11427
9846
  buildRecordUpdateInput(commandOptions)
11428
9847
  );
11429
9848
  if (json) {
11430
- emitJson10(stdout, "records update", data, filePath);
9849
+ emitJson9(stdout, "records update", data, filePath);
11431
9850
  return;
11432
9851
  }
11433
- writeLine10(stdout, `Updated record "${getRecordIdentifier(data)}".`);
9852
+ writeLine9(stdout, `Updated record "${getRecordIdentifier(data)}".`);
11434
9853
  });
11435
- records.command("delete").description("Delete one or more records").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).option("--record <uuid>", "record uuid to delete (repeatable)", collectRecordIds, []).option(
11436
- "--records-file <path>",
11437
- "path to a file with one record uuid per line (merged with --record)"
11438
- ).action(async function action(schema, commandOptions) {
9854
+ records.command("delete").description("Delete a record").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).argument("<record>", "record uuid or slug", parseUuidOrSlugSelector7).action(async function action(schema, record) {
11439
9855
  const { api, schemasApi, json, readOnly } = createRecordsApi(this, filePath);
11440
- ensureWritable7("records delete", readOnly, "destructive");
11441
- const recordIds = resolveDeleteRecordIds(commandOptions);
9856
+ ensureWritable6("records delete", readOnly, "destructive");
11442
9857
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
11443
- const data = await api.deleteRecords(resolvedSchema, recordIds);
9858
+ await api.deleteRecord(resolvedSchema, record);
9859
+ const data = {
9860
+ schema: resolvedSchema.value,
9861
+ record: record.value,
9862
+ deleted: true
9863
+ };
11444
9864
  if (json) {
11445
- emitJson10(stdout, "records delete", data, filePath);
9865
+ emitJson9(stdout, "records delete", data, filePath);
11446
9866
  return;
11447
9867
  }
11448
- writeLine10(
11449
- stdout,
11450
- `Deleted ${recordIds.length} record(s) from schema "${schema.value}".`
11451
- );
9868
+ writeLine9(stdout, `Deleted record "${record.value}" from schema "${schema.value}".`);
11452
9869
  });
11453
- records.command("clear").description("Delete all records from a schema's table").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).action(async function action(schema) {
9870
+ records.command("clear").description("Delete all records from a schema's table").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).action(async function action(schema) {
11454
9871
  const { api, schemasApi, json, readOnly } = createRecordsApi(this, filePath);
11455
- ensureWritable7("records clear", readOnly, "destructive");
9872
+ ensureWritable6("records clear", readOnly, "destructive");
11456
9873
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
11457
9874
  const data = await api.clearRecords(resolvedSchema);
11458
9875
  if (json) {
11459
- emitJson10(stdout, "records clear", data, filePath);
9876
+ emitJson9(stdout, "records clear", data, filePath);
11460
9877
  return;
11461
9878
  }
11462
- writeLine10(stdout, `Cleared all records from schema "${schema.value}".`);
9879
+ writeLine9(stdout, `Cleared all records from schema "${schema.value}".`);
11463
9880
  });
11464
9881
  }
11465
9882
 
11466
9883
  // src/commands/schemas.ts
11467
- import { readFileSync as readFileSync9 } from "fs";
11468
- import { InvalidArgumentError as InvalidArgumentError9 } from "commander";
11469
- var HIGHLIGHTED_FIELD_HELP = `
11470
- Highlighted field:
11471
- The schema's "main" field. The frontend uses its value as each record's
11472
- display name, in two places:
11473
- - Activity panel: the record's title in the activity side panel
11474
- (the panel with the record's logs and comments).
11475
- - Detail view: the record's name in the left-hand record list you
11476
- browse to open each record's form.
11477
- `;
11478
- function getCommandIo11(stdout) {
9884
+ import { readFileSync as readFileSync8 } from "fs";
9885
+ import { InvalidArgumentError as InvalidArgumentError8 } from "commander";
9886
+ function getCommandIo10(stdout) {
11479
9887
  return stdout ?? process.stdout;
11480
9888
  }
11481
- function writeLine11(stdout, value) {
9889
+ function writeLine10(stdout, value) {
11482
9890
  stdout.write(`${value}
11483
9891
  `);
11484
9892
  }
11485
- function getGlobalOptions11(command) {
9893
+ function getGlobalOptions10(command) {
11486
9894
  return command.optsWithGlobals();
11487
9895
  }
11488
- function emitJson11(stdout, commandName, data, configPath) {
11489
- writeLine11(
9896
+ function emitJson10(stdout, commandName, data, configPath) {
9897
+ writeLine10(
11490
9898
  stdout,
11491
9899
  JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath }))
11492
9900
  );
11493
9901
  }
11494
- function toConfigurationError10(filePath, error) {
9902
+ function toConfigurationError9(filePath, error) {
11495
9903
  if (error instanceof CliError) {
11496
9904
  throw error;
11497
9905
  }
@@ -11506,7 +9914,7 @@ function toConfigurationError10(filePath, error) {
11506
9914
  function createSchemasApi(command, filePath) {
11507
9915
  try {
11508
9916
  const config = readRuntimeConfig(filePath);
11509
- const runtime = resolveRuntimeContext(config, getGlobalOptions11(command));
9917
+ const runtime = resolveRuntimeContext(config, getGlobalOptions10(command));
11510
9918
  if (!runtime.baseUrl) {
11511
9919
  throw new CliError(
11512
9920
  "configuration_error",
@@ -11525,10 +9933,10 @@ function createSchemasApi(command, filePath) {
11525
9933
  readOnly: runtime.readOnly
11526
9934
  };
11527
9935
  } catch (error) {
11528
- toConfigurationError10(filePath, error);
9936
+ toConfigurationError9(filePath, error);
11529
9937
  }
11530
9938
  }
11531
- function ensureWritable8(commandName, readOnly, commandMode) {
9939
+ function ensureWritable7(commandName, readOnly, commandMode) {
11532
9940
  if (readOnly) {
11533
9941
  throw new CliError(
11534
9942
  "command_not_allowed_in_read_only_mode",
@@ -11540,17 +9948,14 @@ function ensureWritable8(commandName, readOnly, commandMode) {
11540
9948
  );
11541
9949
  }
11542
9950
  }
11543
- function parseUuidOrSlugSelector9(input) {
9951
+ function parseUuidOrSlugSelector8(input) {
11544
9952
  try {
11545
9953
  return normalizeUuidOrSlug(input);
11546
9954
  } catch (error) {
11547
9955
  const message = error instanceof Error ? error.message : "Invalid selector.";
11548
- throw new InvalidArgumentError9(message);
9956
+ throw new InvalidArgumentError8(message);
11549
9957
  }
11550
9958
  }
11551
- function collectFieldSelectors(value, previous = []) {
11552
- return [...previous, parseUuidOrSlugSelector9(value)];
11553
- }
11554
9959
  function parseBooleanFlag(input) {
11555
9960
  const normalized = input.trim().toLowerCase();
11556
9961
  if (["true", "1", "yes", "y", "on"].includes(normalized)) {
@@ -11559,9 +9964,9 @@ function parseBooleanFlag(input) {
11559
9964
  if (["false", "0", "no", "n", "off"].includes(normalized)) {
11560
9965
  return false;
11561
9966
  }
11562
- throw new InvalidArgumentError9(`Expected a boolean value, received "${input}".`);
9967
+ throw new InvalidArgumentError8(`Expected a boolean value, received "${input}".`);
11563
9968
  }
11564
- function isJsonObject7(value) {
9969
+ function isJsonObject6(value) {
11565
9970
  return typeof value === "object" && value !== null && !Array.isArray(value);
11566
9971
  }
11567
9972
  function parseRawJsonObject3(input, sourceLabel) {
@@ -11575,7 +9980,7 @@ function parseRawJsonObject3(input, sourceLabel) {
11575
9980
  `Failed to parse JSON from ${sourceLabel}: ${message}`
11576
9981
  );
11577
9982
  }
11578
- if (!isJsonObject7(parsed)) {
9983
+ if (!isJsonObject6(parsed)) {
11579
9984
  throw new CliError(
11580
9985
  "invalid_cli_usage",
11581
9986
  `Expected ${sourceLabel} to contain a JSON object.`
@@ -11596,7 +10001,7 @@ function readRawObject4(raw, rawFile) {
11596
10001
  if (rawFile) {
11597
10002
  let contents;
11598
10003
  try {
11599
- contents = readFileSync9(rawFile, "utf8");
10004
+ contents = readFileSync8(rawFile, "utf8");
11600
10005
  } catch (error) {
11601
10006
  const message = error instanceof Error ? error.message : "Unable to read file.";
11602
10007
  throw new CliError(
@@ -11655,7 +10060,7 @@ function applyFieldDefaultValue(input, defaultValue) {
11655
10060
  return;
11656
10061
  }
11657
10062
  const config = input.config;
11658
- if (config !== void 0 && !isJsonObject7(config)) {
10063
+ if (config !== void 0 && !isJsonObject6(config)) {
11659
10064
  throw new CliError(
11660
10065
  "invalid_cli_usage",
11661
10066
  'Expected field "config" to be a JSON object when using "--default".'
@@ -11695,7 +10100,7 @@ function buildFieldCreateInput(options) {
11695
10100
  input.required = options.required;
11696
10101
  }
11697
10102
  applyFieldDefaultValue(input, options.default);
11698
- if ("config" in input && isJsonObject7(input.config) && isEmptyObject6(input.config)) {
10103
+ if ("config" in input && isJsonObject6(input.config) && isEmptyObject5(input.config)) {
11699
10104
  delete input.config;
11700
10105
  }
11701
10106
  return input;
@@ -11768,35 +10173,35 @@ async function resolveFieldSelector(api, schema, selector) {
11768
10173
  value: match.id
11769
10174
  };
11770
10175
  }
11771
- function isEmptyObject6(value) {
10176
+ function isEmptyObject5(value) {
11772
10177
  return Object.keys(value).length === 0;
11773
10178
  }
11774
10179
  function registerSchemasCommands(program, options = {}) {
11775
10180
  const filePath = options.configPath ?? defaultConfigPath;
11776
- const stdout = getCommandIo11(options.stdout);
10181
+ const stdout = getCommandIo10(options.stdout);
11777
10182
  const schemas = program.command("schemas").description("Manage schemas and schema fields");
11778
10183
  schemas.command("list").description("List schemas").action(async function action() {
11779
10184
  const { api, json } = createSchemasApi(this, filePath);
11780
10185
  const data = await api.listSchemas();
11781
10186
  if (json) {
11782
- emitJson11(stdout, "schemas list", data, filePath);
10187
+ emitJson10(stdout, "schemas list", data, filePath);
11783
10188
  return;
11784
10189
  }
11785
10190
  emitSchemasTable(stdout, data);
11786
10191
  });
11787
- schemas.command("get").description("Get a schema by UUID or slug").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector9).action(async function action(schema) {
10192
+ schemas.command("get").description("Get a schema by UUID or slug").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).action(async function action(schema) {
11788
10193
  const { api, json } = createSchemasApi(this, filePath);
11789
10194
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
11790
10195
  const data = await api.getSchema(resolvedSchema);
11791
10196
  if (json) {
11792
- emitJson11(stdout, "schemas get", data, filePath);
10197
+ emitJson10(stdout, "schemas get", data, filePath);
11793
10198
  return;
11794
10199
  }
11795
10200
  emitSchemasTable(stdout, [data]);
11796
10201
  });
11797
10202
  schemas.command("create").description("Create a schema").requiredOption("--name <name>", "schema name").requiredOption("--slug <slug>", "schema slug").option("--auditable", "mark schema as auditable").option("--commentable", "mark schema as commentable").action(async function action(commandOptions) {
11798
10203
  const { api, json, readOnly } = createSchemasApi(this, filePath);
11799
- ensureWritable8("schemas create", readOnly, "write");
10204
+ ensureWritable7("schemas create", readOnly, "write");
11800
10205
  const input = {
11801
10206
  name: commandOptions.name,
11802
10207
  slug: commandOptions.slug,
@@ -11805,87 +10210,32 @@ function registerSchemasCommands(program, options = {}) {
11805
10210
  };
11806
10211
  const data = await api.createSchema(input);
11807
10212
  if (json) {
11808
- emitJson11(stdout, "schemas create", data, filePath);
10213
+ emitJson10(stdout, "schemas create", data, filePath);
11809
10214
  return;
11810
10215
  }
11811
- writeLine11(stdout, `Created schema "${data.slug ?? commandOptions.slug}".`);
10216
+ writeLine10(stdout, `Created schema "${data.slug ?? commandOptions.slug}".`);
11812
10217
  });
11813
- schemas.command("update").description("Update a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector9).option("--name <name>", "schema name").option("--slug <slug>", "schema slug").option("--auditable <bool>", "auditable flag", parseBooleanFlag).option("--commentable <bool>", "commentable flag", parseBooleanFlag).option(
11814
- "--highlighted-field <field>",
11815
- "its value is used as each record's display name in the UI (field uuid or slug)",
11816
- parseUuidOrSlugSelector9
11817
- ).action(async function action(schema, commandOptions) {
10218
+ schemas.command("update").description("Update a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).option("--name <name>", "schema name").option("--slug <slug>", "schema slug").option("--auditable <bool>", "auditable flag", parseBooleanFlag).option("--commentable <bool>", "commentable flag", parseBooleanFlag).action(async function action(schema, commandOptions) {
11818
10219
  const { api, json, readOnly } = createSchemasApi(this, filePath);
11819
- ensureWritable8("schemas update", readOnly, "write");
10220
+ ensureWritable7("schemas update", readOnly, "write");
11820
10221
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
11821
10222
  const input = buildSchemaUpdateInput(commandOptions);
11822
- if (commandOptions.highlightedField !== void 0) {
11823
- const resolvedField = await resolveFieldSelector(
11824
- api,
11825
- resolvedSchema,
11826
- commandOptions.highlightedField
11827
- );
11828
- input.highlightedField = resolvedField.value;
11829
- }
11830
- if (isEmptyObject6(input)) {
10223
+ if (isEmptyObject5(input)) {
11831
10224
  throw new CliError(
11832
10225
  "invalid_cli_usage",
11833
- 'Provide at least one schema field to update via "--name", "--slug", "--auditable", "--commentable", or "--highlighted-field".'
10226
+ 'Provide at least one schema field to update via "--name", "--slug", "--auditable", or "--commentable".'
11834
10227
  );
11835
10228
  }
11836
10229
  const data = await api.updateSchema(resolvedSchema, input);
11837
10230
  if (json) {
11838
- emitJson11(stdout, "schemas update", data, filePath);
11839
- return;
11840
- }
11841
- writeLine11(stdout, `Updated schema "${data.slug ?? schema.value}".`);
11842
- }).addHelpText("after", HIGHLIGHTED_FIELD_HELP);
11843
- schemas.command("set-unique-fields").description("Set or clear the composite unique-field constraint on a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector9).option(
11844
- "--field <field>",
11845
- "field uuid or slug to include in the unique constraint (repeatable)",
11846
- collectFieldSelectors,
11847
- []
11848
- ).option("--clear", "clear the unique constraint (sends an empty field list)").action(async function action(schema, commandOptions) {
11849
- const { api, json, readOnly } = createSchemasApi(this, filePath);
11850
- ensureWritable8("schemas set-unique-fields", readOnly, "write");
11851
- const selectors = commandOptions.field ?? [];
11852
- if (commandOptions.clear && selectors.length > 0) {
11853
- throw new CliError(
11854
- "invalid_cli_usage",
11855
- 'Use either "--field" or "--clear", not both.'
11856
- );
11857
- }
11858
- if (!commandOptions.clear && selectors.length === 0) {
11859
- throw new CliError(
11860
- "invalid_cli_usage",
11861
- 'Provide at least one field via "--field", or pass "--clear" to remove the unique constraint.'
11862
- );
11863
- }
11864
- const resolvedSchema = await resolveSchemaSelector2(api, schema);
11865
- const resolvedFields = await Promise.all(
11866
- selectors.map((selector) => resolveFieldSelector(api, resolvedSchema, selector))
11867
- );
11868
- const input = {
11869
- fieldIds: resolvedFields.map((field) => field.value)
11870
- };
11871
- const data = await api.setUniqueFields(resolvedSchema, input);
11872
- if (json) {
11873
- emitJson11(stdout, "schemas set-unique-fields", data, filePath);
11874
- return;
11875
- }
11876
- if (input.fieldIds.length === 0) {
11877
- writeLine11(stdout, `Cleared unique fields on schema "${schema.value}".`);
10231
+ emitJson10(stdout, "schemas update", data, filePath);
11878
10232
  return;
11879
10233
  }
11880
- const count = input.fieldIds.length;
11881
- writeLine11(
11882
- stdout,
11883
- `Set unique fields on schema "${schema.value}" (${count} field${count === 1 ? "" : "s"}).`
11884
- );
10234
+ writeLine10(stdout, `Updated schema "${data.slug ?? schema.value}".`);
11885
10235
  });
11886
- schemas.command("delete").description("Delete a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector9).action(async function action(schema) {
10236
+ schemas.command("delete").description("Delete a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).action(async function action(schema) {
11887
10237
  const { api, json, readOnly } = createSchemasApi(this, filePath);
11888
- ensureWritable8("schemas delete", readOnly, "destructive");
10238
+ ensureWritable7("schemas delete", readOnly, "destructive");
11889
10239
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
11890
10240
  await api.deleteSchema(resolvedSchema);
11891
10241
  const data = {
@@ -11893,36 +10243,36 @@ function registerSchemasCommands(program, options = {}) {
11893
10243
  deleted: true
11894
10244
  };
11895
10245
  if (json) {
11896
- emitJson11(stdout, "schemas delete", data, filePath);
10246
+ emitJson10(stdout, "schemas delete", data, filePath);
11897
10247
  return;
11898
10248
  }
11899
- writeLine11(stdout, `Deleted schema "${schema.value}".`);
10249
+ writeLine10(stdout, `Deleted schema "${schema.value}".`);
11900
10250
  });
11901
10251
  const fields = schemas.command("fields").description("Manage schema fields");
11902
- fields.command("list").description("List fields for a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector9).action(async function action(schema) {
10252
+ fields.command("list").description("List fields for a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).action(async function action(schema) {
11903
10253
  const { api, json } = createSchemasApi(this, filePath);
11904
10254
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
11905
10255
  const data = await api.listFields(resolvedSchema);
11906
10256
  if (json) {
11907
- emitJson11(stdout, "schemas fields list", data, filePath);
10257
+ emitJson10(stdout, "schemas fields list", data, filePath);
11908
10258
  return;
11909
10259
  }
11910
10260
  emitFieldsTable(stdout, data);
11911
10261
  });
11912
- fields.command("get").description("Get a field by UUID or slug").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector9).argument("<field>", "field uuid or slug", parseUuidOrSlugSelector9).action(async function action(schema, field) {
10262
+ fields.command("get").description("Get a field by UUID or slug").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).argument("<field>", "field uuid or slug", parseUuidOrSlugSelector8).action(async function action(schema, field) {
11913
10263
  const { api, json } = createSchemasApi(this, filePath);
11914
10264
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
11915
10265
  const resolvedField = await resolveFieldSelector(api, resolvedSchema, field);
11916
10266
  const data = await api.getField(resolvedSchema, resolvedField);
11917
10267
  if (json) {
11918
- emitJson11(stdout, "schemas fields get", data, filePath);
10268
+ emitJson10(stdout, "schemas fields get", data, filePath);
11919
10269
  return;
11920
10270
  }
11921
10271
  emitFieldsTable(stdout, [data]);
11922
10272
  });
11923
- fields.command("create").description(`Create a field in a schema.${buildSchemaFieldCreateHelpText()}`).argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector9).option("--type <type>", `field type (${formatSchemaFieldTypes()})`).option("--slug <slug>", "field slug").option("--label <label>", "field label").option("--required <bool>", "required flag", parseBooleanFlag).option("--default <value>", "default field value").option("--raw <json>", "raw JSON object payload (see type-specific shapes in --help)").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, commandOptions) {
10273
+ fields.command("create").description(`Create a field in a schema.${buildSchemaFieldCreateHelpText()}`).argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).option("--type <type>", `field type (${formatSchemaFieldTypes()})`).option("--slug <slug>", "field slug").option("--label <label>", "field label").option("--required <bool>", "required flag", parseBooleanFlag).option("--default <value>", "default field value").option("--raw <json>", "raw JSON object payload (see type-specific shapes in --help)").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, commandOptions) {
11924
10274
  const { api, json, readOnly } = createSchemasApi(this, filePath);
11925
- ensureWritable8("schemas fields create", readOnly, "write");
10275
+ ensureWritable7("schemas fields create", readOnly, "write");
11926
10276
  const input = buildFieldCreateInput(commandOptions);
11927
10277
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
11928
10278
  let data;
@@ -11932,14 +10282,14 @@ function registerSchemasCommands(program, options = {}) {
11932
10282
  toFieldCreateError(error, input);
11933
10283
  }
11934
10284
  if (json) {
11935
- emitJson11(stdout, "schemas fields create", data, filePath);
10285
+ emitJson10(stdout, "schemas fields create", data, filePath);
11936
10286
  return;
11937
10287
  }
11938
- writeLine11(stdout, `Created field "${data.slug ?? commandOptions.slug}".`);
10288
+ writeLine10(stdout, `Created field "${data.slug ?? commandOptions.slug}".`);
11939
10289
  });
11940
- fields.command("update").description("Update a field in a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector9).argument("<field>", "field uuid or slug", parseUuidOrSlugSelector9).option("--label <label>", "field label").option("--required <bool>", "required flag", parseBooleanFlag).option("--default <value>", "default field value").option("--raw <json>", "raw JSON object payload").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, field, commandOptions) {
10290
+ fields.command("update").description("Update a field in a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).argument("<field>", "field uuid or slug", parseUuidOrSlugSelector8).option("--label <label>", "field label").option("--required <bool>", "required flag", parseBooleanFlag).option("--default <value>", "default field value").option("--raw <json>", "raw JSON object payload").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, field, commandOptions) {
11941
10291
  const { api, json, readOnly } = createSchemasApi(this, filePath);
11942
- ensureWritable8("schemas fields update", readOnly, "write");
10292
+ ensureWritable7("schemas fields update", readOnly, "write");
11943
10293
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
11944
10294
  const resolvedField = await resolveFieldSelector(api, resolvedSchema, field);
11945
10295
  const currentField = await api.getField(resolvedSchema, resolvedField);
@@ -11948,7 +10298,7 @@ function registerSchemasCommands(program, options = {}) {
11948
10298
  throw new CliError("invalid_cli_usage", `Field "${field.value}" is missing type metadata.`);
11949
10299
  }
11950
10300
  const input = buildFieldUpdateInput(currentType, commandOptions);
11951
- if (isEmptyObject6(input)) {
10301
+ if (isEmptyObject5(input)) {
11952
10302
  throw new CliError(
11953
10303
  "invalid_cli_usage",
11954
10304
  'Provide at least one field update via "--label", "--required", "--raw", or "--raw-file".'
@@ -11956,14 +10306,14 @@ function registerSchemasCommands(program, options = {}) {
11956
10306
  }
11957
10307
  const data = await api.updateField(resolvedSchema, resolvedField, input);
11958
10308
  if (json) {
11959
- emitJson11(stdout, "schemas fields update", data, filePath);
10309
+ emitJson10(stdout, "schemas fields update", data, filePath);
11960
10310
  return;
11961
10311
  }
11962
- writeLine11(stdout, `Updated field "${data.slug ?? field.value}".`);
10312
+ writeLine10(stdout, `Updated field "${data.slug ?? field.value}".`);
11963
10313
  });
11964
- fields.command("delete").description("Delete a field from a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector9).argument("<field>", "field uuid or slug", parseUuidOrSlugSelector9).action(async function action(schema, field) {
10314
+ fields.command("delete").description("Delete a field from a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).argument("<field>", "field uuid or slug", parseUuidOrSlugSelector8).action(async function action(schema, field) {
11965
10315
  const { api, json, readOnly } = createSchemasApi(this, filePath);
11966
- ensureWritable8("schemas fields delete", readOnly, "destructive");
10316
+ ensureWritable7("schemas fields delete", readOnly, "destructive");
11967
10317
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
11968
10318
  const resolvedField = await resolveFieldSelector(api, resolvedSchema, field);
11969
10319
  await api.deleteField(resolvedSchema, resolvedField);
@@ -11973,19 +10323,19 @@ function registerSchemasCommands(program, options = {}) {
11973
10323
  deleted: true
11974
10324
  };
11975
10325
  if (json) {
11976
- emitJson11(stdout, "schemas fields delete", data, filePath);
10326
+ emitJson10(stdout, "schemas fields delete", data, filePath);
11977
10327
  return;
11978
10328
  }
11979
- writeLine11(stdout, `Deleted field "${field.value}" from schema "${schema.value}".`);
10329
+ writeLine10(stdout, `Deleted field "${field.value}" from schema "${schema.value}".`);
11980
10330
  });
11981
10331
  }
11982
10332
 
11983
10333
  // src/commands/teamspace.ts
11984
- import { readFileSync as readFileSync10 } from "fs";
11985
- import { InvalidArgumentError as InvalidArgumentError10 } from "commander";
10334
+ import { readFileSync as readFileSync9 } from "fs";
10335
+ import { InvalidArgumentError as InvalidArgumentError9 } from "commander";
11986
10336
 
11987
10337
  // src/api/teamspace.ts
11988
- function jsonOptions8(body, method) {
10338
+ function jsonOptions7(body, method) {
11989
10339
  return {
11990
10340
  method,
11991
10341
  headers: {
@@ -11994,7 +10344,7 @@ function jsonOptions8(body, method) {
11994
10344
  body: JSON.stringify(body)
11995
10345
  };
11996
10346
  }
11997
- function selectorValue10(selector) {
10347
+ function selectorValue9(selector) {
11998
10348
  return selector.value;
11999
10349
  }
12000
10350
  var TeamspaceApi = class {
@@ -12015,53 +10365,53 @@ var TeamspaceApi = class {
12015
10365
  createFolder(input) {
12016
10366
  return this.client.requestJson(
12017
10367
  "/api/v2/teamspaces/folders",
12018
- jsonOptions8(input, "POST")
10368
+ jsonOptions7(input, "POST")
12019
10369
  );
12020
10370
  }
12021
10371
  updateFolder(folder, input) {
12022
10372
  return this.client.requestJson(
12023
- `/api/v2/teamspaces/folders/${selectorValue10(folder)}`,
12024
- jsonOptions8(input, "PATCH")
10373
+ `/api/v2/teamspaces/folders/${selectorValue9(folder)}`,
10374
+ jsonOptions7(input, "PATCH")
12025
10375
  );
12026
10376
  }
12027
10377
  deleteFolder(folder) {
12028
10378
  return this.client.requestJson(
12029
- `/api/v2/teamspaces/folders/${selectorValue10(folder)}`,
10379
+ `/api/v2/teamspaces/folders/${selectorValue9(folder)}`,
12030
10380
  { method: "DELETE" }
12031
10381
  );
12032
10382
  }
12033
10383
  publishResource(input) {
12034
10384
  return this.client.requestJson(
12035
10385
  "/api/v2/teamspaces/resources:publish",
12036
- jsonOptions8(input, "POST")
10386
+ jsonOptions7(input, "POST")
12037
10387
  );
12038
10388
  }
12039
10389
  unpublishResource(resourceId) {
12040
10390
  return this.client.requestJson(
12041
10391
  "/api/v2/teamspaces/resources:unpublish",
12042
- jsonOptions8({ resourceId }, "POST")
10392
+ jsonOptions7({ resourceId }, "POST")
12043
10393
  );
12044
10394
  }
12045
10395
  };
12046
10396
 
12047
10397
  // src/commands/teamspace.ts
12048
- function getCommandIo12(stdout) {
10398
+ function getCommandIo11(stdout) {
12049
10399
  return stdout ?? process.stdout;
12050
10400
  }
12051
- function writeLine12(stdout, value) {
10401
+ function writeLine11(stdout, value) {
12052
10402
  stdout.write(`${value}
12053
10403
  `);
12054
10404
  }
12055
- function getGlobalOptions12(command) {
10405
+ function getGlobalOptions11(command) {
12056
10406
  return command.optsWithGlobals();
12057
10407
  }
12058
- function emitJson12(stdout, commandName, data, configPath) {
12059
- writeLine12(
10408
+ function emitJson11(stdout, commandName, data, configPath) {
10409
+ writeLine11(
12060
10410
  stdout,
12061
10411
  JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath }))
12062
10412
  );
12063
10413
  }
12064
- function toConfigurationError11(filePath, error) {
10414
+ function toConfigurationError10(filePath, error) {
12065
10415
  if (error instanceof CliError) {
12066
10416
  throw error;
12067
10417
  }
@@ -12076,7 +10426,7 @@ function toConfigurationError11(filePath, error) {
12076
10426
  function createTeamspaceApi(command, filePath) {
12077
10427
  try {
12078
10428
  const config = readRuntimeConfig(filePath);
12079
- const runtime = resolveRuntimeContext(config, getGlobalOptions12(command));
10429
+ const runtime = resolveRuntimeContext(config, getGlobalOptions11(command));
12080
10430
  if (!runtime.baseUrl) {
12081
10431
  throw new CliError(
12082
10432
  "configuration_error",
@@ -12094,10 +10444,10 @@ function createTeamspaceApi(command, filePath) {
12094
10444
  readOnly: runtime.readOnly
12095
10445
  };
12096
10446
  } catch (error) {
12097
- toConfigurationError11(filePath, error);
10447
+ toConfigurationError10(filePath, error);
12098
10448
  }
12099
10449
  }
12100
- function ensureWritable9(commandName, readOnly, commandMode) {
10450
+ function ensureWritable8(commandName, readOnly, commandMode) {
12101
10451
  if (readOnly) {
12102
10452
  throw new CliError(
12103
10453
  "command_not_allowed_in_read_only_mode",
@@ -12109,21 +10459,21 @@ function ensureWritable9(commandName, readOnly, commandMode) {
12109
10459
  );
12110
10460
  }
12111
10461
  }
12112
- function parseUuidOrSlugSelector10(input) {
10462
+ function parseUuidOrSlugSelector9(input) {
12113
10463
  try {
12114
10464
  return normalizeUuidOrSlug(input);
12115
10465
  } catch (error) {
12116
10466
  const message = error instanceof Error ? error.message : "Invalid selector.";
12117
- throw new InvalidArgumentError10(message);
10467
+ throw new InvalidArgumentError9(message);
12118
10468
  }
12119
10469
  }
12120
10470
  function parseNonNegativeInteger3(input) {
12121
10471
  if (!/^\d+$/.test(input.trim())) {
12122
- throw new InvalidArgumentError10(`Expected a non-negative integer, received "${input}".`);
10472
+ throw new InvalidArgumentError9(`Expected a non-negative integer, received "${input}".`);
12123
10473
  }
12124
10474
  return Number(input);
12125
10475
  }
12126
- function isJsonObject8(value) {
10476
+ function isJsonObject7(value) {
12127
10477
  return typeof value === "object" && value !== null && !Array.isArray(value);
12128
10478
  }
12129
10479
  function parseRawJsonObject4(input, sourceLabel) {
@@ -12137,7 +10487,7 @@ function parseRawJsonObject4(input, sourceLabel) {
12137
10487
  `Failed to parse JSON from ${sourceLabel}: ${message}`
12138
10488
  );
12139
10489
  }
12140
- if (!isJsonObject8(parsed)) {
10490
+ if (!isJsonObject7(parsed)) {
12141
10491
  throw new CliError(
12142
10492
  "invalid_cli_usage",
12143
10493
  `Expected ${sourceLabel} to contain a JSON object.`
@@ -12158,7 +10508,7 @@ function readRawObject5(raw, rawFile) {
12158
10508
  if (rawFile) {
12159
10509
  let contents;
12160
10510
  try {
12161
- contents = readFileSync10(rawFile, "utf8");
10511
+ contents = readFileSync9(rawFile, "utf8");
12162
10512
  } catch (error) {
12163
10513
  const message = error instanceof Error ? error.message : "Unable to read file.";
12164
10514
  throw new CliError(
@@ -12170,7 +10520,7 @@ function readRawObject5(raw, rawFile) {
12170
10520
  }
12171
10521
  return void 0;
12172
10522
  }
12173
- function isEmptyObject7(value) {
10523
+ function isEmptyObject6(value) {
12174
10524
  return Object.keys(value).length === 0;
12175
10525
  }
12176
10526
  function buildFolderCreateInput(options) {
@@ -12201,7 +10551,7 @@ function buildFolderUpdateInput(options) {
12201
10551
  if (props !== void 0) {
12202
10552
  input.additionalProperties = props;
12203
10553
  }
12204
- if (isEmptyObject7(input)) {
10554
+ if (isEmptyObject6(input)) {
12205
10555
  throw new CliError(
12206
10556
  "invalid_cli_usage",
12207
10557
  'Provide folder updates via "--name", "--order", "--props", or "--props-file".'
@@ -12211,9 +10561,9 @@ function buildFolderUpdateInput(options) {
12211
10561
  }
12212
10562
  function toTableRows5(data) {
12213
10563
  if (Array.isArray(data)) {
12214
- return data.map((entry) => isJsonObject8(entry) ? entry : { value: entry });
10564
+ return data.map((entry) => isJsonObject7(entry) ? entry : { value: entry });
12215
10565
  }
12216
- if (isJsonObject8(data)) {
10566
+ if (isJsonObject7(data)) {
12217
10567
  return [data];
12218
10568
  }
12219
10569
  return [{ value: data }];
@@ -12275,91 +10625,85 @@ async function resolveFolderSelector2(api, selector) {
12275
10625
  }
12276
10626
  function registerTeamspaceCommands(program, options = {}) {
12277
10627
  const filePath = options.configPath ?? defaultConfigPath;
12278
- const stdout = getCommandIo12(options.stdout);
10628
+ const stdout = getCommandIo11(options.stdout);
12279
10629
  const teamspace = program.command("teamspace").description("Manage teamspace folders and resources");
12280
10630
  const folders = teamspace.command("folders").description("Manage teamspace folders");
12281
- folders.command("list").description("List teamspace folders").option("--include-resources", "include the published resources inside each folder").action(async function action(commandOptions) {
10631
+ folders.command("list").description("List teamspace folders").option("--include-resources", "include nested resources").action(async function action(commandOptions) {
12282
10632
  const { api, json } = createTeamspaceApi(this, filePath);
12283
10633
  const data = await api.listFolders(Boolean(commandOptions.includeResources));
12284
10634
  if (json) {
12285
- emitJson12(stdout, "teamspace folders list", data, filePath);
10635
+ emitJson11(stdout, "teamspace folders list", data, filePath);
12286
10636
  return;
12287
10637
  }
12288
10638
  emitTable5(stdout, data);
12289
10639
  });
12290
- 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) {
10640
+ folders.command("get").description("Get a teamspace folder by exact name or UUID").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector9).option("--include-resources", "include nested resources").action(async function action(folder, commandOptions) {
12291
10641
  const { api, json } = createTeamspaceApi(this, filePath);
12292
10642
  const resolvedFolder = await resolveFolderSelector2(api, folder);
12293
10643
  const allFolders = await api.listFolders(Boolean(commandOptions.includeResources));
12294
10644
  const data = findFolderEntity(allFolders, resolvedFolder);
12295
10645
  if (json) {
12296
- emitJson12(stdout, "teamspace folders get", data, filePath);
10646
+ emitJson11(stdout, "teamspace folders get", data, filePath);
12297
10647
  return;
12298
10648
  }
12299
10649
  emitTable5(stdout, data);
12300
10650
  });
12301
- 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) {
10651
+ folders.command("create").description("Create a teamspace folder").requiredOption("--name <name>", "folder name").option("--order <n>", "folder order", parseNonNegativeInteger3).option("--props <json>", "folder properties payload").option("--props-file <path>", "path to a folder properties JSON payload").action(async function action(commandOptions) {
12302
10652
  const { api, json, readOnly } = createTeamspaceApi(this, filePath);
12303
- ensureWritable9("teamspace folders create", readOnly, "write");
10653
+ ensureWritable8("teamspace folders create", readOnly, "write");
12304
10654
  const data = await api.createFolder(buildFolderCreateInput(commandOptions));
12305
10655
  if (json) {
12306
- emitJson12(stdout, "teamspace folders create", data, filePath);
10656
+ emitJson11(stdout, "teamspace folders create", data, filePath);
12307
10657
  return;
12308
10658
  }
12309
- writeLine12(stdout, `Created folder "${getFolderIdentifier(data)}".`);
10659
+ writeLine11(stdout, `Created folder "${getFolderIdentifier(data)}".`);
12310
10660
  });
12311
- 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) {
10661
+ folders.command("update").description("Update a teamspace folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector9).option("--name <name>", "folder name").option("--order <n>", "folder order", parseNonNegativeInteger3).option("--props <json>", "folder properties payload").option("--props-file <path>", "path to a folder properties JSON payload").action(async function action(folder, commandOptions) {
12312
10662
  const { api, json, readOnly } = createTeamspaceApi(this, filePath);
12313
- ensureWritable9("teamspace folders update", readOnly, "write");
10663
+ ensureWritable8("teamspace folders update", readOnly, "write");
12314
10664
  const resolvedFolder = await resolveFolderSelector2(api, folder);
12315
10665
  const data = await api.updateFolder(resolvedFolder, buildFolderUpdateInput(commandOptions));
12316
10666
  if (json) {
12317
- emitJson12(stdout, "teamspace folders update", data, filePath);
10667
+ emitJson11(stdout, "teamspace folders update", data, filePath);
12318
10668
  return;
12319
10669
  }
12320
- writeLine12(stdout, `Updated folder "${getFolderIdentifier(data)}".`);
10670
+ writeLine11(stdout, `Updated folder "${getFolderIdentifier(data)}".`);
12321
10671
  });
12322
- folders.command("delete").description("Delete a teamspace folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector10).action(async function action(folder) {
10672
+ folders.command("delete").description("Delete a teamspace folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector9).action(async function action(folder) {
12323
10673
  const { api, json, readOnly } = createTeamspaceApi(this, filePath);
12324
- ensureWritable9("teamspace folders delete", readOnly, "destructive");
10674
+ ensureWritable8("teamspace folders delete", readOnly, "destructive");
12325
10675
  const resolvedFolder = await resolveFolderSelector2(api, folder);
12326
10676
  const data = await api.deleteFolder(resolvedFolder);
12327
10677
  if (json) {
12328
- emitJson12(stdout, "teamspace folders delete", data, filePath);
10678
+ emitJson11(stdout, "teamspace folders delete", data, filePath);
12329
10679
  return;
12330
10680
  }
12331
- writeLine12(stdout, `Deleted folder "${resolvedFolder.value}".`);
10681
+ writeLine11(stdout, `Deleted folder "${resolvedFolder.value}".`);
12332
10682
  });
12333
10683
  const resources = teamspace.command("resources").description("Manage teamspace resources");
12334
- resources.command("publish").description(
12335
- "Publish a resource to a teamspace folder. Publishing an already-published resource moves it to the new folder."
12336
- ).argument("<resource>", "schema UUID, schema slug, or display UUID", parseUuidOrSlugSelector10).requiredOption(
12337
- "--to <folder>",
12338
- "target folder UUID or exact name (root folder UUID is 00000000-0000-0000-0000-000000000000)",
12339
- parseUuidOrSlugSelector10
12340
- ).action(async function action(resource, commandOptions) {
10684
+ resources.command("publish").description("Publish a resource to a teamspace folder").argument("<resource>", "resource UUID or exact name", parseUuidOrSlugSelector9).requiredOption("--to <folder>", "target folder", parseUuidOrSlugSelector9).action(async function action(resource, commandOptions) {
12341
10685
  const { api, json, readOnly } = createTeamspaceApi(this, filePath);
12342
- ensureWritable9("teamspace resources publish", readOnly, "write");
10686
+ ensureWritable8("teamspace resources publish", readOnly, "write");
12343
10687
  const folder = await resolveFolderSelector2(api, commandOptions.to);
12344
10688
  const data = await api.publishResource({
12345
10689
  resourceId: resource.value,
12346
10690
  targetFolderId: folder.value
12347
10691
  });
12348
10692
  if (json) {
12349
- emitJson12(stdout, "teamspace resources publish", data, filePath);
10693
+ emitJson11(stdout, "teamspace resources publish", data, filePath);
12350
10694
  return;
12351
10695
  }
12352
- writeLine12(stdout, `Published resource "${resource.value}" to folder "${folder.value}".`);
10696
+ writeLine11(stdout, `Published resource "${resource.value}" to folder "${folder.value}".`);
12353
10697
  });
12354
- 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) {
10698
+ resources.command("unpublish").description("Unpublish a resource from teamspace").argument("<resource>", "resource UUID or exact name", parseUuidOrSlugSelector9).action(async function action(resource) {
12355
10699
  const { api, json, readOnly } = createTeamspaceApi(this, filePath);
12356
- ensureWritable9("teamspace resources unpublish", readOnly, "write");
10700
+ ensureWritable8("teamspace resources unpublish", readOnly, "write");
12357
10701
  const data = await api.unpublishResource(resource.value);
12358
10702
  if (json) {
12359
- emitJson12(stdout, "teamspace resources unpublish", data, filePath);
10703
+ emitJson11(stdout, "teamspace resources unpublish", data, filePath);
12360
10704
  return;
12361
10705
  }
12362
- writeLine12(stdout, `Unpublished resource "${resource.value}".`);
10706
+ writeLine11(stdout, `Unpublished resource "${resource.value}".`);
12363
10707
  });
12364
10708
  }
12365
10709
 
@@ -12367,13 +10711,12 @@ function registerTeamspaceCommands(program, options = {}) {
12367
10711
  var require2 = createRequire(import.meta.url);
12368
10712
  var { version } = require2("../package.json");
12369
10713
  function buildProgram(options = {}) {
12370
- const program = new Command11();
10714
+ const program = new Command10();
12371
10715
  program.name("zinkee").description("CLI for Zinkee API v2").version(version).enablePositionalOptions().showHelpAfterError().option("--profile <name>", "select a profile from config").option("--base-url <url>", "override the configured base URL").option("--api-key <token>", "override the configured API key").option("--read-only", "run in read-only mode").option("--example", "show examples for a command").option("--json", "emit JSON output").option("--install-completion [shell]", "install shell completion (bash, zsh, fish, powershell)").option("--show-completion [shell]", "print shell completion script for the current shell");
12372
10716
  registerProfilesCommands(program, options);
12373
10717
  registerAutomationsCommands(program, options);
12374
10718
  registerConfigCommands(program, options);
12375
10719
  registerDisplaysCommands(program, options);
12376
- registerDocumentTemplatesCommands(program, options);
12377
10720
  registerFilesCommands(program, options);
12378
10721
  registerNavigationCommands(program, options);
12379
10722
  registerSchemasCommands(program, options);
@@ -12518,9 +10861,9 @@ function getCompletions(program, request, deps = {}) {
12518
10861
 
12519
10862
  // src/completion/install.ts
12520
10863
  import { execFileSync } from "child_process";
12521
- import { mkdirSync as mkdirSync2, readFileSync as readFileSync11, writeFileSync as writeFileSync4 } from "fs";
10864
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync10, writeFileSync as writeFileSync3 } from "fs";
12522
10865
  import { homedir as homedir2, platform } from "os";
12523
- import { basename as basename3, dirname as dirname2, join as join2 } from "path";
10866
+ import { basename as basename2, dirname as dirname2, join as join2 } from "path";
12524
10867
 
12525
10868
  // src/completion/scripts.ts
12526
10869
  var PROGRAM = "zinkee";
@@ -12642,7 +10985,7 @@ function defaultPowerShellProfile(env) {
12642
10985
  function detectShell(env) {
12643
10986
  const fromEnv = env.shellEnv;
12644
10987
  if (fromEnv) {
12645
- const name = basename3(fromEnv).toLowerCase().replace(/\.exe$/, "");
10988
+ const name = basename2(fromEnv).toLowerCase().replace(/\.exe$/, "");
12646
10989
  if (name === "bash") {
12647
10990
  return "bash";
12648
10991
  }
@@ -12740,7 +11083,7 @@ ${BLOCK_END}
12740
11083
  }
12741
11084
  function readFileOrEmpty(path) {
12742
11085
  try {
12743
- return readFileSync11(path, "utf8");
11086
+ return readFileSync10(path, "utf8");
12744
11087
  } catch (error) {
12745
11088
  if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
12746
11089
  return "";
@@ -12750,7 +11093,7 @@ function readFileOrEmpty(path) {
12750
11093
  }
12751
11094
  function writeFileEnsuringDir(path, content) {
12752
11095
  mkdirSync2(dirname2(path), { recursive: true });
12753
- writeFileSync4(path, content, "utf8");
11096
+ writeFileSync3(path, content, "utf8");
12754
11097
  }
12755
11098
  function installCompletion(shell, env) {
12756
11099
  const target = resolveTarget(shell, env);